From ea880d69ad02a590ce69112dc0a9f9dd976c6962 Mon Sep 17 00:00:00 2001 From: Fin Date: Fri, 10 Feb 2023 17:08:47 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=8E=A8=E9=80=81=E5=8A=A0?= =?UTF-8?q?=E5=AF=86=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Bark.xcodeproj/project.pbxproj | 22 +++ Bark/AppDelegate.swift | 5 +- .../blue_darken5.colorset/Contents.json | 38 ++++ Bark/en.lproj/Localizable.strings | 8 + Bark/zh-Hans.lproj/Localizable.strings | 8 + Common/BKColor.swift | 1 + Controller/CryptoSettingController.swift | 183 ++++++++++++++++++ Controller/CryptoSettingModel.swift | 31 +++ Controller/GroupFilterViewController.swift | 2 +- Podfile | 3 + Podfile.lock | 16 +- View/BKDropDownCell.swift | 48 +++++ View/BKDropDownCell.xib | 56 ++++++ View/BorderTextField.swift | 101 ++++++++++ View/DropBoxView.swift | 109 +++++++++++ View/GradientButton.swift | 62 ++++++ 16 files changed, 689 insertions(+), 4 deletions(-) create mode 100644 Bark/Assets.xcassets/Colors/blue_darken5.colorset/Contents.json create mode 100644 Controller/CryptoSettingController.swift create mode 100644 Controller/CryptoSettingModel.swift create mode 100644 View/BKDropDownCell.swift create mode 100644 View/BKDropDownCell.xib create mode 100644 View/BorderTextField.swift create mode 100644 View/DropBoxView.swift create mode 100644 View/GradientButton.swift diff --git a/Bark.xcodeproj/project.pbxproj b/Bark.xcodeproj/project.pbxproj index 8ff606a..cdbb704 100644 --- a/Bark.xcodeproj/project.pbxproj +++ b/Bark.xcodeproj/project.pbxproj @@ -14,8 +14,13 @@ 060481EE250F404500BC9799 /* SoundsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 060481ED250F404500BC9799 /* SoundsViewController.swift */; }; 060481F0250F51CA00BC9799 /* SoundCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 060481EF250F51CA00BC9799 /* SoundCell.swift */; }; 0604F7DF20620D4900B32F09 /* ServerManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0604F7DE20620D4900B32F09 /* ServerManager.swift */; }; + 0608F06E2994D115006B8029 /* BKDropDownCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0608F06D2994D115006B8029 /* BKDropDownCell.swift */; }; + 0608F0722994D269006B8029 /* BKDropDownCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0608F0712994D269006B8029 /* BKDropDownCell.xib */; }; 06172FDA27F6DAEF002333A4 /* ServerListTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06172FD927F6DAEF002333A4 /* ServerListTableViewCell.swift */; }; 06172FDC27F6DB06002333A4 /* ServerListTableViewCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06172FDB27F6DB06002333A4 /* ServerListTableViewCellViewModel.swift */; }; + 061894C529962EB900E001C2 /* GradientButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 061894C429962EB900E001C2 /* GradientButton.swift */; }; + 0627DABB298B6EA2002F3F69 /* DropBoxView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0627DABA298B6EA2002F3F69 /* DropBoxView.swift */; }; + 0627DABD2990D615002F3F69 /* BorderTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0627DABC2990D615002F3F69 /* BorderTextField.swift */; }; 062B98C3251B2762004562E7 /* BKButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 062B98C2251B2762004562E7 /* BKButton.swift */; }; 062B98C8251B27AE004562E7 /* UINavigationItem+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 062B98C7251B27AE004562E7 /* UINavigationItem+Extension.swift */; }; 0632050F250B6DD4001561EC /* gotosleep.caf in Resources */ = {isa = PBXBuildFile; fileRef = 063204F0250B6DD1001561EC /* gotosleep.caf */; }; @@ -182,8 +187,13 @@ 060481ED250F404500BC9799 /* SoundsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SoundsViewController.swift; sourceTree = ""; }; 060481EF250F51CA00BC9799 /* SoundCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SoundCell.swift; sourceTree = ""; }; 0604F7DE20620D4900B32F09 /* ServerManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerManager.swift; sourceTree = ""; }; + 0608F06D2994D115006B8029 /* BKDropDownCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BKDropDownCell.swift; sourceTree = ""; }; + 0608F0712994D269006B8029 /* BKDropDownCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = BKDropDownCell.xib; sourceTree = ""; }; 06172FD927F6DAEF002333A4 /* ServerListTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerListTableViewCell.swift; sourceTree = ""; }; 06172FDB27F6DB06002333A4 /* ServerListTableViewCellViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerListTableViewCellViewModel.swift; sourceTree = ""; }; + 061894C429962EB900E001C2 /* GradientButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradientButton.swift; sourceTree = ""; }; + 0627DABA298B6EA2002F3F69 /* DropBoxView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DropBoxView.swift; sourceTree = ""; }; + 0627DABC2990D615002F3F69 /* BorderTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BorderTextField.swift; sourceTree = ""; }; 062B98C2251B2762004562E7 /* BKButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BKButton.swift; sourceTree = ""; }; 062B98C7251B27AE004562E7 /* UINavigationItem+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UINavigationItem+Extension.swift"; sourceTree = ""; }; 063204F0250B6DD1001561EC /* gotosleep.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = gotosleep.caf; sourceTree = ""; }; @@ -405,6 +415,11 @@ 0642B55B27EB149900453D91 /* MutableTextCellViewModel.swift */, 06172FD927F6DAEF002333A4 /* ServerListTableViewCell.swift */, 06172FDB27F6DB06002333A4 /* ServerListTableViewCellViewModel.swift */, + 0627DABA298B6EA2002F3F69 /* DropBoxView.swift */, + 0627DABC2990D615002F3F69 /* BorderTextField.swift */, + 0608F06D2994D115006B8029 /* BKDropDownCell.swift */, + 0608F0712994D269006B8029 /* BKDropDownCell.xib */, + 061894C429962EB900E001C2 /* GradientButton.swift */, ); path = View; sourceTree = ""; @@ -801,6 +816,7 @@ 0661A54D204FDA4100965E4E /* LaunchScreen.storyboard in Resources */, 0632051E250B6DD4001561EC /* choo.caf in Resources */, 06320516250B6DD4001561EC /* calypso.caf in Resources */, + 0608F0722994D269006B8029 /* BKDropDownCell.xib in Resources */, 0632052D250B6DD4001561EC /* newsflash.caf in Resources */, 06320514250B6DD4001561EC /* sherwoodforest.caf in Resources */, 0632051A250B6DD4001561EC /* fanfare.caf in Resources */, @@ -864,6 +880,7 @@ ); inputPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Bark/Pods-Bark-resources.sh", + "${PODS_ROOT}/DropDown/DropDown/resources/DropDownCell.xib", "${PODS_ROOT}/MJRefresh/MJRefresh/MJRefresh.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/Material/com.cosmicmind.material.icons.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/Material/com.cosmicmind.material.fonts.bundle", @@ -872,6 +889,7 @@ ); name = "[CP] Copy Pods Resources"; outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/DropDownCell.nib", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/MJRefresh.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/com.cosmicmind.material.icons.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/com.cosmicmind.material.fonts.bundle", @@ -955,8 +973,10 @@ 06BBB896256518760076F63E /* NewServerViewModel.swift in Sources */, 06BBB8C92567B6730076F63E /* Operators.swift in Sources */, 0603706920E1F89500F4CA05 /* PreviewCardCell.swift in Sources */, + 0627DABB298B6EA2002F3F69 /* DropBoxView.swift in Sources */, 06AE311C266F54A500B39FBB /* GroupTableViewCell.swift in Sources */, 0672CB06256903F700570C9D /* MessageListViewModel.swift in Sources */, + 0627DABD2990D615002F3F69 /* BorderTextField.swift in Sources */, 0633E80A256A091B00ED0680 /* MJRefresh+Rx.swift in Sources */, 0637FA8C20E0D7A700E80174 /* BaseViewController.swift in Sources */, 0642B55C27EB149900453D91 /* MutableTextCellViewModel.swift in Sources */, @@ -972,6 +992,7 @@ 065BE4502563D939002A8CA4 /* SoundCellViewModel.swift in Sources */, 06B1158F247BB1FB006D91FB /* Message.swift in Sources */, 06172FDA27F6DAEF002333A4 /* ServerListTableViewCell.swift in Sources */, + 061894C529962EB900E001C2 /* GradientButton.swift in Sources */, 06C595362481160F006B98F3 /* BKLabel.swift in Sources */, 0637FA7820E0926D00E80174 /* BarkTargetType.swift in Sources */, 064CABA6256BE9510018155C /* PreviewModel.swift in Sources */, @@ -997,6 +1018,7 @@ 062B98C3251B2762004562E7 /* BKButton.swift in Sources */, 06885EB6247FB9880004A303 /* MessageSettingsViewController.swift in Sources */, 06F11E7727D9D5FB00F00298 /* QRScannerViewController.swift in Sources */, + 0608F06E2994D115006B8029 /* BKDropDownCell.swift in Sources */, 06C5952D2480E3F8006B98F3 /* LabelCell.swift in Sources */, 068EC15827ED99C900D5D11E /* ServerListViewController.swift in Sources */, 0637FA7C20E0930E00E80174 /* BarkApi.swift in Sources */, diff --git a/Bark/AppDelegate.swift b/Bark/AppDelegate.swift index d4711ea..faf9e93 100644 --- a/Bark/AppDelegate.swift +++ b/Bark/AppDelegate.swift @@ -8,6 +8,7 @@ import CloudKit import IceCream +import IQKeyboardManagerSwift import Material import RealmSwift import UIKit @@ -50,6 +51,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD // 必须在应用一开始就配置,否则应用可能提前在配置之前试用了 Realm() ,则会创建两个独立数据库。 setupRealm() + IQKeyboardManager.shared.enable = true + self.window = UIWindow(frame: UIScreen.main.bounds) let tabBarController = StateStorageTabBarController() tabBarController.tabBar.tintColor = BKColor.grey.darken4 @@ -207,7 +210,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD func applicationWillEnterForeground(_ application: UIApplication) { ServerManager.shared.syncAllServers() - + // 设置 -1 可以清除应用角标,但不清除通知中心的推送 // 设置 0 会将通知中心的所有推送一起清空掉 UIApplication.shared.applicationIconBadgeNumber = -1 diff --git a/Bark/Assets.xcassets/Colors/blue_darken5.colorset/Contents.json b/Bark/Assets.xcassets/Colors/blue_darken5.colorset/Contents.json new file mode 100644 index 0000000..c309b0d --- /dev/null +++ b/Bark/Assets.xcassets/Colors/blue_darken5.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "216", + "green" : "46", + "red" : "34" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xD8", + "green" : "0x2E", + "red" : "0x22" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Bark/en.lproj/Localizable.strings b/Bark/en.lproj/Localizable.strings index 59d25c5..ad4521b 100644 --- a/Bark/en.lproj/Localizable.strings +++ b/Bark/en.lproj/Localizable.strings @@ -123,3 +123,11 @@ export = "Export"; import = "Import"; exportOrImport = "Export and import messages"; items = "messages"; + +enterKey = "Please enter %s-bit Key"; +enterIv = "Please enter %s-bit Iv"; +encryptionSettings = "Encryption Settings"; +algorithm = "Algorithm"; +mode = "Mode"; +copyExample = "Copy Send Script Example"; +preview = "Preview"; diff --git a/Bark/zh-Hans.lproj/Localizable.strings b/Bark/zh-Hans.lproj/Localizable.strings index 8216906..78f537b 100644 --- a/Bark/zh-Hans.lproj/Localizable.strings +++ b/Bark/zh-Hans.lproj/Localizable.strings @@ -126,3 +126,11 @@ export = "导出"; import = "导入"; exportOrImport = "导出或导入消息列表"; items = "条消息"; + +enterKey = "请输入%s位Key"; +enterIv = "请输入16位Iv"; +encryptionSettings = "加密设置"; +algorithm = "算法"; +mode = "模式"; +copyExample = "复制发送脚本示例"; +preview = "预览"; diff --git a/Common/BKColor.swift b/Common/BKColor.swift index 1c5cbea..5c927fc 100644 --- a/Common/BKColor.swift +++ b/Common/BKColor.swift @@ -25,6 +25,7 @@ class BKColor: NSObject { enum blue { public static let base = UIColor(named: "blue_base")! public static let darken1 = UIColor(named: "blue_darken1")! + public static let darken5 = UIColor(named: "blue_darken5")! } enum lightBlue { diff --git a/Controller/CryptoSettingController.swift b/Controller/CryptoSettingController.swift new file mode 100644 index 0000000..8843c17 --- /dev/null +++ b/Controller/CryptoSettingController.swift @@ -0,0 +1,183 @@ +// +// CryptoSettingController.swift +// Bark +// +// Created by huangfeng on 2022/11/10. +// Copyright © 2022 Fin. All rights reserved. +// + +import UIKit + +class CryptoSettingController: BaseViewController { + let algorithmFeild = DropBoxView(values: ["AES128", "AES192", "AES256"]) + let modeFeild = DropBoxView(values: ["CBC", "ECB", "GCM"]) + let paddingField = DropBoxView(values: ["pkcs7"]) + + let keyTextField: BorderTextField = { + let textField = BorderTextField(title: "Key") + textField.font = UIFont.systemFont(ofSize: 14) + textField.placeholder = NSLocalizedString("enterKey") + return textField + }() + + let ivTextField: BorderTextField = { + let textField = BorderTextField(title: "IV") + textField.font = UIFont.systemFont(ofSize: 14) + textField.placeholder = NSLocalizedString("enterIv") + return textField + }() + + let previewLabel: UILabel = { + let label = UILabel() + label.font = UIFont.systemFont(ofSize: 12) + label.textColor = BKColor.grey.darken4 + label.text = "\(NSLocalizedString("preview")): \"helloworld\" -> \"DASGKJLSAJKGH==\"" + return label + }() + + let doneButton: BKButton = { + let btn = BKButton() + btn.setTitle(NSLocalizedString("done"), for: .normal) + btn.setTitleColor(BKColor.lightBlue.darken3, for: .normal) + btn.frame = CGRect(x: 0, y: 0, width: 40, height: 40) + btn.fontSize = 14 + return btn + }() + + let copyButton: UIButton = { + let btn = GradientButton() + btn.setTitle(NSLocalizedString("copyExample"), for: .normal) + btn.setTitleColor(UIColor.white, for: .normal) + btn.titleLabel?.font = UIFont.systemFont(ofSize: 14, weight: .medium) + btn.layer.cornerRadius = 8 + btn.clipsToBounds = true + btn.applyGradient( + withColours: [ + UIColor(r255: 36, g255: 51, b255: 236), + UIColor(r255: 70, g255: 44, b255: 233), + ], + gradientOrientation: .horizontal) + return btn + }() + + let scrollView = UIScrollView() + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + } + + override func makeUI() { + self.title = NSLocalizedString("encryptionSettings") + self.navigationItem.setRightBarButtonItem(item: UIBarButtonItem(customView: doneButton)) + + self.view.addSubview(scrollView) + scrollView.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + + func getTitleLabel(title: String) -> UILabel { + let label = UILabel() + label.font = UIFont.systemFont(ofSize: 14) + label.textColor = BKColor.grey.darken4 + label.text = title + return label + } + + let algorithmLabel = getTitleLabel(title: NSLocalizedString("algorithm")) + let modeLabel = getTitleLabel(title: NSLocalizedString("mode")) + let paddingLabel = getTitleLabel(title: "Padding") + let keyLabel = getTitleLabel(title: "Key") + let ivLabel = getTitleLabel(title: "Iv") + + self.scrollView.addSubview(algorithmLabel) + self.scrollView.addSubview(algorithmFeild) + + self.scrollView.addSubview(modeLabel) + self.scrollView.addSubview(modeFeild) + + self.scrollView.addSubview(paddingLabel) + self.scrollView.addSubview(paddingField) + + self.scrollView.addSubview(keyLabel) + self.scrollView.addSubview(keyTextField) + + self.scrollView.addSubview(ivLabel) + self.scrollView.addSubview(ivTextField) + + self.scrollView.addSubview(previewLabel) + self.scrollView.addSubview(copyButton) + + self.view.backgroundColor = UIColor.white + + algorithmLabel.snp.makeConstraints { make in + make.top.equalTo(24) + make.left.equalTo(24) + } + algorithmFeild.snp.makeConstraints { make in + make.top.equalTo(algorithmLabel.snp.bottom).offset(5) + make.left.equalTo(20) + make.right.equalTo(-20) + make.height.equalTo(45) + make.width.equalToSuperview().offset(-40) + } + + modeLabel.snp.makeConstraints { make in + make.top.equalTo(algorithmFeild.snp.bottom).offset(20) + make.left.equalTo(algorithmLabel) + } + modeFeild.snp.makeConstraints { make in + make.left.right.height.equalTo(algorithmFeild) + make.top.equalTo(modeLabel.snp.bottom).offset(5) + } + + paddingLabel.snp.makeConstraints { make in + make.top.equalTo(modeFeild.snp.bottom).offset(20) + make.left.equalTo(algorithmLabel) + } + paddingField.snp.makeConstraints { make in + make.left.right.height.equalTo(modeFeild) + make.top.equalTo(paddingLabel.snp.bottom).offset(5) + } + + keyLabel.snp.makeConstraints { make in + make.top.equalTo(paddingField.snp.bottom).offset(20) + make.left.equalTo(algorithmLabel) + } + keyTextField.snp.makeConstraints { make in + make.left.right.height.equalTo(paddingField) + make.top.equalTo(keyLabel.snp.bottom).offset(5) + } + + ivLabel.snp.makeConstraints { make in + make.top.equalTo(keyTextField.snp.bottom).offset(20) + make.left.equalTo(algorithmLabel) + } + ivTextField.snp.makeConstraints { make in + make.left.right.height.equalTo(keyTextField) + make.top.equalTo(ivLabel.snp.bottom).offset(5) + } + + previewLabel.snp.makeConstraints { make in + make.left.equalTo(ivLabel) + make.top.equalTo(ivTextField.snp.bottom).offset(20) + } + + copyButton.snp.makeConstraints { make in + make.left.equalTo(ivTextField) + make.right.equalTo(ivTextField) + make.height.equalTo(42) + make.top.equalTo(previewLabel.snp.bottom).offset(10) + make.bottom.equalToSuperview().offset(-20) + } + + self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(resign))) + } + + @objc func resign() { + self.view.endEditing(true) + } + + override func viewDidLoad() { + super.viewDidLoad() + self.view.backgroundColor = BKColor.white + } +} diff --git a/Controller/CryptoSettingModel.swift b/Controller/CryptoSettingModel.swift new file mode 100644 index 0000000..485cead --- /dev/null +++ b/Controller/CryptoSettingModel.swift @@ -0,0 +1,31 @@ +// +// CryptoSettingModel.swift +// Bark +// +// Created by huangfeng on 2022/11/10. +// Copyright © 2022 Fin. All rights reserved. +// + +import CryptoSwift +import Foundation +class CryptoSettingModel: ViewModel, ViewModelType { + struct Input {} + + struct Output {} + + func transform(input: Input) -> Output { + return Output() + } + + override init() { + super.init() + + do { + let aes = try AES(key: "ABCDEFGHIJKLMNOP", iv: "1234567890123456") // aes128 + let ciphertext = try aes.encrypt(Array("hello,world".utf8)) + print("tttt \(ciphertext.toBase64())") + } catch { + print("tttt \(error.rawString())") + } + } +} diff --git a/Controller/GroupFilterViewController.swift b/Controller/GroupFilterViewController.swift index 7306103..977264f 100644 --- a/Controller/GroupFilterViewController.swift +++ b/Controller/GroupFilterViewController.swift @@ -18,7 +18,7 @@ class GroupFilterViewController: BaseViewController { let doneButton: BKButton = { let btn = BKButton() btn.setTitle(NSLocalizedString("done"), for: .normal) - btn.setTitleColor(Color.lightBlue.darken3, for: .normal) + btn.setTitleColor(BKColor.lightBlue.darken3, for: .normal) btn.frame = CGRect(x: 0, y: 0, width: 40, height: 40) btn.fontSize = 14 return btn diff --git a/Podfile b/Podfile index 32c8dcf..1d7c9b9 100644 --- a/Podfile +++ b/Podfile @@ -15,6 +15,8 @@ def pods pod 'DeviceKit' pod 'DefaultsKit', :git => 'https://github.com/nmdias/DefaultsKit' pod 'IceCream' + pod 'CryptoSwift' + pod 'IQKeyboardManagerSwift' pod 'RxSwift' pod 'RxCocoa' @@ -25,6 +27,7 @@ def pods pod 'MJRefresh' pod 'Kingfisher' pod 'MercariQRScanner', :git => 'https://github.com/Finb/QRScanner' + pod 'DropDown' end target 'Bark' do diff --git a/Podfile.lock b/Podfile.lock index 960d3c4..7bbf96e 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,11 +1,14 @@ PODS: - Alamofire (5.4.4) + - CryptoSwift (1.6.0) - DefaultsKit (0.2.0) - DeviceKit (4.5.0) - Differentiator (5.0.0) + - DropDown (2.3.13) - FDFullscreenPopGesture (1.1) - IceCream (2.0.4): - RealmSwift (< 10.8.0) + - IQKeyboardManagerSwift (6.5.10) - Kingfisher (6.3.1) - KVOController (1.2.0) - Material (3.1.8): @@ -48,10 +51,13 @@ PODS: - SwiftyJSON (5.0.1) DEPENDENCIES: + - CryptoSwift - DefaultsKit (from `https://github.com/nmdias/DefaultsKit`) - DeviceKit + - DropDown - FDFullscreenPopGesture - IceCream + - IQKeyboardManagerSwift - Kingfisher - KVOController - Material @@ -71,10 +77,13 @@ DEPENDENCIES: SPEC REPOS: trunk: - Alamofire + - CryptoSwift - DeviceKit - Differentiator + - DropDown - FDFullscreenPopGesture - IceCream + - IQKeyboardManagerSwift - Kingfisher - KVOController - Material @@ -110,11 +119,14 @@ CHECKOUT OPTIONS: SPEC CHECKSUMS: Alamofire: f3b09a368f1582ab751b3fff5460276e0d2cf5c9 + CryptoSwift: 562f8eceb40e80796fffc668b0cad9313284cfa6 DefaultsKit: 6c767941b2c3fe34c4d70e300e6c3b80c94964dd DeviceKit: b68cded46afdaefc5d2253d631d441ba7049a7fe Differentiator: e8497ceab83c1b10ca233716d547b9af21b9344d + DropDown: 8a2116376c1981888557f72ec2ffc9a5e0e456ec FDFullscreenPopGesture: a8a620179e3d9c40e8e00256dcee1c1a27c6d0f0 IceCream: 717d516a1c634eba8eaa8ce7d3d7bc5f7e40c2fa + IQKeyboardManagerSwift: 52962c76ab33532f15ad9f3ff4e5715eda5335bb Kingfisher: 016c8b653a35add51dd34a3aba36b580041acc74 KVOController: d72ace34afea42468329623b3379ab3cd1d286b6 Material: a2a3f400a3b549d53ef89e56c58c4535b29db387 @@ -135,6 +147,6 @@ SPEC CHECKSUMS: SVProgressHUD: 1428aafac632c1f86f62aa4243ec12008d7a51d6 SwiftyJSON: 2f33a42c6fbc52764d96f13368585094bfd8aa5e -PODFILE CHECKSUM: f2443e42f5062c17de4e7a770482b083d2659182 +PODFILE CHECKSUM: a6d53e3d3f1c8c892f61c29cc990d7b70691d966 -COCOAPODS: 1.11.2 +COCOAPODS: 1.11.3 diff --git a/View/BKDropDownCell.swift b/View/BKDropDownCell.swift new file mode 100644 index 0000000..c2410c7 --- /dev/null +++ b/View/BKDropDownCell.swift @@ -0,0 +1,48 @@ +// +// BKDropDownCellTableViewCell.swift +// Bark +// +// Created by huangfeng on 2023/2/9. +// Copyright © 2023 Fin. All rights reserved. +// + +import DropDown +import UIKit + +class BKDropDownCell: DropDownCell { + + @IBOutlet var selectBackgroundView: UIView! + + override func awakeFromNib() { + super.awakeFromNib() + self.backgroundColor = BKColor.white + self.selectBackgroundView.layer.cornerRadius = 10 + self.selectBackgroundView.clipsToBounds = true + } + + override func setSelected(_ selected: Bool, animated: Bool) { + + let executeSelection: () -> Void = { [weak self] in + guard let `self` = self else { return } + + let selectedBackgroundColor = BKColor.grey.lighten5 + if selected { + self.selectBackgroundView.backgroundColor = selectedBackgroundColor + self.optionLabel.textColor = BKColor.grey.darken4 + } else { + self.selectBackgroundView.backgroundColor = .clear + self.optionLabel.textColor = BKColor.grey.darken3 + } + } + + if animated { + UIView.animate(withDuration: 0.3, animations: { + executeSelection() + }) + } else { + executeSelection() + } + + accessibilityTraits = selected ? .selected : .none + } +} diff --git a/View/BKDropDownCell.xib b/View/BKDropDownCell.xib new file mode 100644 index 0000000..166a264 --- /dev/null +++ b/View/BKDropDownCell.xib @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/View/BorderTextField.swift b/View/BorderTextField.swift new file mode 100644 index 0000000..3b408e3 --- /dev/null +++ b/View/BorderTextField.swift @@ -0,0 +1,101 @@ +// +// BorderTextField.swift +// Bark +// +// Created by huangfeng on 2023/2/6. +// Copyright © 2023 Fin. All rights reserved. +// + +import UIKit + +class InsetTextField: UITextField { + var insets = UIEdgeInsets.zero + + override func textRect(forBounds bounds: CGRect) -> CGRect { + let bounds = super.textRect(forBounds: bounds) + return bounds.inset(by: insets) + } + + override func editingRect(forBounds bounds: CGRect) -> CGRect { + let bounds = super.textRect(forBounds: bounds) + return bounds.inset(by: insets) + } + + override func placeholderRect(forBounds bounds: CGRect) -> CGRect { + let bounds = super.textRect(forBounds: bounds) + return bounds.inset(by: insets) + } +} + +class BorderTextField: InsetTextField { + var isSelecting: Bool = true { + didSet { + UIView.animate(withDuration: 0.3) { + if self.isSelecting { + self.backgroundView.borderColor = BKColor.blue.darken5 + self.backgroundView.shadowColor = BKColor.blue.darken5 + self.backgroundView.layer.shadowOpacity = 0.3 + } + else { + self.backgroundView.borderColor = BKColor.grey.lighten1 + self.backgroundView.shadowColor = BKColor.grey.lighten1 + self.backgroundView.layer.shadowOpacity = 0 + } + } + } + } + + let backgroundView: UIView = { + let view = UIView() + view.backgroundColor = BKColor.white + view.isUserInteractionEnabled = false + view.cornerRadiusPreset = .cornerRadius3 + view.shadowColor = BKColor.grey.lighten1 + view.layer.shadowOffset = CGSize(width: 0, height: 0) + view.layer.shadowRadius = 2 + view.layer.shadowOpacity = 0 + view.borderColor = BKColor.grey.lighten1 + view.borderWidthPreset = .border2 + + return view + }() + + init(title: String? = nil) { + super.init(frame: CGRect.zero) + self.insets = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16) + + self.textColor = BKColor.grey.darken3 + self.font = UIFont.systemFont(ofSize: 14) + self.textAlignment = .left + + self.insertSubview(backgroundView, at: 0) + backgroundView.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + + self.delegate = self + } + override var placeholder: String? { + didSet{ + self.attributedPlaceholder = NSAttributedString(string: placeholder ?? "" , attributes: [ + .font: self.font ?? UIFont.systemFont(ofSize: 14), + .foregroundColor: BKColor.grey.darken1 + ]) + } + } + + + @available(*, unavailable) + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} + +extension BorderTextField: UITextFieldDelegate { + func textFieldDidBeginEditing(_ textField: UITextField) { + self.isSelecting = true + } + func textFieldDidEndEditing(_ textField: UITextField) { + self.isSelecting = false + } +} diff --git a/View/DropBoxView.swift b/View/DropBoxView.swift new file mode 100644 index 0000000..17f363c --- /dev/null +++ b/View/DropBoxView.swift @@ -0,0 +1,109 @@ +// +// DropBoxView.swift +// Bark +// +// Created by huangfeng on 2023/2/2. +// Copyright © 2023 Fin. All rights reserved. +// + +import DropDown +import UIKit + +class DropBoxView: UIView { + + let valueLabel: UILabel = { + let label = UILabel() + label.font = UIFont.systemFont(ofSize: 14) + label.textColor = BKColor.grey.darken3 + return label + }() + + let dropIconView: UIImageView = { + let imageView = UIImageView() + imageView.image = UIImage(named: "baseline_keyboard_arrow_down_black_24pt")?.withRenderingMode(.alwaysTemplate) + imageView.tintColor = BKColor.grey.lighten1 + return imageView + }() + + var isSelecting: Bool = true { + didSet { + UIView.animate(withDuration: 0.3) { + if self.isSelecting { + self.borderColor = BKColor.blue.darken5 + self.shadowColor = BKColor.blue.darken5 + self.layer.shadowOpacity = 0.3 + } + else { + self.borderColor = BKColor.grey.lighten1 + self.shadowColor = BKColor.grey.lighten1 + self.layer.shadowOpacity = 0 + } + } + } + } + + let values: [String] + var currentValue: String? { + didSet { + self.valueLabel.text = currentValue + } + } + + init(values: [String]) { + self.values = values + super.init(frame: CGRect.zero) + self.backgroundColor = BKColor.white + + self.borderColor = BKColor.grey.lighten1 + self.borderWidthPreset = .border2 + self.cornerRadiusPreset = .cornerRadius3 + self.shadowColor = BKColor.grey.lighten1 + self.layer.shadowOffset = CGSize(width: 0, height: 0) + self.layer.shadowRadius = 2 + self.layer.shadowOpacity = 0 + + addSubview(valueLabel) + addSubview(dropIconView) + + self.dropIconView.snp.makeConstraints { make in + make.centerY.equalToSuperview() + make.right.equalTo(-6) + } + self.valueLabel.snp.makeConstraints { make in + make.centerY.equalToSuperview() + make.left.equalTo(16) + } + + self.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(tap))) + + defer { + self.currentValue = self.values.first + } + } + + @available(*, unavailable) + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + @objc func tap() { + let dropDown = DropDown(anchorView: self) + dropDown.cellNib = UINib(nibName: "BKDropDownCell", bundle: Bundle(for: BKDropDownCell.self)) + dropDown.cellHeight = 50 + dropDown.cornerRadius = 10 + dropDown.clipsToBounds = true + dropDown.bottomOffset = CGPoint(x: 0, y: 50) + + dropDown.dataSource = self.values + + dropDown.selectionAction = { [weak self] _, str in + self?.currentValue = str + self?.isSelecting = false + } + dropDown.cancelAction = { [weak self] in + self?.isSelecting = false + } + self.isSelecting = true + dropDown.show() + } +} diff --git a/View/GradientButton.swift b/View/GradientButton.swift new file mode 100644 index 0000000..1ab5862 --- /dev/null +++ b/View/GradientButton.swift @@ -0,0 +1,62 @@ +// +// UIView+Gradient.swift +// Bark +// +// Created by huangfeng on 2023/2/10. +// Copyright © 2023 Fin. All rights reserved. +// + +import UIKit + +typealias GradientPoints = (startPoint: CGPoint, endPoint: CGPoint) + +enum GradientOrientation { + case topRightBottomLeft + case topLeftBottomRight + case horizontal + case vertical + + var startPoint: CGPoint { + return points.startPoint + } + + var endPoint: CGPoint { + return points.endPoint + } + + var points: GradientPoints { + switch self { + case .topRightBottomLeft: + return (CGPoint(x: 0.0, y: 1.0), CGPoint(x: 1.0, y: 0.0)) + case .topLeftBottomRight: + return (CGPoint(x: 0.0, y: 0.0), CGPoint(x: 1, y: 1)) + case .horizontal: + return (CGPoint(x: 0.0, y: 0.5), CGPoint(x: 1.0, y: 0.5)) + case .vertical: + return (CGPoint(x: 0.0, y: 0.0), CGPoint(x: 0.0, y: 1.0)) + } + } +} + +class GradientButton: UIButton { + lazy var gradient: CAGradientLayer = { + let gradient = CAGradientLayer() + return gradient + }() + + func applyGradient(withColours colours: [UIColor], gradientOrientation orientation: GradientOrientation) { + gradient.frame = self.bounds + gradient.colors = colours.map { $0.cgColor } + gradient.startPoint = orientation.startPoint + gradient.endPoint = orientation.endPoint + + if gradient.superlayer == nil { + self.layer.insertSublayer(gradient, at: 0) + } + } + + override func layoutSubviews() { + super.layoutSubviews() + gradient.frame = self.bounds + } +}