Commit afd5ac8a authored by CZ1004's avatar CZ1004

联系人

parent 92524ed8
//
// 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()
}
}
}
//
// 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()
}
}
}
}
//
// 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()
}
}
......@@ -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) {
......
//
// 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()
}
}
......@@ -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: [BackupsModel]
var backups: [BackupInfoModel]
var allContacts: [ContactModel]
init(duplicates: [[ContactModel]], incompleteContacts: [ContactModel], backups: [BackupsModel], allContacts: [ContactModel]) {
init(duplicates: [[ContactModel]], incompleteContacts: [ContactModel], backups: [BackupInfoModel], allContacts: [ContactModel]) {
self.duplicates = duplicates
self.incompleteContacts = incompleteContacts
self.backups = backups
......
//
// 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")
}
}
//
// 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")
}
}
//
// 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)
}
}
}
//
// 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)
}
}
//
// 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")
}
}
//
// 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()
}
}
//
// 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)
}
}
}
//
// 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)
}
}
}
//
// 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)
}
}
//
// 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()
}
}
//
// 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()
}
}
//
// 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()
}
}
//
// 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")
}
}
//
// 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")
}
}
......@@ -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
......
......@@ -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() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment