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
6e41a98b
Commit
6e41a98b
authored
May 07, 2025
by
CZ1004
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
【新增】添加重复联系人点击逻辑
parent
66ed2451
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
253 additions
and
34 deletions
+253
-34
ContactsDupViewController.swift
...ession/Contact/Controller/ContactsDupViewController.swift
+58
-0
CustomContactDupTableViewCell.swift
...ion/Contact/View/Cell/CustomContactDupTableViewCell.swift
+6
-1
CustomDupHeaderView.swift
...Class/Session/Contact/View/Cell/CustomDupHeaderView.swift
+87
-0
ContactDupNormalView.swift
...Class/Session/Contact/View/Dup/ContactDupNormalView.swift
+102
-33
No files found.
PhoneManager/Class/Session/Contact/Controller/ContactsDupViewController.swift
View file @
6e41a98b
...
...
@@ -6,15 +6,25 @@
//
import
Foundation
import
SnapKit
class
ContactsDupViewController
:
BaseViewController
{
var
dataSourceModel
:
[[
ContactModel
]]?
private
var
widthConstraint
:
Constraint
?
lazy
var
navView
:
ContactNavView
=
{
let
view
=
ContactNavView
()
return
view
}()
lazy
var
selectAllButton
:
SelectAllButton
=
{
let
view
=
SelectAllButton
()
view
.
clipsToBounds
=
true
view
.
layer
.
cornerRadius
=
16
return
view
}()
lazy
var
emptyView
:
ContactNoDupView
=
{
let
view
=
ContactNoDupView
()
return
view
...
...
@@ -35,6 +45,14 @@ class ContactsDupViewController : BaseViewController {
make
.
left
.
right
.
equalToSuperview
()
make
.
bottom
.
equalToSuperview
()
}
self
.
navView
.
addSubview
(
self
.
selectAllButton
)
self
.
selectAllButton
.
snp
.
makeConstraints
{
make
in
make
.
right
.
equalTo
(
-
15
*
RScreenW
())
make
.
centerY
.
equalTo
(
self
.
navView
.
backButton
.
snp
.
centerY
)
widthConstraint
=
make
.
width
.
equalTo
(
115
)
.
constraint
make
.
height
.
equalTo
(
32
)
}
}
func
setNormalPage
(){
...
...
@@ -60,10 +78,50 @@ class ContactsDupViewController : BaseViewController {
}
self
.
setDefaultPage
()
self
.
selectAllButton
.
tapCallback
=
{[
weak
self
]
isSelected
in
guard
let
self
else
{
return
}
DispatchQueue
.
main
.
async
{
// 选择之后,更新宽度约束的常量值
if
isSelected
{
self
.
widthConstraint
?
.
update
(
offset
:
131
)
if
let
data
=
self
.
dataSourceModel
{
for
(
index
,
item
)
in
data
.
enumerated
(){
self
.
normalView
.
selectData
[
String
(
index
)]
=
item
}
}
}
else
{
self
.
widthConstraint
?
.
update
(
offset
:
115
)
self
.
normalView
.
selectData
=
[:]
}
// 强制重新布局
UIView
.
animate
(
withDuration
:
0.3
)
{
self
.
selectAllButton
.
setNeedsLayout
()
self
.
selectAllButton
.
layoutIfNeeded
()
}
self
.
normalView
.
tableView
.
reloadData
()
}
}
self
.
normalView
.
dataChangeCallBack
=
{[
weak
self
]
changed
in
guard
let
self
else
{
return
}
DispatchQueue
.
main
.
async
{
// 选择之后,更新宽度约束的常量值
if
changed
{
self
.
widthConstraint
?
.
update
(
offset
:
131
)
self
.
selectAllButton
.
isSelected
=
true
}
else
{
self
.
widthConstraint
?
.
update
(
offset
:
115
)
self
.
selectAllButton
.
isSelected
=
false
}
}
}
}
}
extension
ContactsDupViewController
{
...
...
PhoneManager/Class/Session/Contact/View/Cell/CustomContactDupTableViewCell.swift
View file @
6e41a98b
...
...
@@ -10,6 +10,9 @@ import Foundation
class
CustomContactDupTableViewCell
:
UITableViewCell
{
var
indexPath
:
IndexPath
?
var
cellSelectCallCack
:
(
IndexPath
,
Bool
)
->
Void
=
{
index
,
choose
in
}
var
model
:
ContactModel
?{
didSet
{
...
...
@@ -99,7 +102,9 @@ class CustomContactDupTableViewCell : UITableViewCell {
extension
CustomContactDupTableViewCell
{
@objc
private
func
selectContact
(
_
sender
:
UIButton
)
{
sender
.
isSelected
=
!
sender
.
isSelected
// buttonSelectCallBack(model!,sender.isSelected)
if
let
indexPath
=
self
.
indexPath
{
self
.
cellSelectCallCack
(
indexPath
,
sender
.
isSelected
)
}
}
...
...
PhoneManager/Class/Session/Contact/View/Cell/CustomDupHeaderView.swift
0 → 100644
View file @
6e41a98b
//
// CustomDupHeaderView.swift
// PhoneManager
//
// Created by edy on 2025/5/7.
//
import
Foundation
class
CustomDupHeaderView
:
UITableViewHeaderFooterView
{
var
model
:
[
ContactModel
]
=
[]
{
didSet
{
DispatchQueue
.
main
.
async
{
self
.
tiplabel
.
text
=
"
\(
self
.
model
.
count
)
Duplicate Contacts"
}
}
}
var
headerCallback
:
([
ContactModel
])
->
Void
=
{
array
in
}
var
selectStatus
:
Bool
=
false
lazy
var
tiplabel
:
UILabel
=
{
let
label
=
UILabel
()
label
.
text
=
"
\(
self
.
model
.
count
)
Duplicate Contacts"
label
.
textAlignment
=
.
left
label
.
font
=
UIFont
.
systemFont
(
ofSize
:
16
,
weight
:
.
medium
)
label
.
textColor
=
UIColor
(
red
:
0.4
,
green
:
0.4
,
blue
:
0.4
,
alpha
:
1
)
return
label
}()
lazy
var
subLabel
:
UILabel
=
{
let
selectLabel
=
UILabel
()
selectLabel
.
textAlignment
=
.
right
selectLabel
.
textColor
=
UIColor
(
red
:
0
,
green
:
0.51
,
blue
:
1
,
alpha
:
1
)
if
self
.
selectStatus
{
selectLabel
.
text
=
"Select All"
}
else
{
selectLabel
.
text
=
"Deselect All"
}
let
tap
=
UITapGestureRecognizer
()
tap
.
addTarget
(
self
,
action
:
#selector(
cellSelectTap
)
)
selectLabel
.
isUserInteractionEnabled
=
true
selectLabel
.
addGestureRecognizer
(
tap
)
return
selectLabel
}()
override
init
(
reuseIdentifier
:
String
?)
{
super
.
init
(
reuseIdentifier
:
reuseIdentifier
)
self
.
backgroundColor
=
.
clear
self
.
addSubview
(
self
.
tiplabel
)
self
.
tiplabel
.
snp
.
makeConstraints
{
make
in
make
.
left
.
top
.
equalToSuperview
()
make
.
width
.
equalTo
(
200
)
make
.
height
.
equalTo
(
22
)
}
self
.
addSubview
(
self
.
subLabel
)
self
.
subLabel
.
snp
.
makeConstraints
{
make
in
make
.
width
.
equalTo
(
100
)
make
.
height
.
equalTo
(
22
)
make
.
right
.
equalToSuperview
()
make
.
centerY
.
equalTo
(
self
.
tiplabel
.
snp
.
centerY
)
}
}
required
init
?(
coder
:
NSCoder
)
{
fatalError
(
"init(coder:) has not been implemented"
)
}
}
extension
CustomDupHeaderView
{
@objc
func
cellSelectTap
(){
if
self
.
selectStatus
{
self
.
subLabel
.
text
=
"Deselect All"
}
else
{
self
.
subLabel
.
text
=
"Select All"
}
self
.
headerCallback
(
self
.
model
)
}
}
PhoneManager/Class/Session/Contact/View/Dup/ContactDupNormalView.swift
View file @
6e41a98b
...
...
@@ -11,7 +11,9 @@ class ContactDupNormalView : UIView {
var
dataSourceModel
:
[[
ContactModel
]]
=
[]
var
selectData
:
[
Int
:
[
ContactModel
]]
=
[:]
var
selectData
:
[
String
:
[
ContactModel
]]
=
[:]
var
dataChangeCallBack
:(
Bool
)
->
Void
=
{
changed
in
}
/// 选择的联系人
private
var
selectedContacts
:
[
ContactModel
]
=
[]
...
...
@@ -94,8 +96,31 @@ extension ContactDupNormalView : UITableViewDelegate,UITableViewDataSource{
func
tableView
(
_
tableView
:
UITableView
,
cellForRowAt
indexPath
:
IndexPath
)
->
UITableViewCell
{
let
cell
=
tableView
.
dequeueReusableCell
(
withIdentifier
:
"CustomContactDupTableViewCell"
,
for
:
indexPath
)
as!
CustomContactDupTableViewCell
cell
.
indexPath
=
indexPath
cell
.
model
=
self
.
dataSourceModel
[
indexPath
.
section
][
indexPath
.
row
]
cell
.
cellSelectCallCack
=
{[
weak
self
]
index
,
choose
in
guard
let
self
else
{
return
}
if
choose
{
self
.
saveSelectModel
(
index
:
index
)
}
else
{
self
.
removeSelectModel
(
index
:
index
)
}
}
// 如果有选中的更新
DispatchQueue
.
main
.
async
{
if
let
tempArray
=
self
.
selectData
[
String
(
indexPath
.
section
)]
{
if
tempArray
.
contains
(
where
:
{
$0
.
identifier
==
cell
.
model
?
.
identifier
})
{
cell
.
selectButton
.
isSelected
=
true
}
else
{
cell
.
selectButton
.
isSelected
=
false
}
}
else
{
cell
.
selectButton
.
isSelected
=
false
}
}
return
cell
}
func
tableView
(
_
tableView
:
UITableView
,
heightForRowAt
indexPath
:
IndexPath
)
->
CGFloat
{
...
...
@@ -103,30 +128,27 @@ extension ContactDupNormalView : UITableViewDelegate,UITableViewDataSource{
}
func
tableView
(
_
tableView
:
UITableView
,
viewForHeaderInSection
section
:
Int
)
->
UIView
?
{
let
view
=
UIView
(
frame
:
CGRect
(
x
:
0
,
y
:
0
,
width
:
self
.
tableView
.
width
,
height
:
22
))
view
.
backgroundColor
=
.
clear
let
label
=
UILabel
(
frame
:
CGRect
(
x
:
0
,
y
:
0
,
width
:
200
,
height
:
22
))
label
.
text
=
"
\(
self
.
dataSourceModel
[
section
]
.
count
)
Duplicate Contacts"
label
.
textAlignment
=
.
left
label
.
font
=
UIFont
.
systemFont
(
ofSize
:
16
,
weight
:
.
medium
)
label
.
textColor
=
UIColor
(
red
:
0.4
,
green
:
0.4
,
blue
:
0.4
,
alpha
:
1
)
view
.
addSubview
(
label
)
let
selectLabel
=
UILabel
(
frame
:
CGRect
(
x
:
0
,
y
:
0
,
width
:
100
,
height
:
22
))
selectLabel
.
center
=
CGPointMake
(
self
.
tableView
.
width
-
50
,
label
.
centerY
)
selectLabel
.
textAlignment
=
.
right
selectLabel
.
textColor
=
UIColor
(
red
:
0
,
green
:
0.51
,
blue
:
1
,
alpha
:
1
)
selectLabel
.
text
=
"Select All"
let
tap
=
UITapGestureRecognizer
()
tap
.
addTarget
(
self
,
action
:
#selector(
cellSelectTap
)
)
selectLabel
.
isUserInteractionEnabled
=
true
selectLabel
.
addGestureRecognizer
(
tap
)
view
.
addSubview
(
selectLabel
)
let
view
=
CustomDupHeaderView
(
frame
:
CGRect
(
x
:
0
,
y
:
0
,
width
:
self
.
tableView
.
width
,
height
:
22
))
view
.
model
=
self
.
dataSourceModel
[
section
]
// UI判断
changeHeaderSelectButton
(
section
:
section
,
view
:
view
)
view
.
headerCallback
=
{[
weak
self
]
data
in
guard
let
self
else
{
return
}
if
let
tempData
=
self
.
selectData
[
String
(
section
)]
{
if
tempData
.
count
>
0
{
self
.
selectData
[
String
(
section
)]
=
[]
}
else
{
self
.
selectData
[
String
(
section
)]
=
data
}
}
else
{
self
.
selectData
[
String
(
section
)]
=
data
}
DispatchQueue
.
main
.
async
{
self
.
dataChangeCallBack
(
self
.
isAllData
())
tableView
.
reloadSections
(
IndexSet
(
integer
:
section
),
with
:
.
automatic
)
}
}
return
view
}
func
tableView
(
_
tableView
:
UITableView
,
heightForHeaderInSection
section
:
Int
)
->
CGFloat
{
...
...
@@ -135,17 +157,64 @@ extension ContactDupNormalView : UITableViewDelegate,UITableViewDataSource{
// MARK: 响应方法
@objc
func
cellSelectTap
(){
// MARK: 辅助方法
func
changeHeaderSelectButton
(
section
:
Int
,
view
:
CustomDupHeaderView
){
DispatchQueue
.
main
.
async
{
if
let
tempData
=
self
.
selectData
[
String
(
section
)]
{
if
tempData
.
count
==
self
.
dataSourceModel
[
section
]
.
count
{
// 改变UI
view
.
subLabel
.
text
=
"Deselect All"
}
else
{
view
.
subLabel
.
text
=
"Select All"
}
}
else
{
view
.
subLabel
.
text
=
"Select All"
}
}
}
func
saveSelectModel
(
index
:
IndexPath
){
let
tempModel
=
self
.
dataSourceModel
[
index
.
section
][
index
.
row
]
if
var
array
=
self
.
selectData
[
String
(
index
.
section
)]
{
array
.
append
(
tempModel
)
self
.
selectData
[
String
(
index
.
section
)]
=
array
}
else
{
self
.
selectData
[
String
(
index
.
section
)]
=
[
tempModel
]
}
changeHeaderSelectButton
(
section
:
index
.
section
,
view
:
self
.
tableView
.
headerView
(
forSection
:
index
.
section
)
as!
CustomDupHeaderView
)
// 改变导航栏的选择按钮状态
self
.
dataChangeCallBack
(
isAllData
())
}
// MARK: 辅助方法
func
removeSelectModel
(
index
:
IndexPath
){
let
tempModel
=
self
.
dataSourceModel
[
index
.
section
][
index
.
row
]
if
var
array
=
self
.
selectData
[
String
(
index
.
section
)]
{
if
array
.
contains
(
tempModel
){
array
.
removeAll
(
where
:
{
$0
.
identifier
==
tempModel
.
identifier
})
}
self
.
selectData
[
String
(
index
.
section
)]
=
array
}
// 改变当前section的选择按钮
changeHeaderSelectButton
(
section
:
index
.
section
,
view
:
self
.
tableView
.
headerView
(
forSection
:
index
.
section
)
as!
CustomDupHeaderView
)
// 改变导航栏的选择按钮状态
self
.
dataChangeCallBack
(
isAllData
())
}
// 判断当前数量是不是全部
func
isAllData
()
->
Bool
{
var
selectCount
=
0
for
(
_
,
value
)
in
self
.
selectData
{
selectCount
+=
value
.
count
}
var
allDataCount
=
0
for
item
in
self
.
dataSourceModel
{
allDataCount
+=
item
.
count
}
if
selectCount
==
allDataCount
{
return
true
}
return
false
}
}
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