Commit e6ef2048 authored by Alex朱枝文's avatar Alex朱枝文

添加续签在港缴费指引

parent b97c8321
...@@ -223,6 +223,10 @@ ...@@ -223,6 +223,10 @@
044F39322CB64CC0007CA277 /* YHBottomPresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 044F39312CB64CC0007CA277 /* YHBottomPresentationController.swift */; }; 044F39322CB64CC0007CA277 /* YHBottomPresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 044F39312CB64CC0007CA277 /* YHBottomPresentationController.swift */; };
044F39342CB6507D007CA277 /* YHVisaRenewalGuideVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 044F39332CB6507D007CA277 /* YHVisaRenewalGuideVC.swift */; }; 044F39342CB6507D007CA277 /* YHVisaRenewalGuideVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 044F39332CB6507D007CA277 /* YHVisaRenewalGuideVC.swift */; };
044F39362CB6574D007CA277 /* YHVisaRenewalGuideHeaderCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 044F39352CB6574D007CA277 /* YHVisaRenewalGuideHeaderCell.swift */; }; 044F39362CB6574D007CA277 /* YHVisaRenewalGuideHeaderCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 044F39352CB6574D007CA277 /* YHVisaRenewalGuideHeaderCell.swift */; };
044F39382CB77359007CA277 /* YHVisaRenewalGuideParagraphCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 044F39372CB77359007CA277 /* YHVisaRenewalGuideParagraphCell.swift */; };
044F393A2CB7772D007CA277 /* YHVisaRenewalGuideRemarkCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 044F39392CB7772D007CA277 /* YHVisaRenewalGuideRemarkCell.swift */; };
044F393C2CB777D3007CA277 /* YHVisaRenewalGuideIndentCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 044F393B2CB777D3007CA277 /* YHVisaRenewalGuideIndentCell.swift */; };
044F393E2CB7827B007CA277 /* YHVisaRenewalGuideTipsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 044F393D2CB7827B007CA277 /* YHVisaRenewalGuideTipsCell.swift */; };
04506F552C6F57E600738EA1 /* YHFamilyMemberInfoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04506F542C6F57E600738EA1 /* YHFamilyMemberInfoCell.swift */; }; 04506F552C6F57E600738EA1 /* YHFamilyMemberInfoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04506F542C6F57E600738EA1 /* YHFamilyMemberInfoCell.swift */; };
045A08C02C37ABF500BCBABA /* YHSegmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 045A08BF2C37ABF500BCBABA /* YHSegmentView.swift */; }; 045A08C02C37ABF500BCBABA /* YHSegmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 045A08BF2C37ABF500BCBABA /* YHSegmentView.swift */; };
045A08C22C37EB8B00BCBABA /* YHMyFileListNoneCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 045A08C12C37EB8B00BCBABA /* YHMyFileListNoneCell.swift */; }; 045A08C22C37EB8B00BCBABA /* YHMyFileListNoneCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 045A08C12C37EB8B00BCBABA /* YHMyFileListNoneCell.swift */; };
...@@ -1094,6 +1098,10 @@ ...@@ -1094,6 +1098,10 @@
044F39312CB64CC0007CA277 /* YHBottomPresentationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHBottomPresentationController.swift; sourceTree = "<group>"; }; 044F39312CB64CC0007CA277 /* YHBottomPresentationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHBottomPresentationController.swift; sourceTree = "<group>"; };
044F39332CB6507D007CA277 /* YHVisaRenewalGuideVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHVisaRenewalGuideVC.swift; sourceTree = "<group>"; }; 044F39332CB6507D007CA277 /* YHVisaRenewalGuideVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHVisaRenewalGuideVC.swift; sourceTree = "<group>"; };
044F39352CB6574D007CA277 /* YHVisaRenewalGuideHeaderCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHVisaRenewalGuideHeaderCell.swift; sourceTree = "<group>"; }; 044F39352CB6574D007CA277 /* YHVisaRenewalGuideHeaderCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHVisaRenewalGuideHeaderCell.swift; sourceTree = "<group>"; };
044F39372CB77359007CA277 /* YHVisaRenewalGuideParagraphCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHVisaRenewalGuideParagraphCell.swift; sourceTree = "<group>"; };
044F39392CB7772D007CA277 /* YHVisaRenewalGuideRemarkCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHVisaRenewalGuideRemarkCell.swift; sourceTree = "<group>"; };
044F393B2CB777D3007CA277 /* YHVisaRenewalGuideIndentCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHVisaRenewalGuideIndentCell.swift; sourceTree = "<group>"; };
044F393D2CB7827B007CA277 /* YHVisaRenewalGuideTipsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHVisaRenewalGuideTipsCell.swift; sourceTree = "<group>"; };
04506F542C6F57E600738EA1 /* YHFamilyMemberInfoCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHFamilyMemberInfoCell.swift; sourceTree = "<group>"; }; 04506F542C6F57E600738EA1 /* YHFamilyMemberInfoCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHFamilyMemberInfoCell.swift; sourceTree = "<group>"; };
045A08BF2C37ABF500BCBABA /* YHSegmentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHSegmentView.swift; sourceTree = "<group>"; }; 045A08BF2C37ABF500BCBABA /* YHSegmentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHSegmentView.swift; sourceTree = "<group>"; };
045A08C12C37EB8B00BCBABA /* YHMyFileListNoneCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHMyFileListNoneCell.swift; sourceTree = "<group>"; }; 045A08C12C37EB8B00BCBABA /* YHMyFileListNoneCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHMyFileListNoneCell.swift; sourceTree = "<group>"; };
...@@ -2456,6 +2464,10 @@ ...@@ -2456,6 +2464,10 @@
044F39312CB64CC0007CA277 /* YHBottomPresentationController.swift */, 044F39312CB64CC0007CA277 /* YHBottomPresentationController.swift */,
044F392F2CB55D5E007CA277 /* YHDashLineView.swift */, 044F392F2CB55D5E007CA277 /* YHDashLineView.swift */,
044F39352CB6574D007CA277 /* YHVisaRenewalGuideHeaderCell.swift */, 044F39352CB6574D007CA277 /* YHVisaRenewalGuideHeaderCell.swift */,
044F39372CB77359007CA277 /* YHVisaRenewalGuideParagraphCell.swift */,
044F39392CB7772D007CA277 /* YHVisaRenewalGuideRemarkCell.swift */,
044F393B2CB777D3007CA277 /* YHVisaRenewalGuideIndentCell.swift */,
044F393D2CB7827B007CA277 /* YHVisaRenewalGuideTipsCell.swift */,
); );
path = V; path = V;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -5125,6 +5137,7 @@ ...@@ -5125,6 +5137,7 @@
04EC2F812C22888E002907D7 /* YHFriendRequestView.swift in Sources */, 04EC2F812C22888E002907D7 /* YHFriendRequestView.swift in Sources */,
044EE24C2C94396E00A2FE3A /* YHResignCertificatePassportTableViewCell.swift in Sources */, 044EE24C2C94396E00A2FE3A /* YHResignCertificatePassportTableViewCell.swift in Sources */,
04F2435B2C9D140C00DF2C74 /* YHHKRecordsTitleCell.swift in Sources */, 04F2435B2C9D140C00DF2C74 /* YHHKRecordsTitleCell.swift in Sources */,
044F393A2CB7772D007CA277 /* YHVisaRenewalGuideRemarkCell.swift in Sources */,
041892242C91BCF100B9FB94 /* YHResignRoundCellType.swift in Sources */, 041892242C91BCF100B9FB94 /* YHResignRoundCellType.swift in Sources */,
0430E6722C749E74000511E2 /* YHAdopterBirthViewController.swift in Sources */, 0430E6722C749E74000511E2 /* YHAdopterBirthViewController.swift in Sources */,
048058392C7F289700502CAA /* YHTravelCertificateItemView.swift in Sources */, 048058392C7F289700502CAA /* YHTravelCertificateItemView.swift in Sources */,
...@@ -5375,6 +5388,7 @@ ...@@ -5375,6 +5388,7 @@
04256E1D2C75C74200A37BA4 /* YHAppointHKResultModel.swift in Sources */, 04256E1D2C75C74200A37BA4 /* YHAppointHKResultModel.swift in Sources */,
04CE1ADB2C2AD91F001CB80A /* YHActivityTitleItemView.swift in Sources */, 04CE1ADB2C2AD91F001CB80A /* YHActivityTitleItemView.swift in Sources */,
A5FD63BF2B6250BC00D1D9DA /* YHInformationPerfectCell.swift in Sources */, A5FD63BF2B6250BC00D1D9DA /* YHInformationPerfectCell.swift in Sources */,
044F393E2CB7827B007CA277 /* YHVisaRenewalGuideTipsCell.swift in Sources */,
045EEE942B9F171A0022A143 /* YHPreviewInfoQuestionAndAnswerItemView.swift in Sources */, 045EEE942B9F171A0022A143 /* YHPreviewInfoQuestionAndAnswerItemView.swift in Sources */,
04F5F86A2C1A95BB004A463C /* YHOtherServiceViewController.swift in Sources */, 04F5F86A2C1A95BB004A463C /* YHOtherServiceViewController.swift in Sources */,
0430E6762C74A4BE000511E2 /* YHAdopterMarryViewController.swift in Sources */, 0430E6762C74A4BE000511E2 /* YHAdopterMarryViewController.swift in Sources */,
...@@ -5522,6 +5536,7 @@ ...@@ -5522,6 +5536,7 @@
0430E6662C7487B8000511E2 /* YHAdopterTravelItemTableViewCell.swift in Sources */, 0430E6662C7487B8000511E2 /* YHAdopterTravelItemTableViewCell.swift in Sources */,
045EEEE22B9F171A0022A143 /* YHMySignatureDetailViewModel.swift in Sources */, 045EEEE22B9F171A0022A143 /* YHMySignatureDetailViewModel.swift in Sources */,
045EEE7D2B9F171A0022A143 /* YHWorkExpDataModel.swift in Sources */, 045EEE7D2B9F171A0022A143 /* YHWorkExpDataModel.swift in Sources */,
044F39382CB77359007CA277 /* YHVisaRenewalGuideParagraphCell.swift in Sources */,
0485DFDA2C660EFA00B50293 /* YHPrincipleRequestModel.swift in Sources */, 0485DFDA2C660EFA00B50293 /* YHPrincipleRequestModel.swift in Sources */,
A5CA3F522C744A5000EB22F5 /* YHUploadCertificateTitleCell.swift in Sources */, A5CA3F522C744A5000EB22F5 /* YHUploadCertificateTitleCell.swift in Sources */,
045EEE832B9F171A0022A143 /* YHMainInfoPreviewModel.swift in Sources */, 045EEE832B9F171A0022A143 /* YHMainInfoPreviewModel.swift in Sources */,
...@@ -5743,6 +5758,7 @@ ...@@ -5743,6 +5758,7 @@
04EA230A2BB5172F009DA928 /* YHDocumentPromptTableViewCell.swift in Sources */, 04EA230A2BB5172F009DA928 /* YHDocumentPromptTableViewCell.swift in Sources */,
A5EB6C6F2C69FB9A0081FB6C /* YHOfficalLetterListModel.swift in Sources */, A5EB6C6F2C69FB9A0081FB6C /* YHOfficalLetterListModel.swift in Sources */,
045EEF092B9F171A0022A143 /* YHBasicInfoFillModel.swift in Sources */, 045EEF092B9F171A0022A143 /* YHBasicInfoFillModel.swift in Sources */,
044F393C2CB777D3007CA277 /* YHVisaRenewalGuideIndentCell.swift in Sources */,
044EE2422C92EF0C00A2FE3A /* YHResignCertificateDetailEVisaViewController.swift in Sources */, 044EE2422C92EF0C00A2FE3A /* YHResignCertificateDetailEVisaViewController.swift in Sources */,
A5ACE9352B4564F7002C94D2 /* YHNetRequest.swift in Sources */, A5ACE9352B4564F7002C94D2 /* YHNetRequest.swift in Sources */,
04F243612C9D488200DF2C74 /* YHHKRecordsPersonnelSelectCell.swift in Sources */, 04F243612C9D488200DF2C74 /* YHHKRecordsPersonnelSelectCell.swift in Sources */,
......
...@@ -28,6 +28,7 @@ class YHHKVisaRenewalPaymentVC: YHBaseViewController { ...@@ -28,6 +28,7 @@ class YHHKVisaRenewalPaymentVC: YHBaseViewController {
return view return view
}() }()
private var didShowGuideVC = false
private let orderId: Int private let orderId: Int
init(orderId: Int) { init(orderId: Int) {
...@@ -44,6 +45,17 @@ class YHHKVisaRenewalPaymentVC: YHBaseViewController { ...@@ -44,6 +45,17 @@ class YHHKVisaRenewalPaymentVC: YHBaseViewController {
setupUI() setupUI()
} }
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if !didShowGuideVC {
didShowGuideVC = true
let didShowGuide = YHVisaRenewalGuideVC.didShowGuide
if !didShowGuide {
showGuideVC()
}
}
}
} }
extension YHHKVisaRenewalPaymentVC { extension YHHKVisaRenewalPaymentVC {
...@@ -69,6 +81,17 @@ extension YHHKVisaRenewalPaymentVC { ...@@ -69,6 +81,17 @@ extension YHHKVisaRenewalPaymentVC {
tableView.tableHeaderView = UIView(frame: CGRect.init(x: 0, y: 0, width: KScreenWidth, height: kMargin)) tableView.tableHeaderView = UIView(frame: CGRect.init(x: 0, y: 0, width: KScreenWidth, height: kMargin))
tableView.tableFooterView = UIView(frame: CGRect.init(x: 0, y: 0, width: KScreenWidth, height: kMargin)) tableView.tableFooterView = UIView(frame: CGRect.init(x: 0, y: 0, width: KScreenWidth, height: kMargin))
} }
private func showGuideVC() {
let vc = YHVisaRenewalGuideVC()
let pc = YHBottomPresentationController(presentedViewController: vc, presenting: self)
pc.customRadius = 16.0
vc.transitioningDelegate = pc
vc.sureButtonEvent = { [weak vc] in
vc?.dismiss(animated: true)
}
present(vc, animated: true, completion: nil)
}
} }
extension YHHKVisaRenewalPaymentVC: UITableViewDelegate, UITableViewDataSource { extension YHHKVisaRenewalPaymentVC: UITableViewDelegate, UITableViewDataSource {
......
...@@ -7,8 +7,22 @@ ...@@ -7,8 +7,22 @@
// //
import UIKit import UIKit
import AttributedString
class YHVisaRenewalGuideVC: YHBaseViewController { class YHVisaRenewalGuideVC: YHBaseViewController {
static private let showCardGuideKey = "VisaRenewalGuideVCDidShow"
static var didShowGuide: Bool {
UserDefaults.standard.value(forKey: showCardGuideKey) as? Bool == true
}
enum TableRow {
case header
case paragraph(_ title: String, _ detail: String)
case indent(_ title: String, _ detail: String)
case tips(_ title: String, _ detail: ASAttributedString)
case remark(_ detail: String)
}
private lazy var tableView: UITableView = { private lazy var tableView: UITableView = {
let view = UITableView(frame: .zero, style: .plain) let view = UITableView(frame: .zero, style: .plain)
...@@ -19,7 +33,11 @@ class YHVisaRenewalGuideVC: YHBaseViewController { ...@@ -19,7 +33,11 @@ class YHVisaRenewalGuideVC: YHBaseViewController {
view.dataSource = self view.dataSource = self
view.delegate = self view.delegate = self
view.showsVerticalScrollIndicator = false view.showsVerticalScrollIndicator = false
view.register(YHHKRecordsHeaderCell.self, forCellReuseIdentifier: YHHKRecordsHeaderCell.cellReuseIdentifier) view.register(YHVisaRenewalGuideHeaderCell.self, forCellReuseIdentifier: YHVisaRenewalGuideHeaderCell.cellReuseIdentifier)
view.register(YHVisaRenewalGuideParagraphCell.self, forCellReuseIdentifier: YHVisaRenewalGuideParagraphCell.cellReuseIdentifier)
view.register(YHVisaRenewalGuideRemarkCell.self, forCellReuseIdentifier: YHVisaRenewalGuideRemarkCell.cellReuseIdentifier)
view.register(YHVisaRenewalGuideIndentCell.self, forCellReuseIdentifier: YHVisaRenewalGuideIndentCell.cellReuseIdentifier)
view.register(YHVisaRenewalGuideTipsCell.self, forCellReuseIdentifier: YHVisaRenewalGuideTipsCell.cellReuseIdentifier)
return view return view
}() }()
...@@ -32,10 +50,13 @@ class YHVisaRenewalGuideVC: YHBaseViewController { ...@@ -32,10 +50,13 @@ class YHVisaRenewalGuideVC: YHBaseViewController {
button.setTitle("我已知悉,确认", for: .highlighted) button.setTitle("我已知悉,确认", for: .highlighted)
button.setTitleColor( UIColor(hex:0xffffff), for: .normal) button.setTitleColor( UIColor(hex:0xffffff), for: .normal)
button.setTitleColor( UIColor(hex:0xffffff), for: .highlighted) button.setTitleColor( UIColor(hex:0xffffff), for: .highlighted)
button.setTitleColor( UIColor(hex:0xffffff), for: .disabled)
button.addTarget(self, action: #selector(clickSureButton), for: .touchUpInside) button.addTarget(self, action: #selector(clickSureButton), for: .touchUpInside)
button.layer.cornerRadius = kCornerRadius3 button.layer.cornerRadius = kCornerRadius3
button.clipsToBounds = true button.clipsToBounds = true
button.backgroundColor = .brandMainColor let isEnable = YHVisaRenewalGuideVC.didShowGuide
button.backgroundColor = isEnable ? .brandMainColor : UIColor(hex: 0xB7C0CC, alpha: 1.0)
button.isEnabled = isEnable
return button return button
}() }()
...@@ -45,9 +66,33 @@ class YHVisaRenewalGuideVC: YHBaseViewController { ...@@ -45,9 +66,33 @@ class YHVisaRenewalGuideVC: YHBaseViewController {
return view return view
}() }()
var sureButtonEvent: (() -> Void)?
private lazy var datas: [TableRow] = []
private var isStartTimer: Bool = false
private let maxCount = 5
private var timer: DispatchSourceTimer?
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
setupUI() setupUI()
setupDatas()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if !isStartTimer {
isStartTimer = true
let didShowGuide = YHVisaRenewalGuideVC.didShowGuide
if !didShowGuide {
setupTimer()
}
}
}
deinit {
cancelTimer()
} }
} }
...@@ -55,7 +100,7 @@ class YHVisaRenewalGuideVC: YHBaseViewController { ...@@ -55,7 +100,7 @@ class YHVisaRenewalGuideVC: YHBaseViewController {
extension YHVisaRenewalGuideVC { extension YHVisaRenewalGuideVC {
@objc private func clickSureButton() { @objc private func clickSureButton() {
// sureButtonEvent?()
} }
private func setupUI() { private func setupUI() {
...@@ -85,21 +130,111 @@ extension YHVisaRenewalGuideVC { ...@@ -85,21 +130,111 @@ extension YHVisaRenewalGuideVC {
make.top.equalToSuperview() make.top.equalToSuperview()
make.bottom.equalTo(bottomView.snp.top) make.bottom.equalTo(bottomView.snp.top)
} }
tableView.tableFooterView = UIView(frame: CGRect.init(x: 0, y: 0, width: KScreenWidth, height: kMargin)) tableView.tableFooterView = UIView(frame: CGRect.init(x: 0, y: 0, width: KScreenWidth, height: 82))
preferredContentSize = CGSize(width: KScreenWidth, height: KScreenHeight - k_Height_NavigationtBarAndStatuBar) preferredContentSize = CGSize(width: KScreenWidth, height: KScreenHeight - k_Height_NavigationtBarAndStatuBar)
} }
private func setupDatas() {
datas.append(.header)
datas.append(.paragraph("二、原签证未过期但已离境,需赴港缴费领取新签证", "携带港澳通行证逗留D签注(如是护照申请则为护照)、香港身份证;香港关请务必走香港居民通道"))
datas.append(.indent("内地关", "使用港澳通行证逗留D签注"))
datas.append(.indent("香港关", "已有香港身份证则使用香港身份证走香港居民通道;未满11岁无香港身份证,则使用对应旅行证件和电子签证走香港居民人工通道"))
datas.append(.paragraph("三、原签证已过期且已离境,需赴港缴费领取新签证", "携带港澳通行证旅游签注(如护照申请,则同时携带护照)、香港身份证;香港关也走访客通道"))
datas.append(.indent("内地关", "使用港澳通行证旅游签注"))
datas.append(.indent("香港关", "使用港澳通行证旅游签注(如护照申请则使用护照)走访客通道"))
datas.append(.remark("备注:如用中国护照申请,从内地赴港,在非需前往其他国家的情况下可能无法直接持护照过关,需提前办理港澳通行证旅游签注备用;建议联合其他国行程,香港作为中转,即可护照顺利入境"))
let firstAtt: ASAttributedString = .init(string: "1、信用卡(只接受VISA、万事达卡、银联卡及JCB),缴费灵,「转数快」或内地电子钱包(只接受支付宝、微信支付及云闪付App)缴付。付款成功后,申请人随即可自行下载或打印「电子签证」\n\n2、缴费过程中或需填写获批者的出生日期与旅行证件号码,请提前准备\n\n3、手机端电脑端都可缴费,建议使用电脑端(每位获批者都需单独缴费一次)", .font(UIFont.PFSC_R(ofSize: 13)), .foreground(UIColor.mainTextColor70), .paragraph(.lineHeightMultiple(1.07)))
datas.append(.tips("缴费注意事项:", firstAtt))
let secLine1a: ASAttributedString = .init(string: "1、涉及的申请人若已在港,并在赴港时使用正确证件,走正确通道才可以去缴费查看签证;未入境前一旦尝试缴费签证就会被锁;若刚入境香港,", .font(UIFont.PFSC_R(ofSize: 13)), .foreground(UIColor.mainTextColor70))
let secLine1b: ASAttributedString = .init(string: "至少2个小时后再进行缴费", .font(UIFont.PFSC_M(ofSize: 13)), .foreground(UIColor.brandMainColor))
let secLine1c: ASAttributedString = .init(string: ",避免海关还未识别到入境记录,导致签证被锁\n\n", .font(UIFont.PFSC_R(ofSize: 13)), .foreground(UIColor.mainTextColor70))
let secLine2a: ASAttributedString = .init(string: "2、签证过期后,再入境香港缴费只能以访客身份入境,会有签证被锁的风险。", .font(UIFont.PFSC_R(ofSize: 13)), .foreground(UIColor.mainTextColor70))
let secLine2b: ASAttributedString = .init(string: "建议尽量在工作日到港缴费", .font(UIFont.PFSC_M(ofSize: 13)), .foreground(UIColor.brandMainColor))
let secLine2c: ASAttributedString = .init(string: ",如遇签证被锁情况方便去入境处核实情况及申请重发,目前重发周期预计是3-6周,重发后需要再次来港缴费", .font(UIFont.PFSC_R(ofSize: 13)), .foreground(UIColor.mainTextColor70))
let secAtt: ASAttributedString = (secLine1a + secLine1b + secLine1c + secLine2a + secLine2b + secLine2c).add(attributes: .paragraph(.lineHeightMultiple(1.07)))
datas.append(.tips("风险提示:", secAtt))
tableView.reloadData()
}
/// 设置定时器
private func setupTimer() {
var countDown = maxCount + 1
timer = DispatchSource.makeTimerSource(queue: .main)
timer?.schedule(deadline: .now(), repeating: .seconds(1))
timer?.setEventHandler(handler: { [weak self] in
guard let self = self else {
return
}
DispatchQueue.main.async {
countDown -= 1
if countDown == 0 {
self.cancelTimer()
self.sureButton.isEnabled = true
self.sureButton.backgroundColor = .brandMainColor
UserDefaults.standard.set(true, forKey: YHVisaRenewalGuideVC.showCardGuideKey)
UserDefaults.standard.synchronize()
return
}
self.sureButton.isEnabled = false
self.sureButton.setTitle("请上滑看完指引后操作(\(countDown)s)", for: .disabled)
self.sureButton.backgroundColor = UIColor(hex: 0xB7C0CC, alpha: 1.0)
}
})
timer?.resume()
}
/// 取消定时器
private func cancelTimer() {
if timer != nil {
timer?.cancel()
timer = nil
}
}
} }
extension YHVisaRenewalGuideVC: UITableViewDelegate, UITableViewDataSource { extension YHVisaRenewalGuideVC: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int { func numberOfSections(in tableView: UITableView) -> Int {
return 0 return datas.count > 0 ? 1 : 0
} }
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 0 return datas.count
} }
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard datas.count > indexPath.row else {
return UITableViewCell()
}
let tableRow = datas[indexPath.row]
switch tableRow {
case .header:
if let cell = tableView.dequeueReusableCell(withIdentifier: YHVisaRenewalGuideHeaderCell.cellReuseIdentifier) as? YHVisaRenewalGuideHeaderCell {
return cell
}
case let .paragraph(title, detail):
if let cell = tableView.dequeueReusableCell(withIdentifier: YHVisaRenewalGuideParagraphCell.cellReuseIdentifier) as? YHVisaRenewalGuideParagraphCell {
cell.setupCellInfo(title: title, detail: detail)
return cell
}
case let .indent(title, detail):
if let cell = tableView.dequeueReusableCell(withIdentifier: YHVisaRenewalGuideIndentCell.cellReuseIdentifier) as? YHVisaRenewalGuideIndentCell {
cell.setupCellInfo(title: title, detail: detail)
return cell
}
case let .tips(title, detail):
if let cell = tableView.dequeueReusableCell(withIdentifier: YHVisaRenewalGuideTipsCell.cellReuseIdentifier) as? YHVisaRenewalGuideTipsCell {
cell.setupCellInfo(title: title, detail: detail)
return cell
}
case let .remark(detail):
if let cell = tableView.dequeueReusableCell(withIdentifier: YHVisaRenewalGuideRemarkCell.cellReuseIdentifier) as? YHVisaRenewalGuideRemarkCell {
cell.setupCellInfo(detail: detail)
return cell
}
}
return UITableViewCell() return UITableViewCell()
} }
......
...@@ -9,109 +9,93 @@ ...@@ -9,109 +9,93 @@
import UIKit import UIKit
class YHBottomPresentationController: UIPresentationController { class YHBottomPresentationController: UIPresentationController {
private var dimmingView: UIView?
/*
let vc = UIViewController()
let pc = YHBottomPresentationController(presentedViewController: vc, presenting: self)
pc.customRadius = 12.0
vc.transitioningDelegate = pc
vc.closeButtonClickClosure = { [weak vc] in
vc?.dismiss(animated: true)
}
pc.dimmingViewTapAction = {
vc.dismiss(animated: true, completion: nil)
}
present(vc, animated: true, completion: nil)
*/
// MARK: - Properties
@IBInspectable public var customRadius: CGFloat = 8.0
@IBInspectable public var blurEffectAlpha: CGFloat = 0.5
public var dimmingViewTapAction: (() -> Void)?
private var presentationWrappingView: UIView? private var presentationWrappingView: UIView?
public var customRadius: CGFloat = 8.0
private enum TransitionState { var blurEffectAlpha: CGFloat = 0.5
case presenting var dimmingViewTapAction: (() -> Void)?
case dismissing
}
private struct Constants {
static let animationDuration: TimeInterval = 0.35
static let shadowOpacity: Float = 0.44
static let shadowRadius: CGFloat = 13.0
static let shadowOffset: CGSize = CGSize(width: 0, height: -6)
}
// MARK: - Lazy Properties
private lazy var dimmingView: UIView = {
let view = UIView()
view.backgroundColor = UIColor.black.withAlphaComponent(blurEffectAlpha)
view.isOpaque = false
view.autoresizingMask = [.flexibleHeight, .flexibleWidth]
view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(dimmingViewTapped(_:))))
return view
}()
private lazy var visualEffectView: UIVisualEffectView = { private lazy var visualEffectView: UIVisualEffectView = {
let effect = UIBlurEffect(style: .dark) let effect = UIBlurEffect(style: .dark)
let view = UIVisualEffectView(effect: effect) let view = UIVisualEffectView(effect: effect)
view.alpha = blurEffectAlpha view.alpha = 0.5
return view return view
}() }()
// MARK: - Initialization
override init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController?) { override init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController?) {
super.init(presentedViewController: presentedViewController, presenting: presentingViewController) super.init(presentedViewController: presentedViewController, presenting: presentingViewController)
presentedViewController.modalPresentationStyle = .custom presentedViewController.modalPresentationStyle = .custom
} }
// MARK: - Overrides
override var presentedView: UIView? { override var presentedView: UIView? {
return presentationWrappingView return presentationWrappingView
} }
override func presentationTransitionWillBegin() { override func presentationTransitionWillBegin() {
guard let containerView = containerView else { return } let presentationWrapperView = UIView(frame: frameOfPresentedViewInContainerView)
presentationWrapperView.layer.shadowOpacity = 0.44
let presentationWrapperView = createPresentationWrapperView() presentationWrapperView.layer.shadowRadius = 13.0
presentationWrapperView.layer.shadowOffset = CGSize(width: 0, height: -6)
presentationWrappingView = presentationWrapperView presentationWrappingView = presentationWrapperView
let presentationRoundedCornerView = UIView(frame: presentationWrapperView.bounds.inset(by: UIEdgeInsets(top: 0, left: 0, bottom: -customRadius, right: 0)))
presentationRoundedCornerView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
presentationRoundedCornerView.layer.cornerRadius = customRadius
presentationRoundedCornerView.layer.masksToBounds = true
setupDimmingView(in: containerView) let presentedViewControllerWrapperView = UIView(frame: presentationRoundedCornerView.bounds.inset(by: UIEdgeInsets(top: 0, left: 0, bottom: customRadius, right: 0)))
presentedViewControllerWrapperView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
let presentedViewControllerView = super.presentedView
if let presentedViewControllerView = presentedViewControllerView {
presentedViewControllerView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
presentedViewControllerView.frame = presentedViewControllerWrapperView.bounds
presentedViewControllerWrapperView.addSubview(presentedViewControllerView)
}
presentationRoundedCornerView.addSubview(presentedViewControllerWrapperView)
presentationWrapperView.addSubview(presentationRoundedCornerView)
if let containerView = containerView {
let dimmingView = UIView(frame: containerView.bounds)
visualEffectView.frame = dimmingView.bounds
visualEffectView.alpha = blurEffectAlpha
dimmingView.addSubview(visualEffectView)
visualEffectView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
dimmingView.backgroundColor = UIColor.black.withAlphaComponent(blurEffectAlpha)
dimmingView.isOpaque = false
dimmingView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
dimmingView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(dimmingViewTapped(_:))))
self.dimmingView = dimmingView
containerView.addSubview(dimmingView)
let transitionCoordinator = presentingViewController.transitionCoordinator let transitionCoordinator = presentingViewController.transitionCoordinator
dimmingView.alpha = 0.0 dimmingView.alpha = 0.0
transitionCoordinator?.animate(alongsideTransition: { [weak self] _ in transitionCoordinator?.animate(alongsideTransition: { [weak self] _ in
self?.dimmingView.alpha = 1 self?.dimmingView?.alpha = 1
}, completion: nil) }, completion: nil)
} }
}
override func presentationTransitionDidEnd(_ completed: Bool) { override func presentationTransitionDidEnd(_ completed: Bool) {
if !completed { if !completed {
presentationWrappingView = nil presentationWrappingView = nil
dimmingView.removeFromSuperview() dimmingView = nil
} }
} }
override func dismissalTransitionWillBegin() { override func dismissalTransitionWillBegin() {
let transitionCoordinator = presentingViewController.transitionCoordinator let transitionCoordinator = presentingViewController.transitionCoordinator
transitionCoordinator?.animate(alongsideTransition: { [weak self] _ in transitionCoordinator?.animate(alongsideTransition: { [weak self] _ in
self?.dimmingView.alpha = 0 self?.dimmingView?.alpha = 0
}, completion: nil) }, completion: nil)
} }
override func dismissalTransitionDidEnd(_ completed: Bool) { override func dismissalTransitionDidEnd(_ completed: Bool) {
if completed { if completed {
presentationWrappingView = nil presentationWrappingView = nil
dimmingView.removeFromSuperview() dimmingView = nil
} }
} }
// MARK: Layout
override func preferredContentSizeDidChange(forChildContentContainer container: UIContentContainer) { override func preferredContentSizeDidChange(forChildContentContainer container: UIContentContainer) {
super.preferredContentSizeDidChange(forChildContentContainer: container) super.preferredContentSizeDidChange(forChildContentContainer: container)
if container === presentedViewController { if container === presentedViewController {
...@@ -120,17 +104,19 @@ class YHBottomPresentationController: UIPresentationController { ...@@ -120,17 +104,19 @@ class YHBottomPresentationController: UIPresentationController {
} }
override func size(forChildContentContainer container: UIContentContainer, withParentContainerSize parentSize: CGSize) -> CGSize { override func size(forChildContentContainer container: UIContentContainer, withParentContainerSize parentSize: CGSize) -> CGSize {
if container === presentedViewController { if container === presentedViewController, (container as? UIViewController) != nil {
return container.preferredContentSize return container.preferredContentSize
} } else {
return super.size(forChildContentContainer: container, withParentContainerSize: parentSize) return super.size(forChildContentContainer: container, withParentContainerSize: parentSize)
} }
}
override var frameOfPresentedViewInContainerView: CGRect { override var frameOfPresentedViewInContainerView: CGRect {
guard let containerView = containerView else { return .zero } guard let containerView = containerView else {
return CGRect.zero
}
let containerViewBounds = containerView.bounds let containerViewBounds = containerView.bounds
let presentedViewContentSize = size(forChildContentContainer: presentedViewController, withParentContainerSize: containerViewBounds.size) let presentedViewContentSize = size(forChildContentContainer: self.presentedViewController, withParentContainerSize: containerViewBounds.size)
var presentedViewControllerFrame = containerViewBounds var presentedViewControllerFrame = containerViewBounds
presentedViewControllerFrame.size.height = presentedViewContentSize.height presentedViewControllerFrame.size.height = presentedViewContentSize.height
...@@ -140,102 +126,87 @@ class YHBottomPresentationController: UIPresentationController { ...@@ -140,102 +126,87 @@ class YHBottomPresentationController: UIPresentationController {
override func containerViewWillLayoutSubviews() { override func containerViewWillLayoutSubviews() {
super.containerViewWillLayoutSubviews() super.containerViewWillLayoutSubviews()
dimmingView.frame = containerView?.bounds ?? .zero dimmingView?.frame = containerView?.bounds ?? CGRect.zero
presentationWrappingView?.frame = frameOfPresentedViewInContainerView presentationWrappingView?.frame = frameOfPresentedViewInContainerView
} }
// MARK: - Private Methods // MARK: Tap Gesture Recognizer
private func createPresentationWrapperView() -> UIView {
let wrapperView = UIView(frame: frameOfPresentedViewInContainerView)
wrapperView.layer.shadowOpacity = Constants.shadowOpacity
wrapperView.layer.shadowRadius = Constants.shadowRadius
wrapperView.layer.shadowOffset = Constants.shadowOffset
let roundedCornerView = createRoundedCornerView(in: wrapperView)
let presentedControllerWrapperView = createPresentedControllerWrapperView(in: roundedCornerView)
if let presentedView = super.presentedView {
presentedView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
presentedView.frame = presentedControllerWrapperView.bounds
presentedControllerWrapperView.addSubview(presentedView)
}
return wrapperView
}
private func createRoundedCornerView(in wrapperView: UIView) -> UIView {
let roundedCornerView = UIView(frame: wrapperView.bounds.inset(by: UIEdgeInsets(top: 0, left: 0, bottom: -customRadius, right: 0)))
roundedCornerView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
roundedCornerView.layer.cornerRadius = customRadius
roundedCornerView.layer.masksToBounds = true
wrapperView.addSubview(roundedCornerView)
return roundedCornerView
}
private func createPresentedControllerWrapperView(in roundedCornerView: UIView) -> UIView {
let wrapperView = UIView(frame: roundedCornerView.bounds.inset(by: UIEdgeInsets(top: 0, left: 0, bottom: customRadius, right: 0)))
wrapperView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
roundedCornerView.addSubview(wrapperView)
return wrapperView
}
private func setupDimmingView(in containerView: UIView) {
dimmingView.frame = containerView.bounds
visualEffectView.frame = dimmingView.bounds
dimmingView.addSubview(visualEffectView)
visualEffectView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
containerView.addSubview(dimmingView)
}
// MARK: - Actions
@objc private func dimmingViewTapped(_: UITapGestureRecognizer) { @objc func dimmingViewTapped(_: UITapGestureRecognizer) {
dimmingViewTapAction?() dimmingViewTapAction?()
} }
} }
// MARK: - UIViewControllerAnimatedTransitioning
extension YHBottomPresentationController: UIViewControllerAnimatedTransitioning { extension YHBottomPresentationController: UIViewControllerAnimatedTransitioning {
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return transitionContext?.isAnimated == true ? Constants.animationDuration : 0 return (transitionContext?.isAnimated ?? false) ? 0.35 : 0
} }
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let state: TransitionState = (transitionContext.viewController(forKey: .from) === presentingViewController) ? .presenting : .dismissing let fromViewController = transitionContext.viewController(forKey: .from)
guard let view = state == .presenting ? transitionContext.view(forKey: .to) : transitionContext.view(forKey: .from) else { return } let toViewController = transitionContext.viewController(forKey: .to)
let toView = transitionContext.view(forKey: .to)
let initialFrame = view.frame let fromView = transitionContext.view(forKey: .from)
let finalFrame = state == .presenting ? transitionContext.finalFrame(for: presentedViewController) : initialFrame.offsetBy(dx: 0, dy: initialFrame.height)
view.frame = state == .presenting ? initialFrame : finalFrame let containerView = transitionContext.containerView
let isPresenting = (fromViewController === presentingViewController)
var fromViewFinalFrame = CGRect.zero
var toViewInitialFrame = CGRect.zero
var toViewFinalFrame = CGRect.zero
let animator = UIViewPropertyAnimator(duration: Constants.animationDuration, curve: .easeInOut) { if let fromViewController = fromViewController {
view.frame = state == .presenting ? finalFrame : initialFrame _ = transitionContext.initialFrame(for: fromViewController)
fromViewFinalFrame = transitionContext.finalFrame(for: fromViewController)
} }
animator.addCompletion { _ in if let toViewController = toViewController {
transitionContext.completeTransition(!transitionContext.transitionWasCancelled) toViewInitialFrame = transitionContext.initialFrame(for: toViewController)
toViewFinalFrame = transitionContext.finalFrame(for: toViewController)
}
if let toView = toView {
containerView.addSubview(toView)
} }
animator.startAnimation() if isPresenting {
toViewInitialFrame.origin = CGPoint(x: containerView.bounds.minX, y: containerView.bounds.maxY)
toViewInitialFrame.size = toViewFinalFrame.size
if let toView = toView {
toView.frame = toViewInitialFrame
}
} else {
if let fromView = fromView {
fromViewFinalFrame = fromView.frame.offsetBy(dx: 0, dy: fromView.frame.size.height)
}
}
let transitionDuration = self.transitionDuration(using: transitionContext)
UIView.animate(withDuration: transitionDuration) {
if isPresenting {
if let toView = toView {
toView.frame = toViewFinalFrame
}
} else {
if let fromView = fromView {
fromView.frame = fromViewFinalFrame
}
}
} completion: { _ in
let wasCancelled = transitionContext.transitionWasCancelled
transitionContext.completeTransition(!wasCancelled)
}
} }
} }
// MARK: - UIViewControllerTransitioningDelegate
extension YHBottomPresentationController: UIViewControllerTransitioningDelegate { extension YHBottomPresentationController: UIViewControllerTransitioningDelegate {
func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? { func presentationController(forPresented presented: UIViewController, presenting _: UIViewController?, source _: UIViewController) -> UIPresentationController? {
assert(presentedViewController === presented, "You didn't initialize \(self) with the correct presentedViewController. Expected \(presented), got \(presentedViewController).") assert(presentedViewController === presented, "You didn't initialize \(self) with the correct presentedViewController. Expected \(presented), got \(presentedViewController).")
return self return self
} }
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { func animationController(forPresented _: UIViewController, presenting _: UIViewController, source _: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return self return self
} }
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { func animationController(forDismissed _: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return self return self
} }
} }
...@@ -144,10 +144,11 @@ extension YHHKVisaRenewalPaymentStepView { ...@@ -144,10 +144,11 @@ extension YHHKVisaRenewalPaymentStepView {
private func getStepLabel(_ title: String) -> UILabel { private func getStepLabel(_ title: String) -> UILabel {
let label = UILabel() let label = UILabel()
label.font = UIFont(name: "DIN Alternate Bold", size: 12) label.font = UIFont(name: "DIN Alternate Bold", size: 12)
label.textColor = .mainTextColor70 label.textColor = .brandMainColor
label.backgroundColor = UIColor(hex: 0xf4f6fa)
label.layer.cornerRadius = stepLabelHeight / 2.0 label.layer.cornerRadius = stepLabelHeight / 2.0
label.clipsToBounds = true label.clipsToBounds = true
label.layer.borderWidth = 1
label.layer.borderColor = UIColor.brandMainColor16.cgColor
label.text = title label.text = title
label.textAlignment = .center label.textAlignment = .center
return label return label
...@@ -156,13 +157,13 @@ extension YHHKVisaRenewalPaymentStepView { ...@@ -156,13 +157,13 @@ extension YHHKVisaRenewalPaymentStepView {
private func getStepNameLabel(_ title: String) -> UILabel { private func getStepNameLabel(_ title: String) -> UILabel {
let label = UILabel() let label = UILabel()
label.font = .PFSC_R(ofSize: 12) label.font = .PFSC_R(ofSize: 12)
label.textColor = .mainTextColor70 label.textColor = .mainTextColor
label.text = title label.text = title
return label return label
} }
private func getDashLineView() -> YHDashLineView { private func getDashLineView() -> YHDashLineView {
let view = YHDashLineView(strokeColor: UIColor(hex: 0x121A26, alpha: 0.12).cgColor, lineWidth: 1, lineDashPattern: [2, 2]) let view = YHDashLineView(strokeColor: UIColor.brandMainColor16.cgColor, lineWidth: 1, lineDashPattern: [2, 2])
return view return view
} }
} }
...@@ -12,49 +12,109 @@ import AttributedString ...@@ -12,49 +12,109 @@ import AttributedString
class YHVisaRenewalGuideHeaderCell: UITableViewCell { class YHVisaRenewalGuideHeaderCell: UITableViewCell {
static let cellReuseIdentifier = "YHVisaRenewalGuideHeaderCell" static let cellReuseIdentifier = "YHVisaRenewalGuideHeaderCell"
private lazy var infoTitleLabel: UILabel = { private lazy var infoTitleIcon: UIImageView = {
let label = UILabel() let view = UIImageView()
label.font = .PFSC_M(ofSize: 17) view.contentMode = .scaleAspectFit
label.textColor = UIColor(hexString: "#222222") view.image = UIImage(named: "resign_visa_guide_title")
return label return view
}() }()
private lazy var tipIcon: UIImageView = { private lazy var tipIcon: UIImageView = {
let view = UIImageView() let view = UIImageView()
view.image = UIImage(named: "right_arrow_black_20") view.image = UIImage(named: "resign_visa_guide_tips")
return view
}()
private lazy var bgIcon: UIImageView = {
let view = UIImageView()
view.image = UIImage(named: "resign_visa_guide_bg")
return view return view
}() }()
private lazy var tipTitleLabel: UILabel = { private lazy var tipTitleLabel: UILabel = {
let label = UILabel() let label = UILabel()
label.font = .PFSC_M(ofSize: 17) label.font = .PFSC_B(ofSize: 14)
label.textColor = UIColor(hexString: "#222222") label.textColor = .mainTextColor
label.text = "香港入境处政策"
return label
}()
private lazy var firstDotView: UIView = {
let view = UIView()
view.backgroundColor = .brandMainColor30
view.layer.cornerRadius = 3
view.clipsToBounds = true
return view
}()
private lazy var secondDotView: UIView = {
let view = UIView()
view.backgroundColor = .brandMainColor30
view.layer.cornerRadius = 3
view.clipsToBounds = true
return view
}()
private lazy var firstTipDetailLabel: UILabel = {
let label = UILabel()
label.font = .PFSC_R(ofSize: 13)
label.textColor = .mainTextColor70
label.text = "获批后,3个月内完成缴费,否则身份会失效"
label.numberOfLines = 0
return label return label
}() }()
private lazy var tipDetailLabel: UILabel = { private lazy var secondTipDetailLabel: UILabel = {
let label = UILabel() let label = UILabel()
label.font = .PFSC_M(ofSize: 17) label.font = .PFSC_R(ofSize: 13)
label.textColor = UIColor(hexString: "#222222") label.textColor = .mainTextColor70
label.text = "缴费领取电子签证时,涉及到的申请人应身在香港"
label.numberOfLines = 0
return label return label
}() }()
private lazy var subContainerView: YHBaseDynamicCornerRadiusView = { private lazy var subContainerView: YHBaseDynamicCornerRadiusView = {
let view = YHBaseDynamicCornerRadiusView(cornerRadius: 8, corner: .none) let view = YHBaseDynamicCornerRadiusView(cornerRadius: 6, corner: .allCorners)
view.backgroundColor = .white view.backgroundColor = UIColor(hexString: "#FFF5EB")
return view return view
}() }()
private lazy var warrnIcon: UIImageView = { private lazy var warnIcon: UIImageView = {
let view = UIImageView() let view = UIImageView()
view.image = UIImage(named: "right_arrow_black_20") view.image = UIImage(named: "resign_visa_guide_warn")
return view return view
}() }()
private lazy var warrnDetailLabel: UILabel = { private lazy var warnDetailLabel: UILabel = {
let label = UILabel()
label.font = .PFSC_R(ofSize: 13)
label.textColor = UIColor(hex: 0xFF8000)
label.text = "在港缴费领取电子签证时使用的入境证件,请务必和递交续签资料时入境香港使用的旅行证件保持一致"
label.numberOfLines = 0
return label
}()
private lazy var paragraphTitleLabel: UILabel = {
let label = UILabel() let label = UILabel()
label.font = .PFSC_M(ofSize: 17) label.font = .PFSC_B(ofSize: 16)
label.textColor = UIColor(hexString: "#222222") label.textColor = .mainTextColor
label.numberOfLines = 0
label.text = "一、递交续签申请后,未离境一直在港"
return label
}()
private lazy var paragraphDetailLabel: UILabel = {
let label = UILabel()
label.font = .PFSC_R(ofSize: 14)
label.textColor = .mainTextColor70
label.numberOfLines = 0
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineHeightMultiple = 1.07
let attributedText = NSAttributedString(
string: "一直未离港,获批后,可在港直接缴费并领取新电子签证",
attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle]
)
label.attributedText = attributedText
return label return label
}() }()
...@@ -67,33 +127,114 @@ class YHVisaRenewalGuideHeaderCell: UITableViewCell { ...@@ -67,33 +127,114 @@ class YHVisaRenewalGuideHeaderCell: UITableViewCell {
fatalError("init(coder:) has not been implemented") fatalError("init(coder:) has not been implemented")
} }
func setupCellInfo(title: String?, detail: String?) {
// infoTitleLabel.text = title
// infoDetailLabel.text = detail
}
func setupCellASAttributedInfo(title: String?, detail: ASAttributedString?, detailColor: UIColor = .mainTextColor50) {
// infoTitleLabel.text = title
// infoDetailLabel.textColor = detailColor
// infoDetailLabel.attributed.text = detail
}
} }
extension YHVisaRenewalGuideHeaderCell { extension YHVisaRenewalGuideHeaderCell {
private func setupUI() { private func setupUI() {
selectionStyle = .none selectionStyle = .none
backgroundColor = .clear contentView.addSubview(bgIcon)
contentView.addSubview(infoTitleIcon)
contentView.addSubview(tipIcon)
contentView.addSubview(tipTitleLabel)
contentView.addSubview(firstDotView)
contentView.addSubview(secondDotView)
contentView.addSubview(firstTipDetailLabel)
contentView.addSubview(secondTipDetailLabel)
contentView.addSubview(subContainerView) contentView.addSubview(subContainerView)
subContainerView.addSubview(warnIcon)
subContainerView.addSubview(warnDetailLabel)
contentView.addSubview(paragraphTitleLabel)
contentView.addSubview(paragraphDetailLabel)
// subContainerView.snp.makeConstraints { make in bgIcon.setContentHuggingPriority(.defaultLow, for: .vertical)
// make.edges.equalToSuperview()
// } infoTitleIcon.setContentHuggingPriority(.required, for: .vertical)
// tipTitleLabel.setContentHuggingPriority(.required, for: .vertical)
// bottomLineView.snp.makeConstraints { make in firstTipDetailLabel.setContentHuggingPriority(.required, for: .vertical)
// make.bottom.equalToSuperview() secondTipDetailLabel.setContentHuggingPriority(.required, for: .vertical)
// make.left.equalToSuperview().offset(18) subContainerView.setContentHuggingPriority(.required, for: .vertical)
// make.right.equalToSuperview().offset(-18) warnDetailLabel.setContentHuggingPriority(.required, for: .vertical)
// make.height.equalTo(0.5) paragraphTitleLabel.setContentHuggingPriority(.required, for: .vertical)
// } paragraphDetailLabel.setContentHuggingPriority(.required, for: .vertical)
bgIcon.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
infoTitleIcon.snp.makeConstraints { make in
make.top.equalToSuperview().offset(25)
make.left.equalToSuperview().offset(22)
make.height.equalTo(25)
make.width.equalTo(253)
}
tipIcon.snp.makeConstraints { make in
make.top.equalTo(infoTitleIcon.snp.bottom).offset(34)
make.left.equalToSuperview().offset(20)
make.height.equalTo(20)
make.width.equalTo(20)
}
tipTitleLabel.snp.makeConstraints { make in
make.left.equalTo(tipIcon.snp.right).offset(8)
make.centerY.equalTo(tipIcon)
}
firstDotView.snp.makeConstraints { make in
make.top.equalTo(tipIcon.snp.bottom).offset(19)
make.left.equalTo(tipIcon)
make.height.equalTo(6)
make.width.equalTo(6)
}
firstTipDetailLabel.snp.makeConstraints { make in
make.top.equalTo(tipIcon.snp.bottom).offset(12)
make.left.equalTo(firstDotView.snp.right).offset(6)
make.right.lessThanOrEqualToSuperview().offset(-20)
}
secondDotView.snp.makeConstraints { make in
make.top.equalTo(firstTipDetailLabel.snp.bottom).offset(19)
make.left.equalTo(tipIcon)
make.height.equalTo(6)
make.width.equalTo(6)
}
secondTipDetailLabel.snp.makeConstraints { make in
make.top.equalTo(firstTipDetailLabel.snp.bottom).offset(12)
make.left.equalTo(secondDotView.snp.right).offset(6)
make.right.lessThanOrEqualToSuperview().offset(-20)
}
subContainerView.snp.makeConstraints { make in
make.top.equalTo(secondTipDetailLabel.snp.bottom).offset(20)
make.left.equalTo(tipIcon)
make.right.equalToSuperview().offset(-20)
}
warnIcon.snp.makeConstraints { make in
make.left.equalToSuperview().offset(16)
make.top.equalToSuperview().offset(19)
make.width.height.equalTo(14)
}
warnDetailLabel.snp.makeConstraints { make in
make.left.equalTo(warnIcon.snp.right).offset(8)
make.right.equalToSuperview().offset(-16)
make.top.equalToSuperview().offset(16)
make.bottom.equalToSuperview().offset(-16)
}
paragraphTitleLabel.snp.makeConstraints { make in
make.top.equalTo(subContainerView.snp.bottom).offset(20)
make.left.equalTo(tipIcon)
make.right.lessThanOrEqualToSuperview().offset(-20)
}
paragraphDetailLabel.snp.makeConstraints { make in
make.top.equalTo(paragraphTitleLabel.snp.bottom).offset(12)
make.left.equalTo(tipIcon)
make.right.lessThanOrEqualToSuperview().offset(-20)
make.bottom.equalToSuperview()
}
} }
} }
//
// YHVisaRenewalGuideIndentCell.swift
// galaxy
//
// Created by alexzzw on 2024/10/10.
// Copyright © 2024 https://www.galaxy-immi.com. All rights reserved.
//
import UIKit
class YHVisaRenewalGuideIndentCell: UITableViewCell {
static let cellReuseIdentifier = "YHVisaRenewalGuideIndentCell"
private let infoTitleLabelHorizontalOffset: CGFloat = 5
private let infoTitleLabelToDetail: CGFloat = 4
private lazy var subContainerView: YHBaseDynamicCornerRadiusView = {
let view = YHBaseDynamicCornerRadiusView(cornerRadius: 2, corner: .allCorners)
view.backgroundColor = UIColor(hex: 0xF4F6FA)
return view
}()
private lazy var infoTitleLabel: UILabel = {
let label = UILabel()
label.textAlignment = .center
label.font = .PFSC_M(ofSize: 13)
label.textColor = .brandMainColor
return label
}()
private lazy var infoDetailLabel: UILabel = {
let label = UILabel()
label.font = .PFSC_R(ofSize: 13)
label.textColor = .mainTextColor70
label.numberOfLines = 0
return label
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupCellInfo(title: String, detail: String) {
infoTitleLabel.text = title
infoTitleLabel.sizeToFit()
subContainerView.sizeToFit()
let paragraphStyle = NSMutableParagraphStyle()
// 设置首行缩进量,单位为points
paragraphStyle.firstLineHeadIndent = infoTitleLabel.bounds.size.width + infoTitleLabelHorizontalOffset * 2 + infoTitleLabelToDetail
paragraphStyle.headIndent = 0
paragraphStyle.lineHeightMultiple = 1.07
let attributedText = NSAttributedString(
string: detail,
attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle]
)
infoDetailLabel.attributedText = attributedText
}
}
extension YHVisaRenewalGuideIndentCell {
private func setupUI() {
selectionStyle = .none
contentView.addSubview(subContainerView)
subContainerView.addSubview(infoTitleLabel)
contentView.addSubview(infoDetailLabel)
subContainerView.snp.makeConstraints { make in
make.top.equalToSuperview().offset(20)
make.left.equalToSuperview().offset(20)
}
infoTitleLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(infoTitleLabelHorizontalOffset)
make.right.equalToSuperview().offset(-infoTitleLabelHorizontalOffset)
make.top.bottom.equalToSuperview()
}
infoDetailLabel.snp.makeConstraints { make in
make.top.equalTo(subContainerView)
make.left.equalTo(subContainerView)
make.right.lessThanOrEqualToSuperview().offset(-20)
make.bottom.equalToSuperview()
}
}
}
//
// YHVisaRenewalGuideParagraphCell.swift
// galaxy
//
// Created by alexzzw on 2024/10/10.
// Copyright © 2024 https://www.galaxy-immi.com. All rights reserved.
//
import UIKit
class YHVisaRenewalGuideParagraphCell: UITableViewCell {
static let cellReuseIdentifier = "YHVisaRenewalGuideParagraphCell"
private lazy var infoTitleLabel: UILabel = {
let label = UILabel()
label.font = .PFSC_B(ofSize: 16)
label.textColor = .mainTextColor
label.numberOfLines = 0
return label
}()
private lazy var infoDetailLabel: UILabel = {
let label = UILabel()
label.font = .PFSC_R(ofSize: 14)
label.textColor = .mainTextColor70
label.numberOfLines = 0
return label
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupCellInfo(title: String, detail: String) {
infoTitleLabel.text = title
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineHeightMultiple = 1.07
let attributedText = NSAttributedString(
string: detail,
attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle]
)
infoDetailLabel.attributedText = attributedText
}
}
extension YHVisaRenewalGuideParagraphCell {
private func setupUI() {
selectionStyle = .none
contentView.addSubview(infoTitleLabel)
contentView.addSubview(infoDetailLabel)
infoTitleLabel.snp.makeConstraints { make in
make.top.equalToSuperview().offset(20)
make.left.equalToSuperview().offset(20)
make.right.lessThanOrEqualToSuperview().offset(-20)
}
infoDetailLabel.snp.makeConstraints { make in
make.top.equalTo(infoTitleLabel.snp.bottom).offset(20)
make.left.equalTo(infoTitleLabel)
make.right.lessThanOrEqualToSuperview().offset(-20)
make.bottom.equalToSuperview()
}
}
}
//
// YHVisaRenewalGuideRemarkCell.swift
// galaxy
//
// Created by alexzzw on 2024/10/10.
// Copyright © 2024 https://www.galaxy-immi.com. All rights reserved.
//
import UIKit
class YHVisaRenewalGuideRemarkCell: UITableViewCell {
static let cellReuseIdentifier = "YHVisaRenewalGuideRemarkCell"
private lazy var infoDetailLabel: UILabel = {
let label = UILabel()
label.font = .PFSC_R(ofSize: 14)
label.textColor = .mainTextColor70
label.numberOfLines = 0
return label
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupCellInfo(detail: String) {
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineHeightMultiple = 1.07
let attributedText = NSAttributedString(
string: detail,
attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle]
)
infoDetailLabel.attributedText = attributedText
}
}
extension YHVisaRenewalGuideRemarkCell {
private func setupUI() {
selectionStyle = .none
contentView.addSubview(infoDetailLabel)
infoDetailLabel.snp.makeConstraints { make in
make.top.equalToSuperview().offset(12)
make.left.equalToSuperview().offset(20)
make.right.lessThanOrEqualToSuperview().offset(-20)
make.bottom.equalToSuperview()
}
}
}
//
// YHVisaRenewalGuideTipsCell.swift
// galaxy
//
// Created by alexzzw on 2024/10/10.
// Copyright © 2024 https://www.galaxy-immi.com. All rights reserved.
//
import UIKit
import AttributedString
class YHVisaRenewalGuideTipsCell: UITableViewCell {
static let cellReuseIdentifier = "YHVisaRenewalGuideTipsCell"
private lazy var iconView: UIView = {
let view = UIView()
view.backgroundColor = .brandMainColor
return view
}()
private lazy var infoTitleLabel: UILabel = {
let label = UILabel()
label.font = .PFSC_B(ofSize: 14)
label.textColor = .mainTextColor
return label
}()
private lazy var infoDetailLabel: UILabel = {
let label = UILabel()
label.font = .PFSC_R(ofSize: 13)
label.textColor = .mainTextColor70
label.numberOfLines = 0
return label
}()
private lazy var subContainerView: YHBaseDynamicCornerRadiusView = {
let view = YHBaseDynamicCornerRadiusView(cornerRadius: 6, corner: .allCorners)
view.backgroundColor = .contentBkgColor
return view
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupCellInfo(title: String, detail: ASAttributedString) {
infoTitleLabel.text = title
infoDetailLabel.attributed.text = detail
}
}
extension YHVisaRenewalGuideTipsCell {
private func setupUI() {
selectionStyle = .none
contentView.addSubview(subContainerView)
subContainerView.addSubview(iconView)
subContainerView.addSubview(infoTitleLabel)
subContainerView.addSubview(infoDetailLabel)
subContainerView.setContentHuggingPriority(.defaultLow, for: .vertical)
subContainerView.snp.makeConstraints { make in
make.top.equalToSuperview().offset(20)
make.left.equalToSuperview().offset(20)
make.right.equalToSuperview().offset(-20)
make.bottom.equalToSuperview()
}
iconView.snp.makeConstraints { make in
make.top.equalToSuperview().offset(18)
make.left.equalToSuperview()
make.width.equalTo(4)
make.height.equalTo(14)
}
infoTitleLabel.snp.makeConstraints { make in
make.centerY.equalTo(iconView)
make.left.equalTo(iconView.snp.right).offset(12)
make.right.lessThanOrEqualToSuperview().offset(-16)
}
infoDetailLabel.snp.makeConstraints { make in
make.top.equalTo(infoTitleLabel.snp.bottom).offset(12)
make.left.equalTo(infoTitleLabel)
make.right.lessThanOrEqualToSuperview().offset(-16)
make.bottom.equalToSuperview().offset(-16)
}
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "resign_visa_guide_bg@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "resign_visa_guide_bg@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "resign_visa_guide_tips@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "resign_visa_guide_tips@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "resign_visa_guide_title@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "resign_visa_guide_title@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "resign_visa_guide_warn@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "resign_visa_guide_warn@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
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