|  |  |  | // Copyright © 2022 Rangeproof Pty Ltd. All rights reserved. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import UIKit | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @objc(SNTextField) | 
					
						
							|  |  |  | public final class TextField: UITextField { | 
					
						
							|  |  |  |     private let usesDefaultHeight: Bool | 
					
						
							|  |  |  |     private let height: CGFloat | 
					
						
							|  |  |  |     private let horizontalInset: CGFloat | 
					
						
							|  |  |  |     private let verticalInset: CGFloat | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static let height: CGFloat = isIPhone5OrSmaller ? CGFloat(48) : CGFloat(80) | 
					
						
							|  |  |  |     public static let cornerRadius: CGFloat = 8 | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     @objc(initWithPlaceholder:usesDefaultHeight:) | 
					
						
							|  |  |  |     public convenience init(placeholder: String, usesDefaultHeight: Bool) { | 
					
						
							|  |  |  |         self.init(placeholder: placeholder, usesDefaultHeight: usesDefaultHeight, customHeight: nil, customHorizontalInset: nil, customVerticalInset: nil) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     public init(placeholder: String, usesDefaultHeight: Bool = true, customHeight: CGFloat? = nil, customHorizontalInset: CGFloat? = nil, customVerticalInset: CGFloat? = nil) { | 
					
						
							|  |  |  |         self.usesDefaultHeight = usesDefaultHeight | 
					
						
							|  |  |  |         self.height = customHeight ?? TextField.height | 
					
						
							|  |  |  |         self.horizontalInset = customHorizontalInset ?? (isIPhone5OrSmaller ? Values.mediumSpacing : Values.largeSpacing) | 
					
						
							|  |  |  |         self.verticalInset = customVerticalInset ?? (isIPhone5OrSmaller ? Values.smallSpacing : Values.largeSpacing) | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         super.init(frame: CGRect.zero) | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         self.placeholder = placeholder | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         setUpStyle() | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     public override init(frame: CGRect) { | 
					
						
							|  |  |  |         preconditionFailure("Use init(placeholder:) instead.") | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     public required init?(coder: NSCoder) { | 
					
						
							|  |  |  |         preconditionFailure("Use init(placeholder:) instead.") | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     private func setUpStyle() { | 
					
						
							|  |  |  |         font = .systemFont(ofSize: Values.smallFontSize) | 
					
						
							|  |  |  |         themeTextColor = .textPrimary | 
					
						
							|  |  |  |         themeTintColor = .primary | 
					
						
							|  |  |  |         themeBorderColor = .borderSeparator | 
					
						
							|  |  |  |         layer.borderWidth = 1 | 
					
						
							|  |  |  |         layer.cornerRadius = TextField.cornerRadius | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         if usesDefaultHeight { | 
					
						
							|  |  |  |             set(.height, to: height) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         ThemeManager.onThemeChange(observer: self) { [weak self] theme, _ in | 
					
						
							|  |  |  |             switch theme.interfaceStyle { | 
					
						
							|  |  |  |                 case .light: self?.keyboardAppearance = .light | 
					
						
							|  |  |  |                 default: self?.keyboardAppearance = .dark | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |             if let textSecondary: UIColor = theme.color(for: .textSecondary), let placeholder: String = self?.placeholder { | 
					
						
							|  |  |  |                 self?.attributedPlaceholder = NSAttributedString( | 
					
						
							|  |  |  |                     string: placeholder, | 
					
						
							|  |  |  |                     attributes: [ .foregroundColor: textSecondary] | 
					
						
							|  |  |  |                 ) | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     public override func textRect(forBounds bounds: CGRect) -> CGRect { | 
					
						
							|  |  |  |         if usesDefaultHeight { | 
					
						
							|  |  |  |             return bounds.insetBy(dx: horizontalInset, dy: verticalInset) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |             return bounds.insetBy(dx: Values.mediumSpacing, dy: Values.smallSpacing) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     public override func editingRect(forBounds bounds: CGRect) -> CGRect { | 
					
						
							|  |  |  |         if usesDefaultHeight { | 
					
						
							|  |  |  |             return bounds.insetBy(dx: horizontalInset, dy: verticalInset) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |             return bounds.insetBy(dx: Values.mediumSpacing, dy: Values.smallSpacing) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |