Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Sign in / Register
Toggle navigation
P
PhoneManager
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Yang
PhoneManager
Commits
afd5ac8a
Commit
afd5ac8a
authored
Apr 21, 2025
by
CZ1004
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
联系人
parent
92524ed8
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
2655 additions
and
72 deletions
+2655
-72
ContactAllViewController.swift
...Session/Contact/Controller/ContactAllViewController.swift
+88
-0
ContactBackupDetailViewController.swift
...ontact/Controller/ContactBackupDetailViewController.swift
+266
-0
ContactBackupViewController.swift
...sion/Contact/Controller/ContactBackupViewController.swift
+94
-0
ContactIncompleteViewController.swift
.../Contact/Controller/ContactIncompleteViewController.swift
+49
-0
ContactViewController.swift
...ss/Session/Contact/Controller/ContactViewController.swift
+52
-37
ContactsDupViewController.swift
...ession/Contact/Controller/ContactsDupViewController.swift
+51
-0
ContactModuleModel.swift
...ager/Class/Session/Contact/Model/ContactModuleModel.swift
+21
-17
ContactAllView.swift
...nager/Class/Session/Contact/View/All/ContactAllView.swift
+340
-0
ContactNoAllView.swift
...ger/Class/Session/Contact/View/All/ContactNoAllView.swift
+84
-0
ContactBackUpNormalView.swift
...ss/Session/Contact/View/Bac/ContactBackUpNormalView.swift
+286
-0
ContactNoBackUpView.swift
.../Class/Session/Contact/View/Bac/ContactNoBackUpView.swift
+82
-0
BackupViewModel.swift
.../Session/Contact/View/Bac/ViewModel/BackupViewModel.swift
+126
-0
CustomContactAllViewTableViewCell.swift
...Contact/View/Cell/CustomContactAllViewTableViewCell.swift
+79
-0
CustomContactBacDetailTableViewCell.swift
...ntact/View/Cell/CustomContactBacDetailTableViewCell.swift
+54
-0
ContactBacRestoreAlertView.swift
...ct/View/Common/AlertView/ContactBacRestoreAlertView.swift
+165
-0
ContactBackUpCompletedAlertView.swift
...ew/Common/AlertView/ContactBackUpCompletedAlertView.swift
+85
-0
ContactBackUpDeleteCompletedAlertView.swift
...mon/AlertView/ContactBackUpDeleteCompletedAlertView.swift
+85
-0
ContactBackupAlertView.swift
...ontact/View/Common/AlertView/ContactBackupAlertView.swift
+139
-0
ContactDeleteAlertView.swift
...ontact/View/Common/AlertView/ContactDeleteAlertView.swift
+165
-0
ContactNavView.swift
...er/Class/Session/Contact/View/Common/ContactNavView.swift
+0
-0
DeleteButtonView.swift
.../Class/Session/Contact/View/Common/DeleteButtonView.swift
+66
-0
RestoreButtonView.swift
...Class/Session/Contact/View/Common/RestoreButtonView.swift
+61
-0
ContactNoDupView.swift
...ger/Class/Session/Contact/View/Dup/ContactNoDupView.swift
+70
-0
ContactNoIncomView.swift
...r/Class/Session/Contact/View/Inc/ContactNoIncomView.swift
+87
-0
ContactDefaultView.swift
...ss/Session/Contact/View/MenuView/ContactDefaultView.swift
+2
-2
ContactModuleView.swift
...ass/Session/Contact/View/MenuView/ContactModuleView.swift
+58
-16
No files found.
PhoneManager/Class/Session/Contact/Controller/ContactAllViewController.swift
0 → 100644
View file @
afd5ac8a
//
// AllContactViewController.swift
// PhoneManager
//
// Created by 赵前 on 2025/4/19.
//
import
Foundation
class
ContactAllViewController
:
BaseViewController
{
var
dataSourceModel
:
[
ContactModel
]
=
[]
lazy
var
navView
:
ContactNavView
=
{
let
view
=
ContactNavView
()
return
view
}()
lazy
var
emptyView
:
ContactNoAllView
=
{
let
view
=
ContactNoAllView
()
return
view
}()
lazy
var
normalView
:
ContactAllView
=
{
let
view
=
ContactAllView
()
return
view
}()
// 默认页面
func
setDefaultPage
(){
self
.
normalView
.
removeFromSuperview
()
self
.
view
.
addSubview
(
self
.
emptyView
)
self
.
emptyView
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalTo
(
self
.
navView
.
snp
.
bottom
)
.
offset
(
0
)
make
.
left
.
right
.
equalToSuperview
()
make
.
bottom
.
equalToSuperview
()
}
}
func
setNormalPage
(){
self
.
emptyView
.
removeFromSuperview
()
self
.
view
.
addSubview
(
self
.
normalView
)
self
.
normalView
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalTo
(
self
.
navView
.
snp
.
bottom
)
.
offset
(
0
)
make
.
left
.
right
.
equalToSuperview
()
make
.
bottom
.
equalToSuperview
()
}
}
override
func
viewDidLoad
()
{
super
.
viewDidLoad
()
self
.
view
.
backgroundColor
=
.
white
self
.
view
.
addSubview
(
self
.
navView
)
self
.
navView
.
snp
.
makeConstraints
{
make
in
make
.
top
.
left
.
right
.
equalToSuperview
()
make
.
height
.
equalTo
(
statusBarHeight
+
44
)
}
}
}
extension
ContactAllViewController
{
override
func
viewWillAppear
(
_
animated
:
Bool
)
{
super
.
viewWillAppear
(
animated
)
if
self
.
dataSourceModel
.
count
>
0
{
self
.
setNormalPage
()
self
.
normalView
.
dataSourceModel
=
self
.
dataSourceModel
DispatchQueue
.
main
.
async
{
self
.
normalView
.
subTitleLabel
.
text
=
"
\(
self
.
dataSourceModel
.
count
)
Contacts"
self
.
normalView
.
sortContacts
()
self
.
normalView
.
tableView
.
reloadData
()
self
.
normalView
.
setupCustomIndexView
()
}
}
else
{
self
.
setDefaultPage
()
}
}
}
PhoneManager/Class/Session/Contact/Controller/ContactBackupDetailViewController.swift
0 → 100644
View file @
afd5ac8a
This diff is collapsed.
Click to expand it.
PhoneManager/Class/Session/Contact/Controller/ContactBackupViewController.swift
0 → 100644
View file @
afd5ac8a
//
// ContactBackupViewController.swift
// PhoneManager
//
// Created by 赵前 on 2025/4/19.
//
import
Foundation
class
ContactBackupViewController
:
BaseViewController
{
var
dataSourceModel
:
[
BackupInfoModel
]?
// 总数据
var
dataSourceAllModel
:
ContactModuleModel
?
lazy
var
navView
:
ContactNavView
=
{
let
view
=
ContactNavView
()
return
view
}()
lazy
var
emptyView
:
ContactNoBackUpView
=
{
let
view
=
ContactNoBackUpView
()
return
view
}()
lazy
var
normalView
:
ContactBackUpNormalView
=
{
let
view
=
ContactBackUpNormalView
()
return
view
}()
// 默认页面
func
setDefaultPage
(){
self
.
view
.
addSubview
(
self
.
emptyView
)
self
.
emptyView
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalTo
(
self
.
navView
.
snp
.
bottom
)
.
offset
(
0
)
make
.
left
.
right
.
equalToSuperview
()
make
.
bottom
.
equalToSuperview
()
}
}
// 默认页面
func
setNormalPage
(){
self
.
emptyView
.
removeFromSuperview
()
self
.
view
.
addSubview
(
self
.
normalView
)
self
.
normalView
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalTo
(
self
.
navView
.
snp
.
bottom
)
.
offset
(
0
)
make
.
left
.
right
.
equalToSuperview
()
make
.
bottom
.
equalToSuperview
()
}
}
override
func
viewDidLoad
()
{
super
.
viewDidLoad
()
self
.
view
.
backgroundColor
=
.
white
self
.
view
.
addSubview
(
self
.
navView
)
self
.
navView
.
snp
.
makeConstraints
{
make
in
make
.
top
.
left
.
right
.
equalToSuperview
()
make
.
height
.
equalTo
(
statusBarHeight
+
44
)
}
self
.
setDefaultPage
()
}
}
extension
ContactBackupViewController
{
override
func
viewWillAppear
(
_
animated
:
Bool
)
{
super
.
viewWillAppear
(
animated
)
// 请求下数据
let
vm
=
BackupViewModel
()
vm
.
retrieveContactsFromBackup
{[
weak
self
]
info
,
error
in
guard
let
self
else
{
return
}
if
error
!=
nil
{
Print
(
"取出备份错误
\(
String
(
describing
:
error
?
.
localizedDescription
)
)
"
)
return
}
DispatchQueue
.
main
.
async
{
self
.
setNormalPage
()
self
.
dataSourceModel
=
info
self
.
normalView
.
dataSourceModel
=
info
??
[]
self
.
normalView
.
dataSourceAllModel
=
self
.
dataSourceAllModel
?
.
allContacts
self
.
normalView
.
tableView
.
reloadData
()
}
}
}
}
PhoneManager/Class/Session/Contact/Controller/ContactIncompleteViewController.swift
0 → 100644
View file @
afd5ac8a
//
// ContactIncompleteViewController.swift
// PhoneManager
//
// Created by 赵前 on 2025/4/19.
//
import
Foundation
class
ContactIncompleteViewController
:
BaseViewController
{
var
dataSourceModel
:
[
ContactModel
]?
lazy
var
navView
:
ContactNavView
=
{
let
view
=
ContactNavView
()
return
view
}()
lazy
var
emptyView
:
ContactNoIncomView
=
{
let
view
=
ContactNoIncomView
()
return
view
}()
// 默认页面
func
setDefaultPage
(){
self
.
view
.
addSubview
(
self
.
emptyView
)
self
.
emptyView
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalTo
(
self
.
navView
.
snp
.
bottom
)
.
offset
(
0
)
make
.
left
.
right
.
equalToSuperview
()
make
.
bottom
.
equalToSuperview
()
}
}
override
func
viewDidLoad
()
{
super
.
viewDidLoad
()
self
.
view
.
backgroundColor
=
.
white
self
.
view
.
addSubview
(
self
.
navView
)
self
.
navView
.
snp
.
makeConstraints
{
make
in
make
.
top
.
left
.
right
.
equalToSuperview
()
make
.
height
.
equalTo
(
statusBarHeight
+
44
)
}
self
.
setDefaultPage
()
}
}
PhoneManager/Class/Session/Contact/Controller/ContactViewController.swift
View file @
afd5ac8a
...
...
@@ -49,6 +49,7 @@ class ContactViewController : BaseViewController {
}
}
func
setNormalPage
(){
self
.
emptyView
.
removeFromSuperview
()
self
.
view
.
addSubview
(
self
.
moduleView
)
self
.
moduleView
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalTo
(
self
.
navView
.
snp
.
bottom
)
.
offset
(
0
)
...
...
@@ -59,6 +60,7 @@ class ContactViewController : BaseViewController {
override
func
viewWillAppear
(
_
animated
:
Bool
)
{
super
.
viewWillAppear
(
animated
)
// 请求联系人权限
self
.
setDefaultPage
()
requestContactsPermission
{
permission
in
DispatchQueue
.
main
.
async
{
if
permission
{
...
...
@@ -67,9 +69,6 @@ class ContactViewController : BaseViewController {
self
.
setNormalPage
()
// 初始化数据
self
.
initContatsInfo
()
}
else
{
// 没有权限显示空白页
self
.
setDefaultPage
()
}
}
...
...
@@ -95,51 +94,67 @@ extension ContactViewController{
moduleViewData
.
append
(
model4
)
self
.
moduleView
.
moduleViewData
=
moduleViewData
self
.
moduleView
.
dataSourceModel
=
self
.
dataSourceModel
}
/// 初始化联系人数据
func
initContatsInfo
()
{
DispatchQueue
.
global
()
.
async
{
let
store
=
CNContactStore
()
let
keysToFetch
=
[
CNContactGivenNameKey
as
CNKeyDescriptor
,
CNContactFamilyNameKey
as
CNKeyDescriptor
,
CNContactPhoneNumbersKey
as
CNKeyDescriptor
]
do
{
let
request
=
CNContactFetchRequest
(
keysToFetch
:
keysToFetch
)
try
store
.
enumerateContacts
(
with
:
request
)
{
contact
,
stop
in
let
givenName
=
contact
.
givenName
let
familyName
=
contact
.
familyName
let
fullName
=
"
\(
familyName
)
\(
givenName
)
"
// 创建数组
var
incompleteContacts
:
[
ContactModel
]
=
[]
var
allContacts
:
[
ContactModel
]
=
[]
for
phone
in
contact
.
phoneNumbers
{
let
phoneNumber
=
phone
.
value
.
stringValue
let
model
=
ContactModel
.
init
(
name
:
fullName
,
phoneNumber
:
phoneNumber
)
allContacts
.
append
(
model
)
if
fullName
.
isEmpty
||
phoneNumber
.
isEmpty
{
incompleteContacts
.
append
(
model
)
}
}
self
.
dataSourceModel
=
ContactModuleModel
.
init
(
duplicates
:
[],
incompleteContacts
:
incompleteContacts
,
backups
:
[],
allContacts
:
allContacts
)
DispatchQueue
.
main
.
async
{
self
.
updateModuleData
()
self
.
moduleView
.
tableView
.
reloadSections
(
IndexSet
(
integer
:
0
),
with
:
.
automatic
)
}
}
}
catch
{
DispatchQueue
.
main
.
async
{
print
(
"获取联系人信息时发生错误:
\(
error
)
"
)
let
store
=
CNContactStore
()
let
keysToFetch
=
[
CNContactGivenNameKey
as
CNKeyDescriptor
,
CNContactFamilyNameKey
as
CNKeyDescriptor
,
CNContactPhoneNumbersKey
as
CNKeyDescriptor
]
do
{
let
request
=
CNContactFetchRequest
(
keysToFetch
:
keysToFetch
)
// 创建数组
var
incompleteContacts
:
[
ContactModel
]
=
[]
var
allContacts
:
[
ContactModel
]
=
[]
try
store
.
enumerateContacts
(
with
:
request
)
{
contact
,
stop
in
let
givenName
=
contact
.
givenName
let
familyName
=
contact
.
familyName
let
fullName
=
"
\(
familyName
)
\(
givenName
)
"
let
phoneNumbers
=
contact
.
phoneNumbers
.
map
{
$0
.
value
.
stringValue
}
let
model
=
ContactModel
.
init
(
name
:
fullName
,
phoneNumber
:
phoneNumbers
,
identifier
:
contact
.
identifier
)
if
fullName
.
isEmpty
||
phoneNumbers
.
count
<=
0
{
incompleteContacts
.
append
(
model
)
}
allContacts
.
append
(
model
)
self
.
dataSourceModel
=
ContactModuleModel
.
init
(
duplicates
:
[],
incompleteContacts
:
incompleteContacts
,
backups
:
[],
allContacts
:
allContacts
)
}
DispatchQueue
.
main
.
async
{
self
.
updateModuleData
()
self
.
moduleView
.
tableView
.
reloadData
()
}
}
catch
{
DispatchQueue
.
main
.
async
{
print
(
"获取联系人信息时发生错误:
\(
error
)
"
)
}
}
// 获取备份数据
let
vm
=
BackupViewModel
()
vm
.
retrieveContactsFromBackup
{
model
,
error
in
if
let
error
=
error
{
Print
(
"请求备份数据失败,
\(
error
.
localizedDescription
)
"
)
return
}
DispatchQueue
.
main
.
async
{
self
.
dataSourceModel
.
backups
=
model
!
self
.
updateModuleData
()
self
.
moduleView
.
tableView
.
reloadData
()
}
}
// fixme:获取重复数据
}
func
requestContactsPermission
(
completion
:
@escaping
(
Bool
)
->
Void
)
{
let
store
=
CNContactStore
()
switch
CNContactStore
.
authorizationStatus
(
for
:
.
contacts
)
{
...
...
PhoneManager/Class/Session/Contact/Controller/ContactsDupViewController.swift
0 → 100644
View file @
afd5ac8a
//
// ContactsDupViewController.swift
// PhoneManager
//
// Created by 赵前 on 2025/4/19.
//
import
Foundation
class
ContactsDupViewController
:
BaseViewController
{
var
dataSourceModel
:
[[
ContactModel
]]?
lazy
var
navView
:
ContactNavView
=
{
let
view
=
ContactNavView
()
return
view
}()
lazy
var
emptyView
:
ContactNoDupView
=
{
let
view
=
ContactNoDupView
()
return
view
}()
// 默认页面
func
setDefaultPage
(){
self
.
view
.
addSubview
(
self
.
emptyView
)
self
.
emptyView
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalTo
(
self
.
navView
.
snp
.
bottom
)
.
offset
(
0
)
make
.
left
.
right
.
equalToSuperview
()
make
.
bottom
.
equalToSuperview
()
}
}
override
func
viewDidLoad
()
{
super
.
viewDidLoad
()
self
.
view
.
backgroundColor
=
.
white
self
.
view
.
addSubview
(
self
.
navView
)
self
.
navView
.
snp
.
makeConstraints
{
make
in
make
.
top
.
left
.
right
.
equalToSuperview
()
make
.
height
.
equalTo
(
statusBarHeight
+
44
)
}
self
.
setDefaultPage
()
}
}
PhoneManager/Class/Session/Contact/Model/ContactModuleModel.swift
View file @
afd5ac8a
...
...
@@ -6,30 +6,34 @@
//
import
Foundation
import
Contacts
struct
ContactModel
{
struct
ContactModel
:
Codable
,
Equatable
{
// 联系人名字
var
name
:
String
// 联系人电话
var
phoneNumber
:
String
?
var
phoneNumber
:
[
String
]
?
init
(
name
:
String
,
phoneNumber
:
String
)
{
// 唯一id
var
identifier
:
String
init
(
name
:
String
,
phoneNumber
:
[
String
]?
=
nil
,
identifier
:
String
)
{
self
.
name
=
name
self
.
phoneNumber
=
phoneNumber
self
.
identifier
=
identifier
}
}
struct
BackupsModel
{
// 备份时间
var
backupsDate
:
Date
// 备份的联系人
var
backupsContacts
:
[
ContactModel
]
init
(
backupsDate
:
Date
,
backupsContacts
:
[
ContactModel
])
{
self
.
backupsDate
=
backupsDate
self
.
backupsContacts
=
backupsContacts
extension
ContactModel
{
init
?(
contact
:
CNContact
)
{
let
fullName
=
"
\(
contact
.
givenName
)
\(
contact
.
familyName
)
"
.
trimmingCharacters
(
in
:
.
whitespaces
)
let
phoneNumbers
=
contact
.
phoneNumbers
.
map
{
$0
.
value
.
stringValue
}
let
uniqueID
=
contact
.
identifier
if
fullName
.
isEmpty
||
phoneNumbers
.
isEmpty
||
uniqueID
.
isEmpty
{
return
nil
}
self
.
name
=
fullName
self
.
phoneNumber
=
phoneNumbers
self
.
identifier
=
uniqueID
}
}
...
...
@@ -40,11 +44,11 @@ struct ContactModuleModel {
var
incompleteContacts
:
[
ContactModel
]
var
backups
:
[
Backup
s
Model
]
var
backups
:
[
Backup
Info
Model
]
var
allContacts
:
[
ContactModel
]
init
(
duplicates
:
[[
ContactModel
]],
incompleteContacts
:
[
ContactModel
],
backups
:
[
Backup
s
Model
],
allContacts
:
[
ContactModel
])
{
init
(
duplicates
:
[[
ContactModel
]],
incompleteContacts
:
[
ContactModel
],
backups
:
[
Backup
Info
Model
],
allContacts
:
[
ContactModel
])
{
self
.
duplicates
=
duplicates
self
.
incompleteContacts
=
incompleteContacts
self
.
backups
=
backups
...
...
PhoneManager/Class/Session/Contact/View/All/ContactAllView.swift
0 → 100644
View file @
afd5ac8a
This diff is collapsed.
Click to expand it.
PhoneManager/Class/Session/Contact/View/All/ContactNoAllView.swift
0 → 100644
View file @
afd5ac8a
//
// ContactNoAll.swift
// PhoneManager
//
// Created by 赵前 on 2025/4/19.
//
import
Foundation
class
ContactNoAllView
:
UIView
{
lazy
var
titleLabel
:
UILabel
=
{
let
label
=
UILabel
()
label
.
text
=
"All contacts"
label
.
font
=
UIFont
.
systemFont
(
ofSize
:
20
,
weight
:
.
bold
)
label
.
textColor
=
UIColor
(
red
:
0.2
,
green
:
0.2
,
blue
:
0.2
,
alpha
:
1
)
label
.
textAlignment
=
.
left
return
label
}()
lazy
var
subTitleLabel
:
UILabel
=
{
let
label
=
UILabel
()
label
.
text
=
"0 Contacts"
label
.
font
=
UIFont
.
systemFont
(
ofSize
:
14
,
weight
:
.
regular
)
label
.
textColor
=
UIColor
(
red
:
0.2
,
green
:
0.2
,
blue
:
0.2
,
alpha
:
1
)
label
.
textAlignment
=
.
left
return
label
}()
lazy
var
tipLabel
:
UILabel
=
{
let
label
=
UILabel
()
label
.
text
=
"No Contacts"
label
.
font
=
UIFont
.
systemFont
(
ofSize
:
24
,
weight
:
.
bold
)
label
.
textColor
=
UIColor
(
red
:
0.2
,
green
:
0.2
,
blue
:
0.2
,
alpha
:
1
)
label
.
textAlignment
=
.
center
return
label
}()
lazy
var
subTipLabel
:
UILabel
=
{
let
label
=
UILabel
()
label
.
text
=
"Go add a contact!"
label
.
font
=
UIFont
.
systemFont
(
ofSize
:
14
,
weight
:
.
regular
)
label
.
textColor
=
UIColor
(
red
:
0.4
,
green
:
0.4
,
blue
:
0.4
,
alpha
:
1
)
label
.
textAlignment
=
.
center
return
label
}()
override
init
(
frame
:
CGRect
)
{
super
.
init
(
frame
:
frame
)
self
.
addSubview
(
self
.
titleLabel
)
self
.
addSubview
(
self
.
subTitleLabel
)
self
.
addSubview
(
self
.
tipLabel
)
self
.
addSubview
(
self
.
subTipLabel
)
self
.
titleLabel
.
snp
.
makeConstraints
{
make
in
make
.
left
.
equalToSuperview
()
.
offset
(
15
*
RScreenW
())
make
.
top
.
equalToSuperview
()
.
offset
(
14
*
RScreenH
())
make
.
width
.
equalTo
(
345
*
RScreenW
())
make
.
height
.
equalTo
(
32
)
}
self
.
subTitleLabel
.
snp
.
makeConstraints
{
make
in
make
.
left
.
equalToSuperview
()
.
offset
(
15
*
RScreenW
())
make
.
top
.
equalTo
(
self
.
titleLabel
.
snp
.
bottom
)
.
offset
(
2
*
RScreenH
())
make
.
width
.
equalTo
(
345
*
RScreenW
())
make
.
height
.
equalTo
(
20
)
}
self
.
tipLabel
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalTo
(
self
.
subTitleLabel
.
snp
.
bottom
)
.
offset
(
218
*
RScreenH
())
make
.
width
.
equalTo
(
315
*
RScreenW
())
make
.
height
.
equalTo
(
34
)
make
.
centerX
.
equalToSuperview
()
}
self
.
subTipLabel
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalTo
(
self
.
tipLabel
.
snp
.
bottom
)
.
offset
(
8
*
RScreenH
())
make
.
width
.
equalTo
(
315
*
RScreenW
())
make
.
height
.
equalTo
(
20
)
make
.
centerX
.
equalToSuperview
()
}
}
required
init
?(
coder
:
NSCoder
)
{
fatalError
(
"init(coder:) has not been implemented"
)
}
}
PhoneManager/Class/Session/Contact/View/Bac/ContactBackUpNormalView.swift
0 → 100644
View file @
afd5ac8a
This diff is collapsed.
Click to expand it.
PhoneManager/Class/Session/Contact/View/Bac/ContactNoBackUpView.swift
0 → 100644
View file @
afd5ac8a
//
// ContactNoBackUpView.swift
// PhoneManager
//
// Created by 赵前 on 2025/4/19.
//
import
Foundation
class
ContactNoBackUpView
:
UIView
{
lazy
var
titleLabel
:
UILabel
=
{
let
label
=
UILabel
()
label
.
text
=
"Backups"
label
.
font
=
UIFont
.
systemFont
(
ofSize
:
20
,
weight
:
.
bold
)
label
.
textColor
=
UIColor
(
red
:
0.2
,
green
:
0.2
,
blue
:
0.2
,
alpha
:
1
)
label
.
textAlignment
=
.
left
return
label
}()
lazy
var
imageView
:
UIImageView
=
{
let
imageView
=
UIImageView
()
imageView
.
image
=
UIImage
(
named
:
"btn_add_contact"
)
return
imageView
}()
lazy
var
tipLabel
:
UILabel
=
{
let
label
=
UILabel
()
label
.
text
=
"No Backup"
label
.
font
=
UIFont
.
systemFont
(
ofSize
:
24
,
weight
:
.
bold
)
label
.
textColor
=
UIColor
(
red
:
0.2
,
green
:
0.2
,
blue
:
0.2
,
alpha
:
1
)
label
.
textAlignment
=
.
center
return
label
}()
lazy
var
subTipLabel
:
UILabel
=
{
let
label
=
UILabel
()
label
.
text
=
"You can back up your contacts."
label
.
font
=
UIFont
.
systemFont
(
ofSize
:
14
,
weight
:
.
regular
)
label
.
textColor
=
UIColor
(
red
:
0.4
,
green
:
0.4
,
blue
:
0.4
,
alpha
:
1
)
label
.
textAlignment
=
.
center
return
label
}()
override
init
(
frame
:
CGRect
)
{
super
.
init
(
frame
:
frame
)
self
.
addSubview
(
self
.
titleLabel
)
self
.
addSubview
(
self
.
imageView
)
self
.
addSubview
(
self
.
tipLabel
)
self
.
addSubview
(
self
.
subTipLabel
)
self
.
titleLabel
.
snp
.
makeConstraints
{
make
in
make
.
left
.
equalToSuperview
()
.
offset
(
15
*
RScreenW
())
make
.
top
.
equalToSuperview
()
.
offset
(
14
*
RScreenH
())
make
.
width
.
equalTo
(
345
*
RScreenW
())
make
.
height
.
equalTo
(
32
)
}
self
.
imageView
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalTo
(
self
.
titleLabel
.
snp
.
bottom
)
.
offset
(
170
*
RScreenH
())
make
.
width
.
height
.
equalTo
(
58
)
make
.
centerX
.
equalToSuperview
()
}
self
.
tipLabel
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalTo
(
self
.
imageView
.
snp
.
bottom
)
.
offset
(
12
*
RScreenH
())
make
.
width
.
equalTo
(
315
*
RScreenW
())
make
.
height
.
equalTo
(
34
)
make
.
centerX
.
equalToSuperview
()
}
self
.
subTipLabel
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalTo
(
self
.
tipLabel
.
snp
.
bottom
)
.
offset
(
8
*
RScreenH
())
make
.
width
.
equalTo
(
315
*
RScreenW
())
make
.
height
.
equalTo
(
20
)
make
.
centerX
.
equalToSuperview
()
}
}
required
init
?(
coder
:
NSCoder
)
{
fatalError
(
"init(coder:) has not been implemented"
)
}
}
PhoneManager/Class/Session/Contact/View/Bac/ViewModel/BackupViewModel.swift
0 → 100644
View file @
afd5ac8a
//
// BackupViewModel.swift
// PhoneManager
//
// Created by 赵前 on 2025/4/20.
//
import
Foundation
import
Contacts
struct
BackupInfoModel
:
Codable
{
let
backupTime
:
Date
private(set)
var
contactCount
:
Int
let
contacts
:
[
ContactModel
]
// 初始化方法
init
(
backupTime
:
Date
=
Date
(),
contacts
:
[
ContactModel
])
{
self
.
backupTime
=
backupTime
self
.
contactCount
=
contacts
.
count
self
.
contacts
=
contacts
}
// 手动实现 Decodable 协议的 init(from:) 方法
init
(
from
decoder
:
Decoder
)
throws
{
let
container
=
try
decoder
.
container
(
keyedBy
:
CodingKeys
.
self
)
let
dateFormatter
=
DateFormatter
()
dateFormatter
.
dateFormat
=
"yyyy-MM-dd'T'HH:mm:ssZ"
// 与 ISO8601 格式匹配
if
let
backupTimeString
=
try
?
container
.
decode
(
String
.
self
,
forKey
:
.
backupTime
),
let
backupTime
=
dateFormatter
.
date
(
from
:
backupTimeString
)
{
self
.
backupTime
=
backupTime
}
else
{
self
.
backupTime
=
try
container
.
decode
(
Date
.
self
,
forKey
:
.
backupTime
)
}
self
.
contacts
=
try
container
.
decode
([
ContactModel
]
.
self
,
forKey
:
.
contacts
)
self
.
contactCount
=
contacts
.
count
}
private
enum
CodingKeys
:
String
,
CodingKey
{
case
backupTime
case
contactCount
case
contacts
}
}
class
BackupViewModel
{
// 备份部分联系人到沙盒
func
backupPartialContacts
(
_
customContacts
:
[
ContactModel
],
completion
:
@escaping
(
Bool
,
Error
?)
->
Void
)
{
let
newBackupInfo
=
BackupInfoModel
(
contacts
:
customContacts
)
guard
let
documentsDirectory
=
FileManager
.
default
.
urls
(
for
:
.
documentDirectory
,
in
:
.
userDomainMask
)
.
first
else
{
completion
(
false
,
NSError
(
domain
:
"ContactBackupError"
,
code
:
1
,
userInfo
:
[
NSLocalizedDescriptionKey
:
"无法获取沙盒目录"
]))
return
}
let
backupFileURL
=
documentsDirectory
.
appendingPathComponent
(
"partial_contacts_backup.json"
)
var
existingBackups
:
[
BackupInfoModel
]
=
[]
if
let
data
=
try
?
Data
(
contentsOf
:
backupFileURL
)
{
let
decoder
=
JSONDecoder
()
decoder
.
dateDecodingStrategy
=
.
iso8601
do
{
existingBackups
=
try
decoder
.
decode
([
BackupInfoModel
]
.
self
,
from
:
data
)
}
catch
{
print
(
"Failed to decode existing backups:
\(
error
)
"
)
}
}
existingBackups
.
append
(
newBackupInfo
)
do
{
let
encoder
=
JSONEncoder
()
encoder
.
dateEncodingStrategy
=
.
iso8601
let
jsonData
=
try
encoder
.
encode
(
existingBackups
)
try
jsonData
.
write
(
to
:
backupFileURL
)
completion
(
true
,
nil
)
}
catch
{
completion
(
false
,
error
)
}
}
// 备份所有联系人到沙盒
func
backupAllContacts
(
_
customContacts
:
[
ContactModel
],
completion
:
@escaping
(
Bool
,
Error
?)
->
Void
)
{
backupPartialContacts
(
customContacts
)
{
success
,
error
in
completion
(
success
,
error
)
}
}
// 从沙盒中取出联系人并转换为自定义模型
func
retrieveContactsFromBackup
(
completion
:
@escaping
([
BackupInfoModel
]?,
Error
?)
->
Void
)
{
guard
let
documentsDirectory
=
FileManager
.
default
.
urls
(
for
:
.
documentDirectory
,
in
:
.
userDomainMask
)
.
first
else
{
completion
(
nil
,
NSError
(
domain
:
"ContactBackupError"
,
code
:
1
,
userInfo
:
[
NSLocalizedDescriptionKey
:
"无法获取沙盒目录"
]))
return
}
let
backupFileURL
=
documentsDirectory
.
appendingPathComponent
(
"partial_contacts_backup.json"
)
do
{
let
jsonData
=
try
Data
(
contentsOf
:
backupFileURL
)
let
decoder
=
JSONDecoder
()
decoder
.
dateDecodingStrategy
=
.
iso8601
// 尝试解码为 BackupInfoModel 数组
let
backupInfos
=
try
decoder
.
decode
([
BackupInfoModel
]
.
self
,
from
:
jsonData
)
completion
(
backupInfos
,
nil
)
}
catch
{
Print
(
error
.
localizedDescription
)
completion
(
nil
,
error
)
}
}
func
saveModel
(
model
:[
BackupInfoModel
],
completion
:
@escaping
(
Bool
,
Error
?)
->
Void
){
guard
let
documentsDirectory
=
FileManager
.
default
.
urls
(
for
:
.
documentDirectory
,
in
:
.
userDomainMask
)
.
first
else
{
completion
(
false
,
NSError
(
domain
:
"ContactBackupError"
,
code
:
1
,
userInfo
:
[
NSLocalizedDescriptionKey
:
"无法获取沙盒目录"
]))
return
}
let
backupFileURL
=
documentsDirectory
.
appendingPathComponent
(
"partial_contacts_backup.json"
)
do
{
let
encoder
=
JSONEncoder
()
encoder
.
dateEncodingStrategy
=
.
iso8601
let
jsonData
=
try
encoder
.
encode
(
model
)
try
jsonData
.
write
(
to
:
backupFileURL
)
completion
(
true
,
nil
)
}
catch
{
completion
(
false
,
error
)
}
}
}
PhoneManager/Class/Session/Contact/View/Cell/CustomContactAllViewTableViewCell.swift
0 → 100644
View file @
afd5ac8a
//
// CustomContactAllViewTableViewCell.swift
// PhoneManager
//
// Created by 赵前 on 2025/4/19.
//
import
Foundation
class
CustomContactAllViewTableViewCell
:
UITableViewCell
{
var
model
:
ContactModel
?
var
buttonSelectCallBack
:
(
ContactModel
,
Bool
)
->
Void
=
{
model
,
selected
in
}
lazy
var
backView
:
UIView
=
{
let
view
=
UIView
()
view
.
backgroundColor
=
UIColor
(
red
:
0.95
,
green
:
0.96
,
blue
:
0.99
,
alpha
:
1
)
view
.
clipsToBounds
=
true
view
.
layer
.
cornerRadius
=
12
return
view
}()
lazy
var
nameLabel
:
UILabel
=
{
let
label
=
UILabel
()
label
.
textColor
=
UIColor
(
red
:
0.2
,
green
:
0.2
,
blue
:
0.2
,
alpha
:
1
)
label
.
font
=
UIFont
.
systemFont
(
ofSize
:
16
,
weight
:
.
bold
)
return
label
}()
lazy
var
selectButton
:
UIButton
=
{
let
button
=
UIButton
(
type
:
.
custom
)
button
.
setImage
(
UIImage
(
named
:
"ic_sel_com"
),
for
:
.
normal
)
button
.
setImage
(
UIImage
(
named
:
"ic_unsel_com_red"
),
for
:
.
selected
)
button
.
addTarget
(
self
,
action
:
#selector(
selectContact(_:)
)
,
for
:
.
touchUpInside
)
return
button
}()
override
init
(
style
:
UITableViewCell
.
CellStyle
,
reuseIdentifier
:
String
?)
{
super
.
init
(
style
:
style
,
reuseIdentifier
:
reuseIdentifier
)
self
.
selectionStyle
=
.
none
self
.
contentView
.
addSubview
(
self
.
backView
)
self
.
backView
.
addSubview
(
self
.
nameLabel
)
self
.
backView
.
addSubview
(
self
.
selectButton
)
self
.
backView
.
snp
.
makeConstraints
{
make
in
make
.
left
.
right
.
top
.
equalToSuperview
()
make
.
height
.
equalTo
(
71
)
}
self
.
nameLabel
.
snp
.
makeConstraints
{
make
in
make
.
left
.
equalToSuperview
()
.
offset
(
16
*
RScreenH
())
make
.
centerY
.
equalToSuperview
()
make
.
width
.
equalTo
(
210
)
make
.
height
.
equalTo
(
22
)
}
self
.
selectButton
.
snp
.
makeConstraints
{
make
in
make
.
width
.
height
.
equalTo
(
24
)
make
.
centerY
.
equalToSuperview
()
make
.
right
.
equalToSuperview
()
.
offset
(
-
16
*
RScreenW
())
}
}
required
init
?(
coder
:
NSCoder
)
{
fatalError
(
"init(coder:) has not been implemented"
)
}
}
extension
CustomContactAllViewTableViewCell
{
@objc
private
func
selectContact
(
_
sender
:
UIButton
)
{
sender
.
isSelected
=
!
sender
.
isSelected
buttonSelectCallBack
(
model
!
,
sender
.
isSelected
)
}
}
PhoneManager/Class/Session/Contact/View/Cell/CustomContactBacDetailTableViewCell.swift
0 → 100644
View file @
afd5ac8a
//
// CustomContactBacDetailTableViewCell.swift
// PhoneManager
//
// Created by 赵前 on 2025/4/20.
//
import
Foundation
class
CustomContactBacDetailTableViewCell
:
UITableViewCell
{
var
model
:
ContactModel
?
lazy
var
backView
:
UIView
=
{
let
view
=
UIView
()
view
.
backgroundColor
=
UIColor
(
red
:
0.95
,
green
:
0.96
,
blue
:
0.99
,
alpha
:
1
)
view
.
clipsToBounds
=
true
view
.
layer
.
cornerRadius
=
12
return
view
}()
lazy
var
nameLabel
:
UILabel
=
{
let
label
=
UILabel
()
label
.
textColor
=
UIColor
(
red
:
0.2
,
green
:
0.2
,
blue
:
0.2
,
alpha
:
1
)
label
.
font
=
UIFont
.
systemFont
(
ofSize
:
16
,
weight
:
.
bold
)
return
label
}()
override
init
(
style
:
UITableViewCell
.
CellStyle
,
reuseIdentifier
:
String
?)
{
super
.
init
(
style
:
style
,
reuseIdentifier
:
reuseIdentifier
)
self
.
selectionStyle
=
.
none
self
.
contentView
.
addSubview
(
self
.
backView
)
self
.
backView
.
addSubview
(
self
.
nameLabel
)
self
.
backView
.
snp
.
makeConstraints
{
make
in
make
.
left
.
right
.
top
.
equalToSuperview
()
make
.
height
.
equalTo
(
71
)
}
self
.
nameLabel
.
snp
.
makeConstraints
{
make
in
make
.
left
.
equalToSuperview
()
.
offset
(
16
*
RScreenH
())
make
.
centerY
.
equalToSuperview
()
make
.
width
.
equalTo
(
210
)
make
.
height
.
equalTo
(
22
)
}
}
required
init
?(
coder
:
NSCoder
)
{
fatalError
(
"init(coder:) has not been implemented"
)
}
}
PhoneManager/Class/Session/Contact/View/Common/AlertView/ContactBacRestoreAlertView.swift
0 → 100644
View file @
afd5ac8a
//
// ContactBacRestoreAlertView.swift
// PhoneManager
//
// Created by 赵前 on 2025/4/20.
//
import
Foundation
class
ContactBacRestoreAlertView
:
UIView
{
var
sureCallBack
:
()
->
Void
=
{}
// 懒加载背景视图
private
lazy
var
backgroundView
:
UIView
=
{
let
view
=
UIView
()
view
.
backgroundColor
=
UIColor
.
black
.
withAlphaComponent
(
0.5
)
return
view
}()
// 懒加载卡片视图
private
lazy
var
cardView
:
UIView
=
{
let
view
=
UIView
()
view
.
backgroundColor
=
.
white
view
.
layer
.
cornerRadius
=
10
view
.
clipsToBounds
=
true
return
view
}()
// 懒加载标题标签
private
lazy
var
titleLabel
:
UILabel
=
{
let
label
=
UILabel
()
label
.
text
=
"Are you sure?"
label
.
font
=
UIFont
.
systemFont
(
ofSize
:
17
,
weight
:
.
bold
)
label
.
textColor
=
UIColor
(
red
:
0
,
green
:
0
,
blue
:
0
,
alpha
:
1
)
label
.
textAlignment
=
.
center
return
label
}()
// 懒加载副标题标签
private
lazy
var
subtitleLabel
:
UILabel
=
{
let
label
=
UILabel
()
label
.
text
=
"Your contacts will be removed from your iPhone and iCloud. This process cannot be reversed"
label
.
font
=
UIFont
.
systemFont
(
ofSize
:
13
,
weight
:
.
regular
)
label
.
textColor
=
UIColor
(
red
:
0
,
green
:
0
,
blue
:
0
,
alpha
:
1
)
label
.
numberOfLines
=
0
label
.
textAlignment
=
.
center
return
label
}()
// 懒加载取消按钮
private
lazy
var
cancelButton
:
UIButton
=
{
let
button
=
UIButton
()
button
.
setTitle
(
"Cancel"
,
for
:
.
normal
)
button
.
backgroundColor
=
.
clear
button
.
setTitleColor
(
UIColor
(
red
:
0
,
green
:
0.48
,
blue
:
1
,
alpha
:
1
),
for
:
.
normal
)
button
.
layer
.
cornerRadius
=
5
button
.
titleLabel
?
.
font
=
UIFont
.
systemFont
(
ofSize
:
17
,
weight
:
.
regular
)
button
.
addTarget
(
self
,
action
:
#selector(
dismissAlert
)
,
for
:
.
touchUpInside
)
return
button
}()
// 懒加载确认按钮
private
lazy
var
yesButton
:
UIButton
=
{
let
button
=
UIButton
()
button
.
setTitle
(
"Yes"
,
for
:
.
normal
)
button
.
backgroundColor
=
.
clear
button
.
setTitleColor
(
UIColor
(
red
:
0
,
green
:
0.48
,
blue
:
1
,
alpha
:
1
),
for
:
.
normal
)
button
.
layer
.
cornerRadius
=
5
button
.
titleLabel
?
.
font
=
UIFont
.
systemFont
(
ofSize
:
17
,
weight
:
.
regular
)
button
.
addTarget
(
self
,
action
:
#selector(
sureAlert
)
,
for
:
.
touchUpInside
)
return
button
}()
// 懒加载顶部边线
private
lazy
var
topBorder
:
UIView
=
{
let
view
=
UIView
()
view
.
backgroundColor
=
UIColor
(
red
:
0.24
,
green
:
0.24
,
blue
:
0.26
,
alpha
:
0.3600
)
return
view
}()
// 懒加载中间分割线
private
lazy
var
middleBorder
:
UIView
=
{
let
view
=
UIView
()
view
.
backgroundColor
=
UIColor
(
red
:
0.24
,
green
:
0.24
,
blue
:
0.26
,
alpha
:
0.3600
)
return
view
}()
override
init
(
frame
:
CGRect
)
{
super
.
init
(
frame
:
frame
)
self
.
backgroundColor
=
UIColor
(
red
:
0
,
green
:
0
,
blue
:
0
,
alpha
:
0.5000
)
setupViews
()
}
required
init
?(
coder
:
NSCoder
)
{
fatalError
(
"init(coder:) has not been implemented"
)
}
private
func
setupViews
()
{
self
.
addSubview
(
backgroundView
)
backgroundView
.
snp
.
makeConstraints
{
make
in
make
.
edges
.
equalToSuperview
()
}
self
.
addSubview
(
cardView
)
cardView
.
snp
.
makeConstraints
{
make
in
make
.
center
.
equalToSuperview
()
make
.
width
.
equalTo
(
270
)
make
.
height
.
equalTo
(
154
)
}
cardView
.
addSubview
(
titleLabel
)
titleLabel
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalToSuperview
()
.
offset
(
16
)
make
.
left
.
right
.
equalToSuperview
()
.
inset
(
16
)
make
.
height
.
equalTo
(
22
)
}
cardView
.
addSubview
(
subtitleLabel
)
subtitleLabel
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalTo
(
titleLabel
.
snp
.
bottom
)
.
offset
(
2
)
make
.
left
.
right
.
equalToSuperview
()
.
inset
(
16
)
make
.
height
.
equalTo
(
54
)
}
cardView
.
addSubview
(
cancelButton
)
cancelButton
.
snp
.
makeConstraints
{
make
in
make
.
left
.
equalToSuperview
()
make
.
bottom
.
equalToSuperview
()
make
.
width
.
equalTo
(
cardView
.
snp
.
width
)
.
multipliedBy
(
0.5
)
make
.
height
.
equalTo
(
44
)
}
cardView
.
addSubview
(
yesButton
)
yesButton
.
snp
.
makeConstraints
{
make
in
make
.
right
.
equalToSuperview
()
make
.
bottom
.
equalToSuperview
()
make
.
width
.
equalTo
(
cardView
.
snp
.
width
)
.
multipliedBy
(
0.5
)
make
.
height
.
equalTo
(
44
)
}
cardView
.
addSubview
(
topBorder
)
topBorder
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalTo
(
cancelButton
.
snp
.
top
)
make
.
left
.
right
.
equalTo
(
cardView
)
make
.
height
.
equalTo
(
0.5
)
}
cardView
.
addSubview
(
middleBorder
)
middleBorder
.
snp
.
makeConstraints
{
make
in
make
.
centerX
.
equalTo
(
cardView
)
make
.
top
.
equalTo
(
cancelButton
.
snp
.
top
)
make
.
bottom
.
equalTo
(
cancelButton
.
snp
.
bottom
)
make
.
width
.
equalTo
(
0.5
)
}
}
@objc
private
func
dismissAlert
()
{
self
.
removeFromSuperview
()
}
@objc
private
func
sureAlert
()
{
self
.
removeFromSuperview
()
sureCallBack
()
}
}
PhoneManager/Class/Session/Contact/View/Common/AlertView/ContactBackUpCompletedAlertView.swift
0 → 100644
View file @
afd5ac8a
//
// ContactBackUpCompletedAlertView.swift
// PhoneManager
//
// Created by 赵前 on 2025/4/20.
//
import
Foundation
class
ContactBackUpCompletedAlertView
:
UIView
{
var
sureCallBack
:
()
->
Void
=
{}
// 懒加载背景视图
private
lazy
var
backgroundView
:
UIView
=
{
let
view
=
UIView
()
view
.
backgroundColor
=
UIColor
.
black
.
withAlphaComponent
(
0.5
)
return
view
}()
// 懒加载卡片视图
private
lazy
var
cardView
:
UIView
=
{
let
view
=
UIView
()
view
.
backgroundColor
=
.
white
view
.
layer
.
cornerRadius
=
10
view
.
clipsToBounds
=
true
return
view
}()
private
lazy
var
imageView
:
UIImageView
=
{
let
view
=
UIImageView
()
view
.
backgroundColor
=
.
clear
view
.
image
=
UIImage
(
named
:
"ic_ok_duolicates"
)
return
view
}()
// 懒加载标题标签
private
lazy
var
titleLabel
:
UILabel
=
{
let
label
=
UILabel
()
label
.
text
=
"Backing up is completed"
label
.
font
=
UIFont
.
systemFont
(
ofSize
:
14
,
weight
:
.
regular
)
label
.
textColor
=
UIColor
(
red
:
0.4
,
green
:
0.4
,
blue
:
0.4
,
alpha
:
1
)
label
.
textAlignment
=
.
center
label
.
numberOfLines
=
0
return
label
}()
override
init
(
frame
:
CGRect
)
{
super
.
init
(
frame
:
frame
)
self
.
backgroundColor
=
UIColor
(
red
:
0
,
green
:
0
,
blue
:
0
,
alpha
:
0.5000
)
setupViews
()
}
required
init
?(
coder
:
NSCoder
)
{
fatalError
(
"init(coder:) has not been implemented"
)
}
private
func
setupViews
()
{
self
.
addSubview
(
backgroundView
)
backgroundView
.
snp
.
makeConstraints
{
make
in
make
.
edges
.
equalToSuperview
()
}
self
.
addSubview
(
cardView
)
cardView
.
snp
.
makeConstraints
{
make
in
make
.
center
.
equalToSuperview
()
make
.
width
.
equalTo
(
175
)
make
.
height
.
equalTo
(
115
)
}
cardView
.
addSubview
(
imageView
)
imageView
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalToSuperview
()
.
offset
(
20
)
make
.
width
.
height
.
equalTo
(
35
)
make
.
centerX
.
equalToSuperview
()
}
cardView
.
addSubview
(
titleLabel
)
titleLabel
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalTo
(
self
.
imageView
.
snp
.
bottom
)
.
offset
(
0
)
make
.
left
.
right
.
equalToSuperview
()
.
inset
(
20
)
make
.
height
.
equalTo
(
40
)
}
}
}
PhoneManager/Class/Session/Contact/View/Common/AlertView/ContactBackUpDeleteCompletedAlertView.swift
0 → 100644
View file @
afd5ac8a
//
// ContactBackUpDeleteCompletedAlertView.swift
// PhoneManager
//
// Created by 赵前 on 2025/4/20.
//
import
Foundation
class
ContactBackUpDeleteCompletedAlertView
:
UIView
{
var
sureCallBack
:
()
->
Void
=
{}
// 懒加载背景视图
private
lazy
var
backgroundView
:
UIView
=
{
let
view
=
UIView
()
view
.
backgroundColor
=
UIColor
.
black
.
withAlphaComponent
(
0.5
)
return
view
}()
// 懒加载卡片视图
private
lazy
var
cardView
:
UIView
=
{
let
view
=
UIView
()
view
.
backgroundColor
=
.
white
view
.
layer
.
cornerRadius
=
10
view
.
clipsToBounds
=
true
return
view
}()
private
lazy
var
imageView
:
UIImageView
=
{
let
view
=
UIImageView
()
view
.
backgroundColor
=
.
clear
view
.
image
=
UIImage
(
named
:
"ic_ok_duolicates"
)
return
view
}()
// 懒加载标题标签
private
lazy
var
titleLabel
:
UILabel
=
{
let
label
=
UILabel
()
label
.
text
=
"Done!"
label
.
font
=
UIFont
.
systemFont
(
ofSize
:
14
,
weight
:
.
regular
)
label
.
textColor
=
UIColor
(
red
:
0.4
,
green
:
0.4
,
blue
:
0.4
,
alpha
:
1
)
label
.
textAlignment
=
.
center
return
label
}()
override
init
(
frame
:
CGRect
)
{
super
.
init
(
frame
:
frame
)
self
.
backgroundColor
=
UIColor
(
red
:
0
,
green
:
0
,
blue
:
0
,
alpha
:
0.5000
)
setupViews
()
}
required
init
?(
coder
:
NSCoder
)
{
fatalError
(
"init(coder:) has not been implemented"
)
}
private
func
setupViews
()
{
self
.
addSubview
(
backgroundView
)
backgroundView
.
snp
.
makeConstraints
{
make
in
make
.
edges
.
equalToSuperview
()
}
self
.
addSubview
(
cardView
)
cardView
.
snp
.
makeConstraints
{
make
in
make
.
center
.
equalToSuperview
()
make
.
width
.
equalTo
(
175
)
make
.
height
.
equalTo
(
95
)
}
cardView
.
addSubview
(
imageView
)
imageView
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalToSuperview
()
.
offset
(
20
)
make
.
width
.
height
.
equalTo
(
35
)
make
.
centerX
.
equalToSuperview
()
}
cardView
.
addSubview
(
titleLabel
)
titleLabel
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalTo
(
self
.
imageView
.
snp
.
bottom
)
.
offset
(
0
)
make
.
left
.
right
.
equalToSuperview
()
.
inset
(
20
)
make
.
height
.
equalTo
(
20
)
}
}
}
PhoneManager/Class/Session/Contact/View/Common/AlertView/ContactBackupAlertView.swift
0 → 100644
View file @
afd5ac8a
//
// ContactBackupAlertView.swift
// PhoneManager
//
// Created by 赵前 on 2025/4/20.
//
import
Foundation
class
ContactBackupAlertView
:
UIView
{
var
sureCallBack
:
(
Bool
)
->
Void
=
{
isSure
in
}
// 懒加载背景视图
private
lazy
var
backgroundView
:
UIView
=
{
let
view
=
UIView
()
view
.
backgroundColor
=
UIColor
.
black
.
withAlphaComponent
(
0.5
)
return
view
}()
// 懒加载卡片视图
private
lazy
var
cardView
:
UIView
=
{
let
view
=
UIView
()
view
.
backgroundColor
=
.
white
view
.
layer
.
cornerRadius
=
10
view
.
clipsToBounds
=
true
return
view
}()
// 懒加载标题标签
private
lazy
var
titleLabel
:
UILabel
=
{
let
label
=
UILabel
()
label
.
text
=
"Would you like to back up your contacts before making any changes?"
label
.
font
=
UIFont
.
systemFont
(
ofSize
:
20
,
weight
:
.
bold
)
label
.
textColor
=
UIColor
(
red
:
0
,
green
:
0
,
blue
:
0
,
alpha
:
1
)
label
.
textAlignment
=
.
center
label
.
numberOfLines
=
0
return
label
}()
// 懒加载副标题标签
private
lazy
var
subtitleLabel
:
UILabel
=
{
let
label
=
UILabel
()
label
.
text
=
"Changes cannot be reversed if you do not back up your contacts"
label
.
font
=
UIFont
.
systemFont
(
ofSize
:
14
,
weight
:
.
regular
)
label
.
textColor
=
UIColor
(
red
:
0
,
green
:
0
,
blue
:
0
,
alpha
:
1
)
label
.
numberOfLines
=
0
label
.
textAlignment
=
.
center
return
label
}()
// 懒加载取消按钮
private
lazy
var
cancelButton
:
UIButton
=
{
let
button
=
UIButton
()
button
.
setTitle
(
"No, Thanks"
,
for
:
.
normal
)
button
.
backgroundColor
=
.
clear
button
.
setTitleColor
(
UIColor
(
red
:
0.4
,
green
:
0.4
,
blue
:
0.4
,
alpha
:
1
),
for
:
.
normal
)
button
.
titleLabel
?
.
font
=
UIFont
.
systemFont
(
ofSize
:
16
,
weight
:
.
bold
)
button
.
layer
.
cornerRadius
=
23
button
.
addTarget
(
self
,
action
:
#selector(
dismissAlert
)
,
for
:
.
touchUpInside
)
return
button
}()
// 懒加载确认按钮
private
lazy
var
yesButton
:
UIButton
=
{
let
button
=
UIButton
()
button
.
setTitle
(
"Back up"
,
for
:
.
normal
)
button
.
backgroundColor
=
UIColor
(
red
:
0
,
green
:
0.51
,
blue
:
1
,
alpha
:
1
)
button
.
titleLabel
?
.
font
=
UIFont
.
systemFont
(
ofSize
:
16
,
weight
:
.
bold
)
button
.
setTitleColor
(
.
white
,
for
:
.
normal
)
button
.
layer
.
cornerRadius
=
23
button
.
addTarget
(
self
,
action
:
#selector(
sureAlert
)
,
for
:
.
touchUpInside
)
return
button
}()
override
init
(
frame
:
CGRect
)
{
super
.
init
(
frame
:
frame
)
self
.
backgroundColor
=
UIColor
(
red
:
0
,
green
:
0
,
blue
:
0
,
alpha
:
0.5000
)
setupViews
()
}
required
init
?(
coder
:
NSCoder
)
{
fatalError
(
"init(coder:) has not been implemented"
)
}
private
func
setupViews
()
{
self
.
addSubview
(
backgroundView
)
backgroundView
.
snp
.
makeConstraints
{
make
in
make
.
edges
.
equalToSuperview
()
}
self
.
addSubview
(
cardView
)
cardView
.
snp
.
makeConstraints
{
make
in
make
.
center
.
equalToSuperview
()
make
.
width
.
equalTo
(
345
)
make
.
height
.
equalTo
(
288
)
}
cardView
.
addSubview
(
titleLabel
)
titleLabel
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalToSuperview
()
.
offset
(
28
)
make
.
left
.
right
.
equalToSuperview
()
.
inset
(
20
)
make
.
height
.
equalTo
(
84
)
}
cardView
.
addSubview
(
subtitleLabel
)
subtitleLabel
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalTo
(
titleLabel
.
snp
.
bottom
)
.
offset
(
8
)
make
.
left
.
right
.
equalToSuperview
()
.
inset
(
20
)
make
.
height
.
equalTo
(
40
)
}
cardView
.
addSubview
(
yesButton
)
yesButton
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalTo
(
subtitleLabel
.
snp
.
bottom
)
.
offset
(
16
)
make
.
left
.
right
.
equalToSuperview
()
.
inset
(
20
)
make
.
height
.
equalTo
(
46
)
}
cardView
.
addSubview
(
cancelButton
)
cancelButton
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalTo
(
yesButton
.
snp
.
bottom
)
.
offset
(
4
)
make
.
left
.
right
.
equalToSuperview
()
.
inset
(
20
)
make
.
height
.
equalTo
(
46
)
}
}
@objc
private
func
dismissAlert
()
{
self
.
removeFromSuperview
()
sureCallBack
(
false
)
}
@objc
private
func
sureAlert
()
{
self
.
removeFromSuperview
()
sureCallBack
(
true
)
}
}
PhoneManager/Class/Session/Contact/View/Common/AlertView/ContactDeleteAlertView.swift
0 → 100644
View file @
afd5ac8a
//
// ContactDeleteAlertViewController.swift
// PhoneManager
//
// Created by 赵前 on 2025/4/19.
//
import
Foundation
class
ContactDeleteAlertView
:
UIView
{
var
sureCallBack
:
()
->
Void
=
{}
// 懒加载背景视图
private
lazy
var
backgroundView
:
UIView
=
{
let
view
=
UIView
()
view
.
backgroundColor
=
UIColor
.
black
.
withAlphaComponent
(
0.5
)
return
view
}()
// 懒加载卡片视图
private
lazy
var
cardView
:
UIView
=
{
let
view
=
UIView
()
view
.
backgroundColor
=
.
white
view
.
layer
.
cornerRadius
=
10
view
.
clipsToBounds
=
true
return
view
}()
// 懒加载标题标签
private
lazy
var
titleLabel
:
UILabel
=
{
let
label
=
UILabel
()
label
.
text
=
"Are you sure?"
label
.
font
=
UIFont
.
systemFont
(
ofSize
:
17
,
weight
:
.
bold
)
label
.
textColor
=
UIColor
(
red
:
0
,
green
:
0
,
blue
:
0
,
alpha
:
1
)
label
.
textAlignment
=
.
center
return
label
}()
// 懒加载副标题标签
private
lazy
var
subtitleLabel
:
UILabel
=
{
let
label
=
UILabel
()
label
.
text
=
"Your contacts will be removed from your iPhone and iCloud. This process cannot be reversed"
label
.
font
=
UIFont
.
systemFont
(
ofSize
:
13
,
weight
:
.
regular
)
label
.
textColor
=
UIColor
(
red
:
0
,
green
:
0
,
blue
:
0
,
alpha
:
1
)
label
.
numberOfLines
=
0
label
.
textAlignment
=
.
center
return
label
}()
// 懒加载取消按钮
private
lazy
var
cancelButton
:
UIButton
=
{
let
button
=
UIButton
()
button
.
setTitle
(
"Cancel"
,
for
:
.
normal
)
button
.
backgroundColor
=
.
clear
button
.
setTitleColor
(
UIColor
(
red
:
0
,
green
:
0.48
,
blue
:
1
,
alpha
:
1
),
for
:
.
normal
)
button
.
layer
.
cornerRadius
=
5
button
.
titleLabel
?
.
font
=
UIFont
.
systemFont
(
ofSize
:
17
,
weight
:
.
regular
)
button
.
addTarget
(
self
,
action
:
#selector(
dismissAlert
)
,
for
:
.
touchUpInside
)
return
button
}()
// 懒加载确认按钮
private
lazy
var
yesButton
:
UIButton
=
{
let
button
=
UIButton
()
button
.
setTitle
(
"Yes"
,
for
:
.
normal
)
button
.
backgroundColor
=
.
clear
button
.
setTitleColor
(
UIColor
(
red
:
0
,
green
:
0.48
,
blue
:
1
,
alpha
:
1
),
for
:
.
normal
)
button
.
layer
.
cornerRadius
=
5
button
.
titleLabel
?
.
font
=
UIFont
.
systemFont
(
ofSize
:
17
,
weight
:
.
regular
)
button
.
addTarget
(
self
,
action
:
#selector(
sureAlert
)
,
for
:
.
touchUpInside
)
return
button
}()
// 懒加载顶部边线
private
lazy
var
topBorder
:
UIView
=
{
let
view
=
UIView
()
view
.
backgroundColor
=
UIColor
(
red
:
0.24
,
green
:
0.24
,
blue
:
0.26
,
alpha
:
0.3600
)
return
view
}()
// 懒加载中间分割线
private
lazy
var
middleBorder
:
UIView
=
{
let
view
=
UIView
()
view
.
backgroundColor
=
UIColor
(
red
:
0.24
,
green
:
0.24
,
blue
:
0.26
,
alpha
:
0.3600
)
return
view
}()
override
init
(
frame
:
CGRect
)
{
super
.
init
(
frame
:
frame
)
self
.
backgroundColor
=
UIColor
(
red
:
0
,
green
:
0
,
blue
:
0
,
alpha
:
0.5000
)
setupViews
()
}
required
init
?(
coder
:
NSCoder
)
{
fatalError
(
"init(coder:) has not been implemented"
)
}
private
func
setupViews
()
{
self
.
addSubview
(
backgroundView
)
backgroundView
.
snp
.
makeConstraints
{
make
in
make
.
edges
.
equalToSuperview
()
}
self
.
addSubview
(
cardView
)
cardView
.
snp
.
makeConstraints
{
make
in
make
.
center
.
equalToSuperview
()
make
.
width
.
equalTo
(
270
)
make
.
height
.
equalTo
(
154
)
}
cardView
.
addSubview
(
titleLabel
)
titleLabel
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalToSuperview
()
.
offset
(
16
)
make
.
left
.
right
.
equalToSuperview
()
.
inset
(
16
)
make
.
height
.
equalTo
(
22
)
}
cardView
.
addSubview
(
subtitleLabel
)
subtitleLabel
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalTo
(
titleLabel
.
snp
.
bottom
)
.
offset
(
2
)
make
.
left
.
right
.
equalToSuperview
()
.
inset
(
16
)
make
.
height
.
equalTo
(
54
)
}
cardView
.
addSubview
(
cancelButton
)
cancelButton
.
snp
.
makeConstraints
{
make
in
make
.
left
.
equalToSuperview
()
make
.
bottom
.
equalToSuperview
()
make
.
width
.
equalTo
(
cardView
.
snp
.
width
)
.
multipliedBy
(
0.5
)
make
.
height
.
equalTo
(
44
)
}
cardView
.
addSubview
(
yesButton
)
yesButton
.
snp
.
makeConstraints
{
make
in
make
.
right
.
equalToSuperview
()
make
.
bottom
.
equalToSuperview
()
make
.
width
.
equalTo
(
cardView
.
snp
.
width
)
.
multipliedBy
(
0.5
)
make
.
height
.
equalTo
(
44
)
}
cardView
.
addSubview
(
topBorder
)
topBorder
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalTo
(
cancelButton
.
snp
.
top
)
make
.
left
.
right
.
equalTo
(
cardView
)
make
.
height
.
equalTo
(
0.5
)
}
cardView
.
addSubview
(
middleBorder
)
middleBorder
.
snp
.
makeConstraints
{
make
in
make
.
centerX
.
equalTo
(
cardView
)
make
.
top
.
equalTo
(
cancelButton
.
snp
.
top
)
make
.
bottom
.
equalTo
(
cancelButton
.
snp
.
bottom
)
make
.
width
.
equalTo
(
0.5
)
}
}
@objc
private
func
dismissAlert
()
{
self
.
removeFromSuperview
()
}
@objc
private
func
sureAlert
()
{
self
.
removeFromSuperview
()
sureCallBack
()
}
}
PhoneManager/Class/Session/Contact/View/ContactNavView.swift
→
PhoneManager/Class/Session/Contact/View/Co
mmon/Co
ntactNavView.swift
View file @
afd5ac8a
File moved
PhoneManager/Class/Session/Contact/View/Common/DeleteButtonView.swift
0 → 100644
View file @
afd5ac8a
//
// DeleteButtonView.swift
// PhoneManager
//
// Created by 赵前 on 2025/4/19.
//
import
Foundation
class
DeleteButtonView
:
UIView
{
var
submitCallBack
:
(()
->
Void
)
=
{}
lazy
var
imageView
:
UIImageView
=
{
let
imageView
=
UIImageView
()
imageView
.
image
=
UIImage
(
named
:
"ic_delete_duplicates"
)
return
imageView
}()
lazy
var
titleLabel
:
UILabel
=
{
let
label
=
UILabel
()
label
.
textAlignment
=
.
left
label
.
textColor
=
UIColor
(
red
:
1
,
green
:
1
,
blue
:
1
,
alpha
:
1
)
return
label
}()
override
init
(
frame
:
CGRect
)
{
super
.
init
(
frame
:
frame
)
self
.
isUserInteractionEnabled
=
true
self
.
backgroundColor
=
UIColor
(
red
:
0
,
green
:
0.51
,
blue
:
1
,
alpha
:
1
)
let
tap
=
UITapGestureRecognizer
()
tap
.
addTarget
(
self
,
action
:
#selector(
submitAction
)
)
self
.
addGestureRecognizer
(
tap
)
self
.
addSubview
(
self
.
imageView
)
self
.
addSubview
(
self
.
titleLabel
)
self
.
imageView
.
snp
.
makeConstraints
{
make
in
make
.
width
.
height
.
equalTo
(
20
)
make
.
centerY
.
equalToSuperview
()
make
.
left
.
equalToSuperview
()
.
offset
(
94
*
RScreenW
())
}
self
.
titleLabel
.
snp
.
makeConstraints
{
make
in
make
.
left
.
equalTo
(
self
.
imageView
.
snp
.
right
)
.
offset
(
8
*
RScreenW
())
make
.
centerY
.
equalToSuperview
()
make
.
height
.
equalTo
(
22
)
}
}
required
init
?(
coder
:
NSCoder
)
{
fatalError
(
"init(coder:) has not been implemented"
)
}
}
extension
DeleteButtonView
{
@objc
func
submitAction
(){
submitCallBack
()
}
}
PhoneManager/Class/Session/Contact/View/Common/RestoreButtonView.swift
0 → 100644
View file @
afd5ac8a
//
// RestoreButtonView.swift
// PhoneManager
//
// Created by 赵前 on 2025/4/20.
//
import
Foundation
class
RestoreButtonView
:
UIView
{
var
submitCallBack
:
(()
->
Void
)
=
{}
lazy
var
imageView
:
UIImageView
=
{
let
imageView
=
UIImageView
()
imageView
.
image
=
UIImage
(
named
:
"ic_beifen"
)
return
imageView
}()
lazy
var
titleLabel
:
UILabel
=
{
let
label
=
UILabel
()
label
.
textAlignment
=
.
left
label
.
text
=
"Restore Backup"
label
.
textColor
=
UIColor
(
red
:
1
,
green
:
1
,
blue
:
1
,
alpha
:
1
)
return
label
}()
override
init
(
frame
:
CGRect
)
{
super
.
init
(
frame
:
frame
)
self
.
isUserInteractionEnabled
=
true
self
.
backgroundColor
=
UIColor
(
red
:
0
,
green
:
0.51
,
blue
:
1
,
alpha
:
1
)
let
tap
=
UITapGestureRecognizer
()
tap
.
addTarget
(
self
,
action
:
#selector(
restoreAction
)
)
self
.
addGestureRecognizer
(
tap
)
self
.
addSubview
(
self
.
imageView
)
self
.
addSubview
(
self
.
titleLabel
)
self
.
imageView
.
snp
.
makeConstraints
{
make
in
make
.
width
.
height
.
equalTo
(
20
)
make
.
centerY
.
equalToSuperview
()
make
.
left
.
equalToSuperview
()
.
offset
(
94
*
RScreenW
())
}
self
.
titleLabel
.
snp
.
makeConstraints
{
make
in
make
.
left
.
equalTo
(
self
.
imageView
.
snp
.
right
)
.
offset
(
8
*
RScreenW
())
make
.
centerY
.
equalToSuperview
()
make
.
height
.
equalTo
(
22
)
}
}
required
init
?(
coder
:
NSCoder
)
{
fatalError
(
"init(coder:) has not been implemented"
)
}
@objc
func
restoreAction
(){
submitCallBack
()
}
}
PhoneManager/Class/Session/Contact/View/Dup/ContactNoDupView.swift
0 → 100644
View file @
afd5ac8a
//
// ContactNoDupView.swift
// PhoneManager
//
// Created by 赵前 on 2025/4/19.
//
import
Foundation
class
ContactNoDupView
:
UIView
{
lazy
var
titleLabel
:
UILabel
=
{
let
label
=
UILabel
()
label
.
text
=
"Duplicates"
label
.
font
=
UIFont
.
systemFont
(
ofSize
:
20
,
weight
:
.
bold
)
label
.
textColor
=
UIColor
(
red
:
0.2
,
green
:
0.2
,
blue
:
0.2
,
alpha
:
1
)
label
.
textAlignment
=
.
left
return
label
}()
lazy
var
subTitleLabel
:
UILabel
=
{
let
label
=
UILabel
()
label
.
text
=
"0 Contacts"
label
.
font
=
UIFont
.
systemFont
(
ofSize
:
14
,
weight
:
.
regular
)
label
.
textColor
=
UIColor
(
red
:
0.2
,
green
:
0.2
,
blue
:
0.2
,
alpha
:
1
)
label
.
textAlignment
=
.
left
return
label
}()
lazy
var
tipLabel
:
UILabel
=
{
let
label
=
UILabel
()
label
.
text
=
"No duplicate item"
label
.
font
=
UIFont
.
systemFont
(
ofSize
:
24
,
weight
:
.
bold
)
label
.
textColor
=
UIColor
(
red
:
0.2
,
green
:
0.2
,
blue
:
0.2
,
alpha
:
1
)
label
.
textAlignment
=
.
center
return
label
}()
override
init
(
frame
:
CGRect
)
{
super
.
init
(
frame
:
frame
)
self
.
addSubview
(
self
.
titleLabel
)
self
.
addSubview
(
self
.
subTitleLabel
)
self
.
addSubview
(
self
.
tipLabel
)
self
.
titleLabel
.
snp
.
makeConstraints
{
make
in
make
.
left
.
equalToSuperview
()
.
offset
(
15
*
RScreenW
())
make
.
top
.
equalToSuperview
()
.
offset
(
14
*
RScreenH
())
make
.
width
.
equalTo
(
345
*
RScreenW
())
make
.
height
.
equalTo
(
32
)
}
self
.
subTitleLabel
.
snp
.
makeConstraints
{
make
in
make
.
left
.
equalToSuperview
()
.
offset
(
15
*
RScreenW
())
make
.
top
.
equalTo
(
self
.
titleLabel
.
snp
.
bottom
)
.
offset
(
2
*
RScreenH
())
make
.
width
.
equalTo
(
345
*
RScreenW
())
make
.
height
.
equalTo
(
20
)
}
self
.
tipLabel
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalTo
(
self
.
subTitleLabel
.
snp
.
bottom
)
.
offset
(
218
*
RScreenH
())
make
.
width
.
equalTo
(
315
*
RScreenW
())
make
.
height
.
equalTo
(
34
)
make
.
centerX
.
equalToSuperview
()
}
}
required
init
?(
coder
:
NSCoder
)
{
fatalError
(
"init(coder:) has not been implemented"
)
}
}
PhoneManager/Class/Session/Contact/View/Inc/ContactNoIncomView.swift
0 → 100644
View file @
afd5ac8a
//
// ContactNoIncomView.swift
// PhoneManager
//
// Created by 赵前 on 2025/4/19.
//
import
Foundation
class
ContactNoIncomView
:
UIView
{
lazy
var
titleLabel
:
UILabel
=
{
let
label
=
UILabel
()
label
.
text
=
"Incomplete Contacts"
label
.
font
=
UIFont
.
systemFont
(
ofSize
:
20
,
weight
:
.
bold
)
label
.
textColor
=
UIColor
(
red
:
0.2
,
green
:
0.2
,
blue
:
0.2
,
alpha
:
1
)
label
.
textAlignment
=
.
left
return
label
}()
lazy
var
subTitleLabel
:
UILabel
=
{
let
label
=
UILabel
()
label
.
text
=
"0 Contacts"
label
.
font
=
UIFont
.
systemFont
(
ofSize
:
14
,
weight
:
.
regular
)
label
.
textColor
=
UIColor
(
red
:
0.2
,
green
:
0.2
,
blue
:
0.2
,
alpha
:
1
)
label
.
textAlignment
=
.
left
return
label
}()
lazy
var
tipLabel
:
UILabel
=
{
let
label
=
UILabel
()
label
.
text
=
"No Contacts"
label
.
font
=
UIFont
.
systemFont
(
ofSize
:
24
,
weight
:
.
bold
)
label
.
textColor
=
UIColor
(
red
:
0.2
,
green
:
0.2
,
blue
:
0.2
,
alpha
:
1
)
label
.
textAlignment
=
.
center
return
label
}()
lazy
var
subTipLabel
:
UILabel
=
{
let
label
=
UILabel
()
label
.
text
=
"You can add new contacts from Contacts app in your phone."
label
.
font
=
UIFont
.
systemFont
(
ofSize
:
14
,
weight
:
.
regular
)
label
.
textColor
=
UIColor
(
red
:
0.4
,
green
:
0.4
,
blue
:
0.4
,
alpha
:
1
)
label
.
numberOfLines
=
0
label
.
textAlignment
=
.
center
return
label
}()
override
init
(
frame
:
CGRect
)
{
super
.
init
(
frame
:
frame
)
self
.
addSubview
(
self
.
titleLabel
)
self
.
addSubview
(
self
.
subTitleLabel
)
self
.
addSubview
(
self
.
tipLabel
)
self
.
addSubview
(
self
.
subTipLabel
)
self
.
titleLabel
.
snp
.
makeConstraints
{
make
in
make
.
left
.
equalToSuperview
()
.
offset
(
15
*
RScreenW
())
make
.
top
.
equalToSuperview
()
.
offset
(
14
*
RScreenH
())
make
.
width
.
equalTo
(
345
*
RScreenW
())
make
.
height
.
equalTo
(
32
)
}
self
.
subTitleLabel
.
snp
.
makeConstraints
{
make
in
make
.
left
.
equalToSuperview
()
.
offset
(
15
*
RScreenW
())
make
.
top
.
equalTo
(
self
.
titleLabel
.
snp
.
bottom
)
.
offset
(
2
*
RScreenH
())
make
.
width
.
equalTo
(
345
*
RScreenW
())
make
.
height
.
equalTo
(
20
)
}
self
.
tipLabel
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalTo
(
self
.
subTitleLabel
.
snp
.
bottom
)
.
offset
(
218
*
RScreenH
())
make
.
width
.
equalTo
(
315
*
RScreenW
())
make
.
height
.
equalTo
(
34
)
make
.
centerX
.
equalToSuperview
()
}
self
.
subTipLabel
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalTo
(
self
.
tipLabel
.
snp
.
bottom
)
.
offset
(
8
*
RScreenH
())
make
.
width
.
equalTo
(
315
*
RScreenW
())
make
.
height
.
equalTo
(
40
)
make
.
centerX
.
equalToSuperview
()
}
}
required
init
?(
coder
:
NSCoder
)
{
fatalError
(
"init(coder:) has not been implemented"
)
}
}
PhoneManager/Class/Session/Contact/View/ContactDefaultView.swift
→
PhoneManager/Class/Session/Contact/View/
MenuView/
ContactDefaultView.swift
View file @
afd5ac8a
...
...
@@ -87,8 +87,8 @@ extension ContactDefaultView {
self
.
titleLabel
.
snp
.
makeConstraints
{
make
in
make
.
left
.
equalToSuperview
()
.
offset
(
15
*
RScreenW
())
make
.
top
.
equalToSuperview
()
.
offset
(
14
*
RScreenH
())
make
.
width
.
equalTo
(
86
*
RScreenW
())
make
.
height
.
equalTo
(
28
)
make
.
width
.
equalTo
(
345
*
RScreenW
())
make
.
height
.
equalTo
(
32
)
}
self
.
imageView
.
snp
.
makeConstraints
{
make
in
...
...
PhoneManager/Class/Session/Contact/View/ContactModuleView.swift
→
PhoneManager/Class/Session/Contact/View/
MenuView/
ContactModuleView.swift
View file @
afd5ac8a
...
...
@@ -10,7 +10,10 @@ import Foundation
class
ContactModuleView
:
UIView
{
// 总数据
var
dataSourceModel
:
ContactModuleModel
?
// 当前页面显示数据
var
moduleViewData
:
[
ModuleDataModel
]
=
[]
lazy
var
titleLabel
:
UILabel
=
{
...
...
@@ -23,13 +26,21 @@ class ContactModuleView : UIView {
}()
lazy
var
tableView
:
UITableView
=
{
let
tableView
=
UITableView
()
let
tableView
=
UITableView
(
frame
:
CGRect
(
x
:
0
,
y
:
0
,
width
:
0
,
height
:
12
),
style
:
UITableView
.
Style
.
plain
)
tableView
.
dataSource
=
self
tableView
.
delegate
=
self
tableView
.
register
(
CustomContactModuleTableViewCell
.
self
,
forCellReuseIdentifier
:
"CustomContactModuleTableViewCell"
)
tableView
.
separatorStyle
=
.
none
tableView
.
backgroundColor
=
.
clear
tableView
.
tableHeaderView
=
UIView
(
frame
:
CGRect
(
x
:
0
,
y
:
0
,
width
:
0
,
height
:
12
))
tableView
.
isScrollEnabled
=
false
// 设置分隔线样式
tableView
.
separatorStyle
=
.
none
tableView
.
showsVerticalScrollIndicator
=
false
if
#available(iOS 15.0, *)
{
tableView
.
sectionHeaderTopPadding
=
0
}
return
tableView
}()
...
...
@@ -47,8 +58,8 @@ class ContactModuleView : UIView {
self
.
titleLabel
.
snp
.
makeConstraints
{
make
in
make
.
left
.
equalToSuperview
()
.
offset
(
15
*
RScreenW
())
make
.
top
.
equalToSuperview
()
.
offset
(
14
*
RScreenH
())
make
.
width
.
equalTo
(
86
*
RScreenW
())
make
.
height
.
equalTo
(
28
)
make
.
width
.
equalTo
(
345
*
RScreenW
())
make
.
height
.
equalTo
(
32
)
}
self
.
tableView
.
snp
.
makeConstraints
{
make
in
...
...
@@ -56,7 +67,7 @@ class ContactModuleView : UIView {
make
.
top
.
equalTo
(
self
.
titleLabel
.
snp
.
bottom
)
.
offset
(
18
*
RScreenH
())
make
.
width
.
equalTo
(
345
*
RScreenW
())
make
.
centerX
.
equalToSuperview
()
make
.
bottom
.
equalToSuperview
()
make
.
bottom
.
equalToSuperview
()
.
offset
(
-
34
)
}
}
...
...
@@ -67,7 +78,6 @@ class ContactModuleView : UIView {
extension
ContactModuleView
:
UITableViewDataSource
,
UITableViewDelegate
{
func
numberOfSections
(
in
tableView
:
UITableView
)
->
Int
{
return
self
.
moduleViewData
.
count
}
...
...
@@ -79,9 +89,8 @@ extension ContactModuleView:UITableViewDataSource, UITableViewDelegate {
func
tableView
(
_
tableView
:
UITableView
,
cellForRowAt
indexPath
:
IndexPath
)
->
UITableViewCell
{
let
cell
=
tableView
.
dequeueReusableCell
(
withIdentifier
:
"CustomContactModuleTableViewCell"
,
for
:
indexPath
)
as!
CustomContactModuleTableViewCell
let
titleText
=
self
.
moduleViewData
[
indexPath
.
row
]
.
titleText
let
subTitleText
=
self
.
moduleViewData
[
indexPath
.
row
]
.
subTitleText
cell
.
selectionStyle
=
.
none
let
titleText
=
self
.
moduleViewData
[
indexPath
.
section
]
.
titleText
let
subTitleText
=
self
.
moduleViewData
[
indexPath
.
section
]
.
subTitleText
cell
.
configure
(
title
:
titleText
,
subtitle
:
subTitleText
)
return
cell
}
...
...
@@ -90,16 +99,48 @@ extension ContactModuleView:UITableViewDataSource, UITableViewDelegate {
return
74
}
// 实现 UITableViewDelegate 协议方法,设置 header 的高度
func
tableView
(
_
tableView
:
UITableView
,
heightForHeaderInSection
section
:
Int
)
->
CGFloat
{
return
12
return
section
==
0
?
0
:
12
}
// 实现 UITableViewDelegate 协议方法,返回 header 视图
func
tableView
(
_
tableView
:
UITableView
,
viewForHeaderInSection
section
:
Int
)
->
UIView
?
{
let
headerView
=
UIView
()
headerView
.
backgroundColor
=
.
clear
return
headerView
}
func
tableView
(
_
tableView
:
UITableView
,
didSelectRowAt
indexPath
:
IndexPath
)
{
// 跳转新页面
if
indexPath
.
section
==
0
{
// 跳转重复联系人页面
let
vc
:
ContactsDupViewController
=
ContactsDupViewController
()
vc
.
dataSourceModel
=
self
.
dataSourceModel
?
.
duplicates
self
.
responderViewController
()?
.
navigationController
?
.
pushViewController
(
vc
,
animated
:
true
)
}
if
indexPath
.
section
==
1
{
// 跳转不完整联系人页面
let
vc
:
ContactIncompleteViewController
=
ContactIncompleteViewController
()
vc
.
dataSourceModel
=
self
.
dataSourceModel
?
.
incompleteContacts
self
.
responderViewController
()?
.
navigationController
?
.
pushViewController
(
vc
,
animated
:
true
)
}
if
indexPath
.
section
==
2
{
// 跳转备份页面
let
vc
:
ContactBackupViewController
=
ContactBackupViewController
()
vc
.
dataSourceModel
=
self
.
dataSourceModel
?
.
backups
vc
.
dataSourceAllModel
=
self
.
dataSourceModel
self
.
responderViewController
()?
.
navigationController
?
.
pushViewController
(
vc
,
animated
:
true
)
}
if
indexPath
.
section
==
3
{
// 跳转所有联系人页面
let
vc
:
ContactAllViewController
=
ContactAllViewController
()
vc
.
dataSourceModel
=
self
.
dataSourceModel
!.
allContacts
self
.
responderViewController
()?
.
navigationController
?
.
pushViewController
(
vc
,
animated
:
true
)
}
}
}
...
...
@@ -130,9 +171,10 @@ class CustomContactModuleTableViewCell: UITableViewCell {
super
.
init
(
style
:
style
,
reuseIdentifier
:
reuseIdentifier
)
setupUI
()
setupConstraints
()
contentView
.
layer
.
cornerRadius
=
12
contentView
.
clipsToBounds
=
true
self
.
contentView
.
backgroundColor
=
UIColor
(
red
:
0.95
,
green
:
0.96
,
blue
:
0.99
,
alpha
:
1
)
self
.
layer
.
cornerRadius
=
12
self
.
clipsToBounds
=
true
self
.
selectionStyle
=
.
none
self
.
backgroundColor
=
UIColor
(
red
:
0.95
,
green
:
0.96
,
blue
:
0.99
,
alpha
:
1
)
}
required
init
?(
coder
:
NSCoder
)
{
...
...
@@ -140,9 +182,9 @@ class CustomContactModuleTableViewCell: UITableViewCell {
}
private
func
setupUI
()
{
contentView
.
addSubview
(
titleLabel
)
contentView
.
addSubview
(
subtitleLabel
)
contentView
.
addSubview
(
arrowImageView
)
self
.
addSubview
(
titleLabel
)
self
.
addSubview
(
subtitleLabel
)
self
.
addSubview
(
arrowImageView
)
}
private
func
setupConstraints
()
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment