123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- // _____ _
- // |_ _| |_ _ _ ___ ___ _ __ __ _
- // | | | ' \| '_/ -_) -_) ' \/ _` |_
- // |_| |_||_|_| \___\___|_|_|_\__,_(_)
- //
- // Threema iOS Client
- // Copyright (c) 2018-2020 Threema GmbH
- //
- // This program is free software: you can redistribute it and/or modify
- // it under the terms of the GNU Affero General Public License, version 3,
- // as published by the Free Software Foundation.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU Affero General Public License for more details.
- //
- // You should have received a copy of the GNU Affero General Public License
- // along with this program. If not, see <https://www.gnu.org/licenses/>.
- import UIKit
- @objc protocol SetupTextFieldDelegate {
- func editingChangedTextField(_ sender: SetupTextField, forEvent event: UIEvent) -> Void
- func primaryActionTriggered(_ sender: SetupTextField, forEvent event: UIEvent) -> Void
- }
- @IBDesignable class SetupTextField: UIView {
-
- private var currentDefaultText: String?
-
- //MARK: Control Properties
- @IBInspectable var showIcon: UIImage? {
- didSet {
- self.icon.image = showIcon?.withTint(Colors.white())
- self.icon.isHidden = false
- self.textBackground.frame = CGRect(x: 40, y: 0, width: self.frame.width - 40, height: self.frame.height)
- self.textField.frame = CGRect(x: 45, y: 5, width: 230, height: 30)
- }
- }
-
- @IBInspectable var placeholder: String? {
- didSet {
- let foregroundColor = [NSAttributedString.Key.foregroundColor: UIColor.lightGray] //THREEMA_COLOR_PLACEHOLDER
- self.textField.attributedPlaceholder = NSAttributedString(string: placeholder!, attributes: foregroundColor)
- self.textField.accessibilityLabel = placeholder
- }
- }
-
- @IBInspectable var defaultText: String? {
- didSet {
- self.currentDefaultText = defaultText
- }
- }
-
- @IBInspectable var capitalization: Int = 0 {
- didSet {
- if let type = UITextAutocapitalizationType(rawValue: capitalization) {
- self.textField.autocapitalizationType = type
- }
- }
- }
-
- @IBInspectable var keyboardType: Int = 0 {
- didSet {
- if let type = UIKeyboardType(rawValue: keyboardType) {
- self.textField.keyboardType = type
- }
- }
- }
- @IBInspectable var returnKey: Int = 0 {
- didSet {
- if let type = UIReturnKeyType(rawValue: returnKey) {
- self.textField.returnKeyType = type
- }
- }
- }
-
- @IBInspectable var secureTextEntry: Bool = false {
- didSet {
- self.textField.isSecureTextEntry = secureTextEntry
- }
- }
-
- var text: String? {
- get {
- return self.textField.text
- }
- set {
- self.textField.text = newValue
- }
- }
-
- override var isFirstResponder: Bool {
- get {
- return self.textField.isFirstResponder
- }
- }
-
- //MARK: delegate control events
-
- weak var delegate: SetupTextFieldDelegate?
-
- @objc func editingChanged(_ sender: UITextField, forEvent event: UIEvent) {
- self.delegate?.editingChangedTextField(self, forEvent: event)
- }
-
- @objc private func touchDown(_ sender: UITextField, forEvent event: UIEvent) {
- guard let current = self.currentDefaultText, let currentText = sender.text, currentText.count == 0 else {
- return
- }
- sender.text = current
- }
-
- @objc private func primaryActionTriggered(_ sender: UITextField, forEvent event: UIEvent) {
- self.delegate?.primaryActionTriggered(self, forEvent: event)
- }
-
- //MARK: Initialization
-
- override init(frame: CGRect) {
- super.init(frame: frame)
- self.setup()
- }
-
- required init?(coder aDecoder: NSCoder) {
- super.init(coder: aDecoder)
- self.setup()
- }
-
- @discardableResult
- override func becomeFirstResponder() -> Bool {
- return self.textField.becomeFirstResponder()
- }
-
- @discardableResult
- override func resignFirstResponder() -> Bool {
- return self.textField.resignFirstResponder()
- }
-
- private let icon: UIImageView = {
- let icon = UIImageView()
- icon.isHidden = true
- icon.frame = CGRect(x: 11, y: 11, width: 18, height: 18)
- return icon
- }()
-
- private let textBackground: UIView = {
- let background = UIView()
- background.alpha = 0.1
- background.backgroundColor = .white
- background.layer.borderWidth = 0.5
- background.layer.borderColor = UIColor(red:1.0, green:1.0, blue:1.0, alpha:0.1).cgColor
- background.layer.cornerRadius = 3
- return background
- }()
-
- private let textField: UITextField = {
- let field = UITextField()
- field.textColor = UIColor.white
- field.tintColor = UIColor.white
- field.backgroundColor = .clear
- field.borderStyle = .none
- field.textAlignment = .left
- field.font = UIFont.systemFont(ofSize: 16.0, weight: .light)
- field.autocorrectionType = UITextAutocorrectionType.no
- field.spellCheckingType = UITextSpellCheckingType.no
- field.keyboardAppearance = UIKeyboardAppearance.dark
- return field
- }()
-
- //MARK: Private Methods
-
- private func setup() {
- self.backgroundColor = UIColor.clear
-
- let background = UIView(frame: CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height))
- background.backgroundColor = UIColor.clear
- background.layer.borderWidth = 0.5
- background.layer.borderColor = UIColor(red:1.0, green:1.0, blue:1.0, alpha:0.1).cgColor
- background.layer.cornerRadius = 3
-
- self.textBackground.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height)
- self.textField.frame = CGRect(x: 5, y: 5, width: 270, height: 30)
- self.textField.addTarget(self, action: #selector(editingChanged), for: .editingChanged)
- self.textField.addTarget(self, action: #selector(touchDown), for: .touchDown)
- self.textField.addTarget(self, action: #selector(primaryActionTriggered), for: .primaryActionTriggered)
- self.textField.delegate = self
- self.textField.tintColor = Colors.mainThemeDark()
- self.addSubview(background)
- self.addSubview(self.icon)
- self.addSubview(textBackground)
- self.addSubview(self.textField)
- }
- }
- extension SetupTextField: UITextFieldDelegate {
-
- func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
-
- // Check if it has lowercase characters
- if self.capitalization != 0 && string.rangeOfCharacter(from: CharacterSet.lowercaseLetters) != nil {
- if let textCurrent = textField.text,
- let rangeCurrent = Range<String.Index>(range, in: textCurrent) {
-
- // Get current cursor position
- let selectedTextRangeCurrent = textField.selectedTextRange
-
- // Replace lowercase character with uppercase character
- textField.text = textField.text?.replacingCharacters(in: rangeCurrent, with: string.uppercased())
-
- if let selectedTextRangeCurrent = selectedTextRangeCurrent {
- // Set current cursor position, if cursor position + 1 is valid
- if let newPosition = textField.position(from: selectedTextRangeCurrent.start, offset: 1) {
- textField.selectedTextRange = textField.textRange(from: newPosition, to: newPosition)
- }
- }
- }
- return false
- }
-
- return true;
- }
- }
|