Finished basic variant of "check new number" puller

This commit is contained in:
Selim Mustafaev 2022-03-27 00:46:33 +03:00
parent d34237ecf9
commit 1c12fe5b40
9 changed files with 224 additions and 73 deletions

View File

@ -9,11 +9,16 @@
<key>orderHint</key> <key>orderHint</key>
<integer>0</integer> <integer>0</integer>
</dict> </dict>
<key>AutoCatCore.xcscheme_^#shared#^_</key> <key>AutoCat2.xcscheme_^#shared#^_</key>
<dict> <dict>
<key>orderHint</key> <key>orderHint</key>
<integer>1</integer> <integer>1</integer>
</dict> </dict>
<key>AutoCatCore.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict> </dict>
</dict> </dict>
</plist> </plist>

View File

@ -5,9 +5,9 @@
"color-space" : "srgb", "color-space" : "srgb",
"components" : { "components" : {
"alpha" : "1.000", "alpha" : "1.000",
"blue" : "1.000", "blue" : "0xFF",
"green" : "1.000", "green" : "0xFF",
"red" : "1.000" "red" : "0xFF"
} }
}, },
"idiom" : "universal" "idiom" : "universal"

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -33,6 +33,8 @@ class PlateView: UIView {
} }
} }
var onChange: (() -> Void)?
override init(frame: CGRect) { override init(frame: CGRect) {
super.init(frame: frame) super.init(frame: frame)
setup() setup()
@ -81,6 +83,7 @@ class PlateView: UIView {
override func layoutSubviews() { override func layoutSubviews() {
super.layoutSubviews() super.layoutSubviews()
guard let number = self.number else { return } guard let number = self.number else { return }
guard let fgColorMain = UIColor(named: "PlateForeground")?.cgColor else { return } guard let fgColorMain = UIColor(named: "PlateForeground")?.cgColor else { return }
guard let bgColor = UIColor(named: "PlateBackground")?.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 height = fontSize/1.1 + 4
let width = height/PlateView.aspectRatio let width = height/PlateView.aspectRatio
return CGSize(width: width, height: height) 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?()
}
}
}

View File

@ -6,32 +6,33 @@
// //
import UIKit import UIKit
import AutoCatCore
class CheckController: UIViewController { class CheckController: UIViewController {
public var onCheck: ((String) -> Void)? public var onCheck: ((String) -> Void)?
private lazy var keyboardView: PNKeyboard = { private lazy var keyboardView: PNKeyboard = {
let keyboard = PNKeyboard(target: self.numberField, insets: .zero) let keyboard = PNKeyboard(target: self.plateView, insets: .zero)
keyboard.delegate = self keyboard.delegate = self
return keyboard 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) private lazy var checkButton: ACButton = {
.enable(false) 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 = { private lazy var stackView: UIStackView = {
let stack = UIStackView(arrangedSubviews: [plateView, checkButton]) let stack = UIStackView(arrangedSubviews: [plateView, checkButton])
@ -43,7 +44,7 @@ class CheckController: UIViewController {
private let titleLabel: UILabel = { private let titleLabel: UILabel = {
let label = UILabel() let label = UILabel()
label.text = "Check new plate number" label.text = "Check new number"
label.font = UIFont.preferredFont(forTextStyle: .headline) label.font = UIFont.preferredFont(forTextStyle: .headline)
label.textAlignment = .center label.textAlignment = .center
label.translatesAutoresizingMaskIntoConstraints = false label.translatesAutoresizingMaskIntoConstraints = false
@ -60,35 +61,23 @@ class CheckController: UIViewController {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
//view.backgroundColor = .systemBackground
checkButton.contentEdgeInsets = .init(top: 0, left: 8, bottom: 0, right: 8)
view.addSubview(mainStackView) view.addSubview(mainStackView)
mainStackView.pin(to: view, insets: .init(top: 16, left: 16, bottom: 16, right: 16)) 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() { func check() {
guard let number = numberField.text else { guard let number = plateView.number, number.isValid else {
return return
} }
let numberNormalized = number.filter { !$0.isWhitespace }.uppercased() let numberNormalized = number.asString().filter { !$0.isWhitespace }.uppercased()
numberField.resignFirstResponder()
onCheck?(numberNormalized) onCheck?(numberNormalized)
} }
func onNumberChanged() {
checkButton.isEnabled = plateView.number?.isValid ?? false
}
} }
extension CheckController: PNKeyboardDelegate { extension CheckController: PNKeyboardDelegate {
@ -97,16 +86,3 @@ extension CheckController: PNKeyboardDelegate {
check() 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
}
}

View File

@ -41,13 +41,13 @@ class MainTabController: UITabBarController, UITabBarControllerDelegate {
func showCheckPuller() { func showCheckPuller() {
var attributes = EKAttributes.bottomToast var attributes = EKAttributes.bottomToast
attributes.displayDuration = .infinity attributes.displayDuration = .infinity
attributes.positionConstraints.keyboardRelation = .bind(offset: .none) attributes.entryBackground = .visualEffect(style: .extra) //.color(color: .standardBackground)
attributes.entryBackground = .color(color: .standardBackground) attributes.screenBackground = .color(color: EKColor(UIColor(white: 0, alpha: 0.7)))
attributes.screenBackground = .color(color: EKColor(UIColor(white: 0.3, alpha: 0.5)))
attributes.roundCorners = .top(radius: 24) attributes.roundCorners = .top(radius: 24)
attributes.screenInteraction = .dismiss attributes.screenInteraction = .dismiss
attributes.entryInteraction = .forward 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() let checkController = CheckController()
checkController.onCheck = { number in checkController.onCheck = { number in

View File

@ -1,11 +1,19 @@
import Foundation import Foundation
public class PlateNumber { public class PlateNumber {
private var number: String private var number: String = ""
private var numberEnglish: 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) { 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 }) self.numberEnglish = String(self.number.map { Constants.pnLettersMap[$0] ?? $0 })
} }
@ -14,12 +22,47 @@ public class PlateNumber {
} }
public func mainPart() -> String { public func mainPart() -> String {
let index = self.numberEnglish.index(self.numberEnglish.startIndex, offsetBy: 6) return String(self.numberEnglish.prefix(mainPartLength))
return String(self.numberEnglish[..<index])
} }
public func region() -> String { public func region() -> String {
let index = self.numberEnglish.index(self.numberEnglish.startIndex, offsetBy: 6) guard numberEnglish.count > mainPartLength else {
return String(self.numberEnglish[index...]) 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
} }
} }