diff --git a/AutoCat2.xcodeproj/xcuserdata/selim.xcuserdatad/xcschemes/xcschememanagement.plist b/AutoCat2.xcodeproj/xcuserdata/selim.xcuserdatad/xcschemes/xcschememanagement.plist
index 973e834..e2ffec3 100644
--- a/AutoCat2.xcodeproj/xcuserdata/selim.xcuserdatad/xcschemes/xcschememanagement.plist
+++ b/AutoCat2.xcodeproj/xcuserdata/selim.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -9,11 +9,16 @@
orderHint
0
- AutoCatCore.xcscheme_^#shared#^_
+ AutoCat2.xcscheme_^#shared#^_
orderHint
1
+ AutoCatCore.xcscheme_^#shared#^_
+
+ orderHint
+ 0
+
diff --git a/AutoCat2/Assets.xcassets/Colors/KeyBackground.colorset/Contents.json b/AutoCat2/Assets.xcassets/Colors/KeyBackground.colorset/Contents.json
index eb0fccd..c1af852 100644
--- a/AutoCat2/Assets.xcassets/Colors/KeyBackground.colorset/Contents.json
+++ b/AutoCat2/Assets.xcassets/Colors/KeyBackground.colorset/Contents.json
@@ -5,9 +5,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
- "blue" : "1.000",
- "green" : "1.000",
- "red" : "1.000"
+ "blue" : "0xFF",
+ "green" : "0xFF",
+ "red" : "0xFF"
}
},
"idiom" : "universal"
diff --git a/AutoCat2/Assets.xcassets/Colors/PlateBackground.colorset/Contents.json b/AutoCat2/Assets.xcassets/Colors/PlateBackground.colorset/Contents.json
new file mode 100644
index 0000000..2257e90
--- /dev/null
+++ b/AutoCat2/Assets.xcassets/Colors/PlateBackground.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "1.000",
+ "green" : "1.000",
+ "red" : "1.000"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "display-p3",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0.152",
+ "green" : "0.152",
+ "red" : "0.152"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/AutoCat2/Assets.xcassets/Colors/PlateBackgroundError.colorset/Contents.json b/AutoCat2/Assets.xcassets/Colors/PlateBackgroundError.colorset/Contents.json
new file mode 100644
index 0000000..dcf9455
--- /dev/null
+++ b/AutoCat2/Assets.xcassets/Colors/PlateBackgroundError.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "display-p3",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0.000",
+ "green" : "0.000",
+ "red" : "1.000"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "display-p3",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0.182",
+ "green" : "0.225",
+ "red" : "1.000"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/AutoCat2/Assets.xcassets/Colors/PlateForeground.colorset/Contents.json b/AutoCat2/Assets.xcassets/Colors/PlateForeground.colorset/Contents.json
new file mode 100644
index 0000000..945ab6a
--- /dev/null
+++ b/AutoCat2/Assets.xcassets/Colors/PlateForeground.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0.000",
+ "green" : "0.000",
+ "red" : "0.000"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "display-p3",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0.866",
+ "green" : "0.866",
+ "red" : "0.866"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/AutoCat2/Components/PlateView/PlateView.swift b/AutoCat2/Components/PlateView/PlateView.swift
index 14bb9df..dba7719 100644
--- a/AutoCat2/Components/PlateView/PlateView.swift
+++ b/AutoCat2/Components/PlateView/PlateView.swift
@@ -33,6 +33,8 @@ class PlateView: UIView {
}
}
+ var onChange: (() -> Void)?
+
override init(frame: CGRect) {
super.init(frame: frame)
setup()
@@ -81,6 +83,7 @@ class PlateView: UIView {
override func layoutSubviews() {
super.layoutSubviews()
+
guard let number = self.number else { return }
guard let fgColorMain = UIColor(named: "PlateForeground")?.cgColor else { return }
guard let bgColor = UIColor(named: "PlateBackground")?.cgColor else { return }
@@ -134,16 +137,26 @@ class PlateView: UIView {
let height = fontSize/1.1 + 4
let width = height/PlateView.aspectRatio
return CGSize(width: width, height: height)
-
-// guard self.bounds.width != 0 || self.bounds.height != 0 else {
-// return CGSize.zero
-// }
-//
-// let curAspectRatio = self.bounds.height/self.bounds.width
-// if curAspectRatio >= PlateView.aspectRatio {
-// return CGSize(width: self.bounds.width, height: self.bounds.width*PlateView.aspectRatio)
-// } else {
-// return CGSize(width: self.bounds.height/PlateView.aspectRatio, height: self.bounds.height)
-// }
}
}
+
+extension PlateView: UIKeyInput {
+
+ var hasText: Bool {
+ number?.hasText ?? false
+ }
+
+ func insertText(_ text: String) {
+ if number?.insertText(text) == true {
+ layoutSubviews()
+ onChange?()
+ }
+ }
+
+ func deleteBackward() {
+ if number?.deleteBackward() == true {
+ layoutSubviews()
+ onChange?()
+ }
+ }
+}
diff --git a/AutoCat2/Controllers/CheckController.swift b/AutoCat2/Controllers/CheckController.swift
index fcf88f7..4e87987 100644
--- a/AutoCat2/Controllers/CheckController.swift
+++ b/AutoCat2/Controllers/CheckController.swift
@@ -6,32 +6,33 @@
//
import UIKit
+import AutoCatCore
class CheckController: UIViewController {
public var onCheck: ((String) -> Void)?
private lazy var keyboardView: PNKeyboard = {
- let keyboard = PNKeyboard(target: self.numberField, insets: .zero)
+ let keyboard = PNKeyboard(target: self.plateView, insets: .zero)
keyboard.delegate = self
return keyboard
}()
-
- private lazy var numberField: SwiftMaskTextfield = {
- let textField = SwiftMaskTextfield()
- textField.formatPattern = "@###@@###"
- textField.placeholder = "A001AA 777"
- textField.borderStyle = .roundedRect
- textField.font = .preferredFont(forTextStyle: .largeTitle)
- textField.textAlignment = .center
- textField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
- return textField
- }()
- private let plateView = PlateView(frame: .zero)
+ private lazy var plateView: PlateView = {
+ let view = PlateView(frame: .zero)
+ view.fontSize = 48
+ view.number = PlateNumber("")
+ view.onChange = onNumberChanged
+ view.setContentHuggingPriority(.defaultHigh, for: .horizontal)
+ return view
+ }()
- private lazy var checkButton = ACButton(title: "Check", onTap: check)
- .enable(false)
+ private lazy var checkButton: ACButton = {
+ let button = ACButton(title: "Check", onTap: check)
+ button.isEnabled = false
+ button.contentEdgeInsets = .init(top: 0, left: 8, bottom: 0, right: 8)
+ return button
+ }()
private lazy var stackView: UIStackView = {
let stack = UIStackView(arrangedSubviews: [plateView, checkButton])
@@ -43,7 +44,7 @@ class CheckController: UIViewController {
private let titleLabel: UILabel = {
let label = UILabel()
- label.text = "Check new plate number"
+ label.text = "Check new number"
label.font = UIFont.preferredFont(forTextStyle: .headline)
label.textAlignment = .center
label.translatesAutoresizingMaskIntoConstraints = false
@@ -60,35 +61,23 @@ class CheckController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
-
- //view.backgroundColor = .systemBackground
- checkButton.contentEdgeInsets = .init(top: 0, left: 8, bottom: 0, right: 8)
view.addSubview(mainStackView)
mainStackView.pin(to: view, insets: .init(top: 16, left: 16, bottom: 16, right: 16))
-
- NSLayoutConstraint.activate([
- plateView.heightAnchor.constraint(equalToConstant: 40)
- ])
- }
-
- override func viewDidAppear(_ animated: Bool) {
- super.viewDidAppear(animated)
-
- DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
- self.numberField.becomeFirstResponder()
- }
}
func check() {
- guard let number = numberField.text else {
+ guard let number = plateView.number, number.isValid else {
return
}
- let numberNormalized = number.filter { !$0.isWhitespace }.uppercased()
- numberField.resignFirstResponder()
+ let numberNormalized = number.asString().filter { !$0.isWhitespace }.uppercased()
onCheck?(numberNormalized)
}
+
+ func onNumberChanged() {
+ checkButton.isEnabled = plateView.number?.isValid ?? false
+ }
}
extension CheckController: PNKeyboardDelegate {
@@ -97,16 +86,3 @@ extension CheckController: PNKeyboardDelegate {
check()
}
}
-
-extension CheckController: UITextFieldDelegate {
-
- @objc func textFieldDidChange(_ textField: UITextField) {
- guard let text = textField.text else {
- self.checkButton.isEnabled = false
- return
- }
-
- self.checkButton.isEnabled = text.count >= 8
- }
-
-}
diff --git a/AutoCat2/Controllers/MainTabController.swift b/AutoCat2/Controllers/MainTabController.swift
index ee59ade..fb8ce4a 100644
--- a/AutoCat2/Controllers/MainTabController.swift
+++ b/AutoCat2/Controllers/MainTabController.swift
@@ -41,13 +41,13 @@ class MainTabController: UITabBarController, UITabBarControllerDelegate {
func showCheckPuller() {
var attributes = EKAttributes.bottomToast
attributes.displayDuration = .infinity
- attributes.positionConstraints.keyboardRelation = .bind(offset: .none)
- attributes.entryBackground = .color(color: .standardBackground)
- attributes.screenBackground = .color(color: EKColor(UIColor(white: 0.3, alpha: 0.5)))
+ attributes.entryBackground = .visualEffect(style: .extra) //.color(color: .standardBackground)
+ attributes.screenBackground = .color(color: EKColor(UIColor(white: 0, alpha: 0.7)))
attributes.roundCorners = .top(radius: 24)
attributes.screenInteraction = .dismiss
attributes.entryInteraction = .forward
- //attributes.shadow = .active(with: .init(color: .black, opacity: 0.2, radius: 24, offset: .zero))
+ attributes.entranceAnimation = .init(translate: .init(duration: 0.2))
+ attributes.exitAnimation = .init(translate: .init(duration: 0.2))
let checkController = CheckController()
checkController.onCheck = { number in
diff --git a/AutoCatCore/Models/PlateNumber.swift b/AutoCatCore/Models/PlateNumber.swift
index 1eb436d..2fca407 100644
--- a/AutoCatCore/Models/PlateNumber.swift
+++ b/AutoCatCore/Models/PlateNumber.swift
@@ -1,11 +1,19 @@
import Foundation
public class PlateNumber {
- private var number: String
- private var numberEnglish: String
+ private var number: String = ""
+ private var numberEnglish: String = ""
+
+ private let maxLength = 9
+ private let mainPartLength = 6
+ private let isDigitMask = [false, true, true, true, false, false, true, true, true]
public init(_ string: String) {
- self.number = string
+ setNumber(string)
+ }
+
+ public func setNumber(_ number: String) {
+ self.number = number
self.numberEnglish = String(self.number.map { Constants.pnLettersMap[$0] ?? $0 })
}
@@ -14,12 +22,47 @@ public class PlateNumber {
}
public func mainPart() -> String {
- let index = self.numberEnglish.index(self.numberEnglish.startIndex, offsetBy: 6)
- return String(self.numberEnglish[.. String {
- let index = self.numberEnglish.index(self.numberEnglish.startIndex, offsetBy: 6)
- return String(self.numberEnglish[index...])
+ guard numberEnglish.count > mainPartLength else {
+ return ""
+ }
+
+ return String(self.numberEnglish.dropFirst(mainPartLength))
+ }
+
+ public var isValid: Bool {
+ number.count >= 8
+ }
+
+ // MARK: - UIKeyInput
+
+ public var hasText: Bool {
+ return !number.isEmpty
+ }
+
+ // Returns true if number was changed
+ public func insertText(_ text: String) -> Bool {
+ guard number.count < maxLength, text.count == 1 else {
+ return false
+ }
+
+ if text.first?.isNumber == isDigitMask[number.count] {
+ setNumber(number + text)
+ return true
+ } else {
+ return false
+ }
+ }
+
+ public func deleteBackward() -> Bool {
+ guard !number.isEmpty else {
+ return false
+ }
+
+ setNumber(String(number.dropLast()))
+ return true
}
}