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 {
...
@@ -49,6 +49,7 @@ class ContactViewController : BaseViewController {
}
}
}
}
func
setNormalPage
(){
func
setNormalPage
(){
self
.
emptyView
.
removeFromSuperview
()
self
.
view
.
addSubview
(
self
.
moduleView
)
self
.
view
.
addSubview
(
self
.
moduleView
)
self
.
moduleView
.
snp
.
makeConstraints
{
make
in
self
.
moduleView
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalTo
(
self
.
navView
.
snp
.
bottom
)
.
offset
(
0
)
make
.
top
.
equalTo
(
self
.
navView
.
snp
.
bottom
)
.
offset
(
0
)
...
@@ -59,6 +60,7 @@ class ContactViewController : BaseViewController {
...
@@ -59,6 +60,7 @@ class ContactViewController : BaseViewController {
override
func
viewWillAppear
(
_
animated
:
Bool
)
{
override
func
viewWillAppear
(
_
animated
:
Bool
)
{
super
.
viewWillAppear
(
animated
)
super
.
viewWillAppear
(
animated
)
// 请求联系人权限
// 请求联系人权限
self
.
setDefaultPage
()
requestContactsPermission
{
permission
in
requestContactsPermission
{
permission
in
DispatchQueue
.
main
.
async
{
DispatchQueue
.
main
.
async
{
if
permission
{
if
permission
{
...
@@ -67,9 +69,6 @@ class ContactViewController : BaseViewController {
...
@@ -67,9 +69,6 @@ class ContactViewController : BaseViewController {
self
.
setNormalPage
()
self
.
setNormalPage
()
// 初始化数据
// 初始化数据
self
.
initContatsInfo
()
self
.
initContatsInfo
()
}
else
{
// 没有权限显示空白页
self
.
setDefaultPage
()
}
}
}
}
...
@@ -95,51 +94,67 @@ extension ContactViewController{
...
@@ -95,51 +94,67 @@ extension ContactViewController{
moduleViewData
.
append
(
model4
)
moduleViewData
.
append
(
model4
)
self
.
moduleView
.
moduleViewData
=
moduleViewData
self
.
moduleView
.
moduleViewData
=
moduleViewData
self
.
moduleView
.
dataSourceModel
=
self
.
dataSourceModel
}
}
/// 初始化联系人数据
/// 初始化联系人数据
func
initContatsInfo
()
{
func
initContatsInfo
()
{
DispatchQueue
.
global
()
.
async
{
let
store
=
CNContactStore
()
let
store
=
CNContactStore
()
let
keysToFetch
=
[
let
keysToFetch
=
[
CNContactGivenNameKey
as
CNKeyDescriptor
,
CNContactGivenNameKey
as
CNKeyDescriptor
,
CNContactFamilyNameKey
as
CNKeyDescriptor
,
CNContactFamilyNameKey
as
CNKeyDescriptor
,
CNContactPhoneNumbersKey
as
CNKeyDescriptor
CNContactPhoneNumbersKey
as
CNKeyDescriptor
]
]
do
{
do
{
let
request
=
CNContactFetchRequest
(
keysToFetch
:
keysToFetch
)
let
request
=
CNContactFetchRequest
(
keysToFetch
:
keysToFetch
)
// 创建数组
try
store
.
enumerateContacts
(
with
:
request
)
{
contact
,
stop
in
var
incompleteContacts
:
[
ContactModel
]
=
[]
let
givenName
=
contact
.
givenName
var
allContacts
:
[
ContactModel
]
=
[]
let
familyName
=
contact
.
familyName
try
store
.
enumerateContacts
(
with
:
request
)
{
contact
,
stop
in
let
fullName
=
"
\(
familyName
)
\(
givenName
)
"
let
givenName
=
contact
.
givenName
// 创建数组
let
familyName
=
contact
.
familyName
var
incompleteContacts
:
[
ContactModel
]
=
[]
let
fullName
=
"
\(
familyName
)
\(
givenName
)
"
var
allContacts
:
[
ContactModel
]
=
[]
let
phoneNumbers
=
contact
.
phoneNumbers
.
map
{
$0
.
value
.
stringValue
}
for
phone
in
contact
.
phoneNumbers
{
let
model
=
ContactModel
.
init
(
name
:
fullName
,
phoneNumber
:
phoneNumbers
,
identifier
:
contact
.
identifier
)
let
phoneNumber
=
phone
.
value
.
stringValue
if
fullName
.
isEmpty
||
phoneNumbers
.
count
<=
0
{
let
model
=
ContactModel
.
init
(
name
:
fullName
,
phoneNumber
:
phoneNumber
)
incompleteContacts
.
append
(
model
)
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
)
"
)
}
}
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
)
{
func
requestContactsPermission
(
completion
:
@escaping
(
Bool
)
->
Void
)
{
let
store
=
CNContactStore
()
let
store
=
CNContactStore
()
switch
CNContactStore
.
authorizationStatus
(
for
:
.
contacts
)
{
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 @@
...
@@ -6,30 +6,34 @@
//
//
import
Foundation
import
Foundation
import
Contacts
struct
ContactModel
{
struct
ContactModel
:
Codable
,
Equatable
{
// 联系人名字
// 联系人名字
var
name
:
String
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
.
name
=
name
self
.
phoneNumber
=
phoneNumber
self
.
phoneNumber
=
phoneNumber
self
.
identifier
=
identifier
}
}
}
}
extension
ContactModel
{
struct
BackupsModel
{
init
?(
contact
:
CNContact
)
{
let
fullName
=
"
\(
contact
.
givenName
)
\(
contact
.
familyName
)
"
.
trimmingCharacters
(
in
:
.
whitespaces
)
// 备份时间
let
phoneNumbers
=
contact
.
phoneNumbers
.
map
{
$0
.
value
.
stringValue
}
var
backupsDate
:
Date
let
uniqueID
=
contact
.
identifier
if
fullName
.
isEmpty
||
phoneNumbers
.
isEmpty
||
uniqueID
.
isEmpty
{
// 备份的联系人
return
nil
var
backupsContacts
:
[
ContactModel
]
}
self
.
name
=
fullName
init
(
backupsDate
:
Date
,
backupsContacts
:
[
ContactModel
])
{
self
.
phoneNumber
=
phoneNumbers
self
.
backupsDate
=
backupsDate
self
.
identifier
=
uniqueID
self
.
backupsContacts
=
backupsContacts
}
}
}
}
...
@@ -40,11 +44,11 @@ struct ContactModuleModel {
...
@@ -40,11 +44,11 @@ struct ContactModuleModel {
var
incompleteContacts
:
[
ContactModel
]
var
incompleteContacts
:
[
ContactModel
]
var
backups
:
[
Backup
s
Model
]
var
backups
:
[
Backup
Info
Model
]
var
allContacts
:
[
ContactModel
]
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
.
duplicates
=
duplicates
self
.
incompleteContacts
=
incompleteContacts
self
.
incompleteContacts
=
incompleteContacts
self
.
backups
=
backups
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 {
...
@@ -87,8 +87,8 @@ extension ContactDefaultView {
self
.
titleLabel
.
snp
.
makeConstraints
{
make
in
self
.
titleLabel
.
snp
.
makeConstraints
{
make
in
make
.
left
.
equalToSuperview
()
.
offset
(
15
*
RScreenW
())
make
.
left
.
equalToSuperview
()
.
offset
(
15
*
RScreenW
())
make
.
top
.
equalToSuperview
()
.
offset
(
14
*
RScreenH
())
make
.
top
.
equalToSuperview
()
.
offset
(
14
*
RScreenH
())
make
.
width
.
equalTo
(
86
*
RScreenW
())
make
.
width
.
equalTo
(
345
*
RScreenW
())
make
.
height
.
equalTo
(
28
)
make
.
height
.
equalTo
(
32
)
}
}
self
.
imageView
.
snp
.
makeConstraints
{
make
in
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
...
@@ -10,7 +10,10 @@ import Foundation
class
ContactModuleView
:
UIView
{
class
ContactModuleView
:
UIView
{
// 总数据
var
dataSourceModel
:
ContactModuleModel
?
// 当前页面显示数据
var
moduleViewData
:
[
ModuleDataModel
]
=
[]
var
moduleViewData
:
[
ModuleDataModel
]
=
[]
lazy
var
titleLabel
:
UILabel
=
{
lazy
var
titleLabel
:
UILabel
=
{
...
@@ -23,13 +26,21 @@ class ContactModuleView : UIView {
...
@@ -23,13 +26,21 @@ class ContactModuleView : UIView {
}()
}()
lazy
var
tableView
:
UITableView
=
{
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
.
dataSource
=
self
tableView
.
delegate
=
self
tableView
.
delegate
=
self
tableView
.
register
(
CustomContactModuleTableViewCell
.
self
,
forCellReuseIdentifier
:
"CustomContactModuleTableViewCell"
)
tableView
.
register
(
CustomContactModuleTableViewCell
.
self
,
forCellReuseIdentifier
:
"CustomContactModuleTableViewCell"
)
tableView
.
separatorStyle
=
.
none
tableView
.
separatorStyle
=
.
none
tableView
.
backgroundColor
=
.
clear
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
return
tableView
}()
}()
...
@@ -47,8 +58,8 @@ class ContactModuleView : UIView {
...
@@ -47,8 +58,8 @@ class ContactModuleView : UIView {
self
.
titleLabel
.
snp
.
makeConstraints
{
make
in
self
.
titleLabel
.
snp
.
makeConstraints
{
make
in
make
.
left
.
equalToSuperview
()
.
offset
(
15
*
RScreenW
())
make
.
left
.
equalToSuperview
()
.
offset
(
15
*
RScreenW
())
make
.
top
.
equalToSuperview
()
.
offset
(
14
*
RScreenH
())
make
.
top
.
equalToSuperview
()
.
offset
(
14
*
RScreenH
())
make
.
width
.
equalTo
(
86
*
RScreenW
())
make
.
width
.
equalTo
(
345
*
RScreenW
())
make
.
height
.
equalTo
(
28
)
make
.
height
.
equalTo
(
32
)
}
}
self
.
tableView
.
snp
.
makeConstraints
{
make
in
self
.
tableView
.
snp
.
makeConstraints
{
make
in
...
@@ -56,7 +67,7 @@ class ContactModuleView : UIView {
...
@@ -56,7 +67,7 @@ class ContactModuleView : UIView {
make
.
top
.
equalTo
(
self
.
titleLabel
.
snp
.
bottom
)
.
offset
(
18
*
RScreenH
())
make
.
top
.
equalTo
(
self
.
titleLabel
.
snp
.
bottom
)
.
offset
(
18
*
RScreenH
())
make
.
width
.
equalTo
(
345
*
RScreenW
())
make
.
width
.
equalTo
(
345
*
RScreenW
())
make
.
centerX
.
equalToSuperview
()
make
.
centerX
.
equalToSuperview
()
make
.
bottom
.
equalToSuperview
()
make
.
bottom
.
equalToSuperview
()
.
offset
(
-
34
)
}
}
}
}
...
@@ -67,7 +78,6 @@ class ContactModuleView : UIView {
...
@@ -67,7 +78,6 @@ class ContactModuleView : UIView {
extension
ContactModuleView
:
UITableViewDataSource
,
UITableViewDelegate
{
extension
ContactModuleView
:
UITableViewDataSource
,
UITableViewDelegate
{
func
numberOfSections
(
in
tableView
:
UITableView
)
->
Int
{
func
numberOfSections
(
in
tableView
:
UITableView
)
->
Int
{
return
self
.
moduleViewData
.
count
return
self
.
moduleViewData
.
count
}
}
...
@@ -79,9 +89,8 @@ extension ContactModuleView:UITableViewDataSource, UITableViewDelegate {
...
@@ -79,9 +89,8 @@ extension ContactModuleView:UITableViewDataSource, UITableViewDelegate {
func
tableView
(
_
tableView
:
UITableView
,
cellForRowAt
indexPath
:
IndexPath
)
->
UITableViewCell
{
func
tableView
(
_
tableView
:
UITableView
,
cellForRowAt
indexPath
:
IndexPath
)
->
UITableViewCell
{
let
cell
=
tableView
.
dequeueReusableCell
(
withIdentifier
:
"CustomContactModuleTableViewCell"
,
for
:
indexPath
)
as!
CustomContactModuleTableViewCell
let
cell
=
tableView
.
dequeueReusableCell
(
withIdentifier
:
"CustomContactModuleTableViewCell"
,
for
:
indexPath
)
as!
CustomContactModuleTableViewCell
let
titleText
=
self
.
moduleViewData
[
indexPath
.
row
]
.
titleText
let
titleText
=
self
.
moduleViewData
[
indexPath
.
section
]
.
titleText
let
subTitleText
=
self
.
moduleViewData
[
indexPath
.
row
]
.
subTitleText
let
subTitleText
=
self
.
moduleViewData
[
indexPath
.
section
]
.
subTitleText
cell
.
selectionStyle
=
.
none
cell
.
configure
(
title
:
titleText
,
subtitle
:
subTitleText
)
cell
.
configure
(
title
:
titleText
,
subtitle
:
subTitleText
)
return
cell
return
cell
}
}
...
@@ -90,16 +99,48 @@ extension ContactModuleView:UITableViewDataSource, UITableViewDelegate {
...
@@ -90,16 +99,48 @@ extension ContactModuleView:UITableViewDataSource, UITableViewDelegate {
return
74
return
74
}
}
// 实现 UITableViewDelegate 协议方法,设置 header 的高度
func
tableView
(
_
tableView
:
UITableView
,
heightForHeaderInSection
section
:
Int
)
->
CGFloat
{
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
?
{
func
tableView
(
_
tableView
:
UITableView
,
viewForHeaderInSection
section
:
Int
)
->
UIView
?
{
let
headerView
=
UIView
()
let
headerView
=
UIView
()
headerView
.
backgroundColor
=
.
clear
headerView
.
backgroundColor
=
.
clear
return
headerView
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 {
...
@@ -130,9 +171,10 @@ class CustomContactModuleTableViewCell: UITableViewCell {
super
.
init
(
style
:
style
,
reuseIdentifier
:
reuseIdentifier
)
super
.
init
(
style
:
style
,
reuseIdentifier
:
reuseIdentifier
)
setupUI
()
setupUI
()
setupConstraints
()
setupConstraints
()
contentView
.
layer
.
cornerRadius
=
12
self
.
layer
.
cornerRadius
=
12
contentView
.
clipsToBounds
=
true
self
.
clipsToBounds
=
true
self
.
contentView
.
backgroundColor
=
UIColor
(
red
:
0.95
,
green
:
0.96
,
blue
:
0.99
,
alpha
:
1
)
self
.
selectionStyle
=
.
none
self
.
backgroundColor
=
UIColor
(
red
:
0.95
,
green
:
0.96
,
blue
:
0.99
,
alpha
:
1
)
}
}
required
init
?(
coder
:
NSCoder
)
{
required
init
?(
coder
:
NSCoder
)
{
...
@@ -140,9 +182,9 @@ class CustomContactModuleTableViewCell: UITableViewCell {
...
@@ -140,9 +182,9 @@ class CustomContactModuleTableViewCell: UITableViewCell {
}
}
private
func
setupUI
()
{
private
func
setupUI
()
{
contentView
.
addSubview
(
titleLabel
)
self
.
addSubview
(
titleLabel
)
contentView
.
addSubview
(
subtitleLabel
)
self
.
addSubview
(
subtitleLabel
)
contentView
.
addSubview
(
arrowImageView
)
self
.
addSubview
(
arrowImageView
)
}
}
private
func
setupConstraints
()
{
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