An advanced Ethereum/EVM mobile wallet
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
alpha-wallet-ios/AlphaWallet/UI/FloatLabelCell.swift

175 lines
7.0 KiB

// Copyright SIX DAY LLC. All rights reserved.
7 years ago
import Foundation
import UIKit
import Eureka
// MARK: FloatLabelCell
7 years ago
public class _FloatLabelCell<T>: Cell<T>, UITextFieldDelegate, TextFieldCell where T: Equatable, T: InputTypeInitiable {
7 years ago
public var textField: UITextField! { return floatLabelTextField }
required public init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
7 years ago
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
7 years ago
required public init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
7 years ago
lazy public var floatLabelTextField: FloatLabelTextField = { [unowned self] in
let floatTextField = FloatLabelTextField()
floatTextField.translatesAutoresizingMaskIntoConstraints = false
floatTextField.font = .preferredFont(forTextStyle: .body)
floatTextField.titleFont = .boldSystemFont(ofSize: 11.0)
floatTextField.clearButtonMode = .whileEditing
return floatTextField
}()
7 years ago
open override func setup() {
super.setup()
height = { 55 }
selectionStyle = .none
contentView.addSubview(floatLabelTextField)
floatLabelTextField.delegate = self
floatLabelTextField.addTarget(self, action: #selector(_FloatLabelCell.textFieldDidChange(_:)), for: .editingChanged)
contentView.addConstraints(layoutConstraints())
}
7 years ago
open override func update() {
super.update()
textLabel?.text = nil
detailTextLabel?.text = nil
floatLabelTextField.attributedPlaceholder = NSAttributedString(string: row.title ?? "", attributes: [.foregroundColor: UIColor.lightGray])
7 years ago
floatLabelTextField.text = row.displayValueFor?(row.value)
floatLabelTextField.isEnabled = !row.isDisabled
floatLabelTextField.titleTextColour = .lightGray
floatLabelTextField.alpha = row.isDisabled ? 0.6 : 1
}
7 years ago
open override func cellCanBecomeFirstResponder() -> Bool {
return !row.isDisabled && floatLabelTextField.canBecomeFirstResponder
}
7 years ago
open override func cellBecomeFirstResponder(withDirection direction: Direction) -> Bool {
return floatLabelTextField.becomeFirstResponder()
}
7 years ago
open override func cellResignFirstResponder() -> Bool {
return floatLabelTextField.resignFirstResponder()
}
7 years ago
private func layoutConstraints() -> [NSLayoutConstraint] {
let views = ["floatLabeledTextField": floatLabelTextField]
let metrics = ["vMargin": 8.0]
return NSLayoutConstraint.constraints(
withVisualFormat: "H:|-[floatLabeledTextField]-|",
options: .alignAllLastBaseline,
metrics: metrics,
views: views
) +
NSLayoutConstraint.constraints(
withVisualFormat: "V:|-(vMargin)-[floatLabeledTextField]-(vMargin)-|",
options: .alignAllLastBaseline,
metrics: metrics,
views: views
)
7 years ago
}
@objc public func textFieldDidChange(_ textField: UITextField) {
7 years ago
guard let textValue = textField.text else {
row.value = nil
return
}
if let fieldRow = row as? FormatterConformance, let formatter = fieldRow.formatter {
if fieldRow.useFormatterDuringInput {
let value: AutoreleasingUnsafeMutablePointer<AnyObject?> = AutoreleasingUnsafeMutablePointer<AnyObject?>.init(UnsafeMutablePointer<T>.allocate(capacity: 1))
let errorDesc: AutoreleasingUnsafeMutablePointer<NSString?>? = nil
if formatter.getObjectValue(value, for: textValue, errorDescription: errorDesc) {
row.value = value.pointee as? T
if var selStartPos = textField.selectedTextRange?.start {
let oldVal = textField.text
textField.text = row.displayValueFor?(row.value)
if let f = formatter as? FormatterProtocol {
selStartPos = f.getNewPosition(forPosition: selStartPos, inTextInput: textField, oldValue: oldVal, newValue: textField.text)
}
textField.selectedTextRange = textField.textRange(from: selStartPos, to: selStartPos)
}
return
}
} else {
7 years ago
let value: AutoreleasingUnsafeMutablePointer<AnyObject?> = AutoreleasingUnsafeMutablePointer<AnyObject?>.init(UnsafeMutablePointer<T>.allocate(capacity: 1))
let errorDesc: AutoreleasingUnsafeMutablePointer<NSString?>? = nil
if formatter.getObjectValue(value, for: textValue, errorDescription: errorDesc) {
row.value = value.pointee as? T
}
return
}
}
guard !textValue.isEmpty else {
row.value = nil
return
}
guard let newValue = T.init(string: textValue) else {
return
}
row.value = newValue
}
7 years ago
private func displayValue(useFormatter: Bool) -> String? {
guard let v = row.value else { return nil }
if let formatter = (row as? FormatterConformance)?.formatter, useFormatter {
return textField?.isFirstResponder == true ? formatter.editingString(for: v) : formatter.string(for: v)
}
return String(describing: v)
}
7 years ago
public func textFieldDidBeginEditing(_ textField: UITextField) {
formViewController()?.beginEditing(of: self)
if let fieldRowConformance = row as? FormatterConformance, let _ = fieldRowConformance.formatter, fieldRowConformance.useFormatterOnDidBeginEditing ?? fieldRowConformance.useFormatterDuringInput {
textField.text = displayValue(useFormatter: true)
} else {
textField.text = displayValue(useFormatter: false)
}
}
7 years ago
public func textFieldDidEndEditing(_ textField: UITextField) {
formViewController()?.endEditing(of: self)
formViewController()?.textInputDidEndEditing(textField, cell: self)
textFieldDidChange(textField)
textField.text = displayValue(useFormatter: (row as? FormatterConformance)?.formatter != nil)
}
}
public class TextFloatLabelCell: _FloatLabelCell<String>, CellType {
required public init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
7 years ago
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
7 years ago
required public init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
7 years ago
public override func setup() {
super.setup()
textField?.autocorrectionType = .default
textField?.autocapitalizationType = .sentences
textField?.keyboardType = .default
}
}
// MARK: FloatLabelRow
7 years ago
open class FloatFieldRow<Cell: CellType>: FormatteableRow<Cell> where Cell: BaseCell, Cell: TextFieldCell {
7 years ago
public required init(tag: String?) {
super.init(tag: tag)
}
}
public final class TextFloatLabelRow: FloatFieldRow<TextFloatLabelCell>, RowType {
public required init(tag: String?) {
super.init(tag: tag)
}
}