New keyboard type for entering VIN
This commit is contained in:
parent
24e9b90c16
commit
2ef6968d00
@ -72,6 +72,21 @@
|
|||||||
endingLineNumber = "37"
|
endingLineNumber = "37"
|
||||||
offsetFromSymbolStart = "256">
|
offsetFromSymbolStart = "256">
|
||||||
</Location>
|
</Location>
|
||||||
|
<Location
|
||||||
|
uuid = "2786565A-9610-4232-920E-0763816C4DBF - f20dc4504decd67d"
|
||||||
|
shouldBeEnabled = "Yes"
|
||||||
|
ignoreCount = "0"
|
||||||
|
continueAfterRunningActions = "No"
|
||||||
|
symbolName = "Eureka.DatePickerRowProtocol.configurePickerStyle(Eureka.DatePickerCell, __C.UIDatePickerMode) -> ()"
|
||||||
|
moduleName = "AutoCat"
|
||||||
|
usesParentBreakpointCondition = "Yes"
|
||||||
|
urlString = "file:///Users/selim/Library/Developer/Xcode/DerivedData/AutoCat-fhilwnlnsrpirleiajogdcyhyyey/SourcePackages/checkouts/Eureka/Source/Rows/DateInlineRow.swift"
|
||||||
|
startingColumnNumber = "9223372036854775807"
|
||||||
|
endingColumnNumber = "9223372036854775807"
|
||||||
|
startingLineNumber = "37"
|
||||||
|
endingLineNumber = "37"
|
||||||
|
offsetFromSymbolStart = "112">
|
||||||
|
</Location>
|
||||||
</Locations>
|
</Locations>
|
||||||
</BreakpointContent>
|
</BreakpointContent>
|
||||||
</BreakpointProxy>
|
</BreakpointProxy>
|
||||||
|
|||||||
@ -40,4 +40,21 @@ extension UIStackView {
|
|||||||
self.distribution = distribution
|
self.distribution = distribution
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func removeAllArrangedSubviews() {
|
||||||
|
arrangedSubviews.forEach {
|
||||||
|
self.removeArrangedSubview($0)
|
||||||
|
NSLayoutConstraint.deactivate($0.constraints)
|
||||||
|
$0.removeFromSuperview()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func addArrangedSubviews(_ views: [UIView]) {
|
||||||
|
views.forEach { addArrangedSubview($0) }
|
||||||
|
}
|
||||||
|
|
||||||
|
func setArrangedSubviews(_ views: [UIView]) {
|
||||||
|
removeAllArrangedSubviews()
|
||||||
|
addArrangedSubviews(views)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,6 +39,7 @@ class NewNumberController: UIViewController {
|
|||||||
private lazy var vinField: UITextField = {
|
private lazy var vinField: UITextField = {
|
||||||
let view = UITextField()
|
let view = UITextField()
|
||||||
view.translatesAutoresizingMaskIntoConstraints = false
|
view.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
view.borderStyle = .roundedRect
|
||||||
view.isHidden = true
|
view.isHidden = true
|
||||||
return view
|
return view
|
||||||
}()
|
}()
|
||||||
@ -48,6 +49,7 @@ class NewNumberController: UIViewController {
|
|||||||
button.isEnabled = false
|
button.isEnabled = false
|
||||||
button.contentEdgeInsets = .init(top: 0, left: 8, bottom: 0, right: 8)
|
button.contentEdgeInsets = .init(top: 0, left: 8, bottom: 0, right: 8)
|
||||||
button.accessibilityIdentifier = "checkButton"
|
button.accessibilityIdentifier = "checkButton"
|
||||||
|
button.setContentHuggingPriority(.defaultHigh, for: .horizontal)
|
||||||
return button
|
return button
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -131,9 +133,13 @@ class NewNumberController: UIViewController {
|
|||||||
case .plateNumber:
|
case .plateNumber:
|
||||||
plateView.isHidden = false
|
plateView.isHidden = false
|
||||||
vinField.isHidden = true
|
vinField.isHidden = true
|
||||||
|
keyboardView.target = plateView
|
||||||
|
keyboardView.type = .plateNumber
|
||||||
case .vin:
|
case .vin:
|
||||||
plateView.isHidden = true
|
plateView.isHidden = true
|
||||||
vinField.isHidden = false
|
vinField.isHidden = false
|
||||||
|
keyboardView.target = vinField
|
||||||
|
keyboardView.type = .vin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,28 +15,57 @@ enum PNButtonType {
|
|||||||
case done
|
case done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum PNKeyboardType {
|
||||||
|
|
||||||
|
case plateNumber
|
||||||
|
case vin
|
||||||
|
}
|
||||||
|
|
||||||
class PNButton: UIButton {
|
class PNButton: UIButton {
|
||||||
private(set) var type: PNButtonType
|
private(set) var type: PNButtonType
|
||||||
|
private var keyboardType: PNKeyboardType = .plateNumber
|
||||||
private var rectLayer = CAShapeLayer()
|
private var rectLayer = CAShapeLayer()
|
||||||
private var bgColor = UIColor(named: "KeyBackground")
|
private var bgColor = UIColor(named: "KeyBackground")
|
||||||
|
|
||||||
weak var delegate: PNButtonDelegate?
|
weak var delegate: PNButtonDelegate?
|
||||||
|
|
||||||
init(letter: Character) {
|
var letterFont: UIFont? {
|
||||||
|
|
||||||
|
switch keyboardType {
|
||||||
|
case .plateNumber:
|
||||||
|
return UIFont(name: "RoadNumbers", size: 36)
|
||||||
|
case .vin:
|
||||||
|
return .systemFont(ofSize: 24)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var digitFont: UIFont? {
|
||||||
|
|
||||||
|
switch keyboardType {
|
||||||
|
case .plateNumber:
|
||||||
|
return UIFont(name: "RoadNumbersCyr-Regular", size: 30)
|
||||||
|
case .vin:
|
||||||
|
return .systemFont(ofSize: 24)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init(letter: Character, keyboardType: PNKeyboardType = .plateNumber) {
|
||||||
self.type = .symbol(String(letter))
|
self.type = .symbol(String(letter))
|
||||||
|
self.keyboardType = keyboardType
|
||||||
super.init(frame: .zero)
|
super.init(frame: .zero)
|
||||||
self.setup()
|
self.setup()
|
||||||
self.titleLabel?.font = UIFont(name: "RoadNumbers", size: 36)
|
self.titleLabel?.font = letterFont
|
||||||
let title = String(Constants.pnLettersMap[letter] ?? letter)
|
let title = String(Constants.pnLettersMap[letter] ?? letter)
|
||||||
self.setTitle(title, for: .normal)
|
self.setTitle(title, for: .normal)
|
||||||
self.setTitleColor(.label, for: .normal)
|
self.setTitleColor(.label, for: .normal)
|
||||||
}
|
}
|
||||||
|
|
||||||
init(digit: Int) {
|
init(digit: Int, keyboardType: PNKeyboardType = .plateNumber) {
|
||||||
self.type = .symbol(String(digit))
|
self.type = .symbol(String(digit))
|
||||||
|
self.keyboardType = keyboardType
|
||||||
super.init(frame: .zero)
|
super.init(frame: .zero)
|
||||||
self.setup()
|
self.setup()
|
||||||
self.titleLabel?.font = UIFont(name: "RoadNumbersCyr-Regular", size: 30)
|
self.titleLabel?.font = digitFont
|
||||||
let character = Character(String(digit))
|
let character = Character(String(digit))
|
||||||
let title = String(Constants.pnLettersMap[character] ?? character)
|
let title = String(Constants.pnLettersMap[character] ?? character)
|
||||||
self.setTitle(title, for: .normal)
|
self.setTitle(title, for: .normal)
|
||||||
@ -98,20 +127,52 @@ class PNButton: UIButton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class PNKeyboard: UIView, UIInputViewAudioFeedback, PNButtonDelegate {
|
class PNKeyboard: UIView, UIInputViewAudioFeedback, PNButtonDelegate {
|
||||||
private weak var target: UIKeyInput?
|
public weak var target: UIKeyInput?
|
||||||
weak var delegate: PNKeyboardDelegate?
|
weak var delegate: PNKeyboardDelegate?
|
||||||
|
|
||||||
private let insets: UIEdgeInsets
|
private let insets: UIEdgeInsets
|
||||||
|
|
||||||
init(target: UIKeyInput, insets: UIEdgeInsets = .zero) {
|
public var type: PNKeyboardType {
|
||||||
|
didSet {
|
||||||
|
setupButtons()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var letters: [Character] {
|
||||||
|
|
||||||
|
switch type {
|
||||||
|
case .plateNumber:
|
||||||
|
return Array(Constants.pnLettersMap.keys)
|
||||||
|
case .vin:
|
||||||
|
return Constants.vinLetters
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var lettersWidthConstraint: NSLayoutConstraint?
|
||||||
|
private var digitsWidthConstraint: NSLayoutConstraint?
|
||||||
|
|
||||||
|
var mainStack: UIStackView = .horizontal([])
|
||||||
|
//.distribution(.fillProportionally)
|
||||||
|
.spacing(16)
|
||||||
|
|
||||||
|
init(target: UIKeyInput, type: PNKeyboardType = .plateNumber, insets: UIEdgeInsets = .zero) {
|
||||||
self.target = target
|
self.target = target
|
||||||
self.insets = insets
|
self.insets = insets
|
||||||
|
self.type = type
|
||||||
super.init(frame: .zero)
|
super.init(frame: .zero)
|
||||||
self.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
self.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
||||||
|
|
||||||
let blurEffectView = UIVisualEffectView(effect: UIBlurEffect())
|
let blurEffectView = UIVisualEffectView(effect: UIBlurEffect())
|
||||||
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
||||||
self.addSubview(blurEffectView)
|
self.addSubview(blurEffectView)
|
||||||
|
self.addSubview(mainStack)
|
||||||
|
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
mainStack.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: insets.left),
|
||||||
|
mainStack.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -insets.right),
|
||||||
|
mainStack.topAnchor.constraint(equalTo: self.topAnchor, constant: insets.top),
|
||||||
|
mainStack.bottomAnchor.constraint(equalTo: self.safeAreaLayoutGuide.bottomAnchor, constant: -insets.bottom)
|
||||||
|
])
|
||||||
|
|
||||||
self.setupButtons()
|
self.setupButtons()
|
||||||
}
|
}
|
||||||
@ -120,14 +181,53 @@ class PNKeyboard: UIView, UIInputViewAudioFeedback, PNButtonDelegate {
|
|||||||
fatalError("init(coder:) has not been implemented")
|
fatalError("init(coder:) has not been implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func layoutSubviews() {
|
||||||
|
super.layoutSubviews()
|
||||||
|
|
||||||
|
let lettersMult: CGFloat = type == .plateNumber ? 0.5 : 2.0/3.0
|
||||||
|
let digitsMult: CGFloat = type == .plateNumber ? 0.5 : 1.0/3.0
|
||||||
|
let availableWidth = frame.width - mainStack.spacing
|
||||||
|
|
||||||
|
let newLettersWidth = availableWidth*lettersMult
|
||||||
|
let newDigitsWidth = availableWidth*digitsMult
|
||||||
|
|
||||||
|
let needChangeConstraints = lettersWidthConstraint?.constant != newLettersWidth
|
||||||
|
|| digitsWidthConstraint?.constant != newDigitsWidth
|
||||||
|
|
||||||
|
if needChangeConstraints {
|
||||||
|
lettersWidthConstraint?.constant = newLettersWidth
|
||||||
|
digitsWidthConstraint?.constant = newDigitsWidth
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func letterRows(from buttons: [PNButton]) -> [UIView] {
|
||||||
|
|
||||||
|
switch type {
|
||||||
|
case .plateNumber:
|
||||||
|
return [
|
||||||
|
createLetterStack([buttons[0], buttons[1], buttons[2]]),
|
||||||
|
createLetterStack([buttons[3], buttons[4], buttons[5]]),
|
||||||
|
createLetterStack([buttons[6], buttons[7], buttons[8]]),
|
||||||
|
createLetterStack([buttons[9], buttons[10], buttons[11]])
|
||||||
|
]
|
||||||
|
case .vin:
|
||||||
|
return [
|
||||||
|
createLetterStack([buttons[0], buttons[1], buttons[2], buttons[3], buttons[4], buttons[5]]),
|
||||||
|
createLetterStack([buttons[6], buttons[7], buttons[8], buttons[9], buttons[10], buttons[11]]),
|
||||||
|
createLetterStack([buttons[12], buttons[13], buttons[14], buttons[15], buttons[16], buttons[17]]),
|
||||||
|
createLetterStack([buttons[18], buttons[19], buttons[20], buttons[21], buttons[22]])
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func setupButtons() {
|
func setupButtons() {
|
||||||
let letters: [PNButton] = Constants.pnLettersMap.keys.sorted().map { letter in
|
let letterButtons: [PNButton] = letters.sorted().map { letter in
|
||||||
let button = PNButton(letter: letter)
|
let button = PNButton(letter: letter, keyboardType: type)
|
||||||
button.delegate = self
|
button.delegate = self
|
||||||
return button
|
return button
|
||||||
}
|
}
|
||||||
let digits: [PNButton] = [1,2,3,4,5,6,7,8,9,0].map { digit in
|
let digits: [PNButton] = [1,2,3,4,5,6,7,8,9,0].map { digit in
|
||||||
let button = PNButton(digit: digit)
|
let button = PNButton(digit: digit, keyboardType: type)
|
||||||
button.delegate = self
|
button.delegate = self
|
||||||
return button
|
return button
|
||||||
}
|
}
|
||||||
@ -139,14 +239,8 @@ class PNKeyboard: UIView, UIInputViewAudioFeedback, PNButtonDelegate {
|
|||||||
done.setBacgroundColor(color: .systemBlue)
|
done.setBacgroundColor(color: .systemBlue)
|
||||||
done.tintColor = .white
|
done.tintColor = .white
|
||||||
|
|
||||||
let letterRows = [
|
let rows = letterRows(from: letterButtons)
|
||||||
self.createLetterStack([letters[0], letters[1], letters[2]]),
|
let lettersStack = UIStackView(arrangedSubviews: rows)
|
||||||
self.createLetterStack([letters[3], letters[4], letters[5]]),
|
|
||||||
self.createLetterStack([letters[6], letters[7], letters[8]]),
|
|
||||||
self.createLetterStack([letters[9], letters[10], letters[11]])
|
|
||||||
]
|
|
||||||
|
|
||||||
let lettersStack = UIStackView(arrangedSubviews: letterRows)
|
|
||||||
lettersStack.axis = .vertical
|
lettersStack.axis = .vertical
|
||||||
lettersStack.distribution = .fillEqually
|
lettersStack.distribution = .fillEqually
|
||||||
//lettersStack.spacing = 8
|
//lettersStack.spacing = 8
|
||||||
@ -163,18 +257,15 @@ class PNKeyboard: UIView, UIInputViewAudioFeedback, PNButtonDelegate {
|
|||||||
digitsStack.distribution = .fillEqually
|
digitsStack.distribution = .fillEqually
|
||||||
//digitsStack.spacing = 8
|
//digitsStack.spacing = 8
|
||||||
|
|
||||||
let mainStack = UIStackView(arrangedSubviews: [lettersStack, digitsStack])
|
mainStack.setArrangedSubviews([lettersStack, digitsStack])
|
||||||
mainStack.spacing = 16
|
|
||||||
mainStack.distribution = .fillEqually
|
|
||||||
mainStack.translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
self.addSubview(mainStack)
|
|
||||||
|
|
||||||
NSLayoutConstraint.activate([
|
lettersWidthConstraint = lettersStack.widthAnchor.constraint(equalToConstant: 0)
|
||||||
mainStack.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: insets.left),
|
digitsWidthConstraint = digitsStack.widthAnchor.constraint(equalToConstant: 0)
|
||||||
mainStack.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -insets.right),
|
|
||||||
mainStack.topAnchor.constraint(equalTo: self.topAnchor, constant: insets.top),
|
lettersWidthConstraint?.priority = .defaultLow
|
||||||
mainStack.bottomAnchor.constraint(equalTo: self.safeAreaLayoutGuide.bottomAnchor, constant: -insets.bottom)
|
digitsWidthConstraint?.priority = .defaultLow
|
||||||
])
|
|
||||||
|
NSLayoutConstraint.activate([lettersWidthConstraint, digitsWidthConstraint].compactMap { $0 })
|
||||||
}
|
}
|
||||||
|
|
||||||
func createLetterStack(_ views: [UIView]) -> UIStackView {
|
func createLetterStack(_ views: [UIView]) -> UIStackView {
|
||||||
|
|||||||
@ -15,6 +15,10 @@ public enum Constants {
|
|||||||
"А": "A", "В": "B", "Е": "E", "К": "K", "М": "M", "Н": "H", "О": "O", "Р": "P", "С": "C", "Т": "T", "У": "Y", "Х": "X"
|
"А": "A", "В": "B", "Е": "E", "К": "K", "М": "M", "Н": "H", "О": "O", "Р": "P", "С": "C", "Т": "T", "У": "Y", "Х": "X"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
public static let vinLetters: [Character] = [
|
||||||
|
"A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"
|
||||||
|
]
|
||||||
|
|
||||||
public static let googleAuthURL = "https://accounts.google.com/o/oauth2/v2/auth"
|
public static let googleAuthURL = "https://accounts.google.com/o/oauth2/v2/auth"
|
||||||
public static let googleTokenURL = "https://oauth2.googleapis.com/token"
|
public static let googleTokenURL = "https://oauth2.googleapis.com/token"
|
||||||
public static let googleRedirectURL = "com.googleusercontent.apps.994679674451-k7clunkk4nicl6iuajdtc5u7hvustbdb:/oauth2callback"
|
public static let googleRedirectURL = "com.googleusercontent.apps.994679674451-k7clunkk4nicl6iuajdtc5u7hvustbdb:/oauth2callback"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user