spiegel-keyman/ios/engine/KMEI/KeymanEngine/Classes/TextFieldDelegateProxy.swift

73 lines
2.8 KiB
Swift

//
// TextFieldDelegateProxy.swift
// KeymanEngine
//
// Created by Gabriel Wong on 2017-10-06.
// Copyright © 2017 SIL International. All rights reserved.
//
// Proxies delegate messages for a TextField.
// This allows the TextField to hook into these calls while allowing a developer to still
// use the delegate as normal (albeit with a different name: 'keymanDelegate')
//
// This class is required because at the time of writing, setting a UITextField as it's
// own delegate caused an infinite loop in Apple's code, repeatedly calling the selectionDidChange callback
// See: http://lists.apple.com/archives/cocoa-dev/2010/Feb/msg01391.html
import UIKit
public protocol TextFieldDelegate: UITextFieldDelegate { }
class TextFieldDelegateProxy: NSObject, UITextFieldDelegate {
weak var keymanDelegate: TextFieldDelegate?
private unowned let textField: UITextFieldDelegate
init(_ textField: TextField) {
self.textField = textField
super.init()
}
// MARK: - UITextFieldDelegate
// NOTE: Return values from the TextField hooks are ignored
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
_ = self.textField.textFieldShouldBeginEditing?(textField)
return keymanDelegate?.textFieldShouldBeginEditing?(textField) ?? true
}
func textFieldDidBeginEditing(_ textField: UITextField) {
self.textField.textFieldDidBeginEditing?(textField)
keymanDelegate?.textFieldDidBeginEditing?(textField)
}
func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
_ = self.textField.textFieldShouldEndEditing?(textField)
return keymanDelegate?.textFieldShouldEndEditing?(textField) ?? true
}
func textFieldDidEndEditing(_ textField: UITextField) {
self.textField.textFieldDidEndEditing?(textField)
keymanDelegate?.textFieldDidEndEditing?(textField)
}
@available(iOS 10.0, *)
func textFieldDidEndEditing(_ textField: UITextField, reason: UITextField.DidEndEditingReason) {
self.textField.textFieldDidEndEditing?(textField, reason: reason)
keymanDelegate?.textFieldDidEndEditing?(textField, reason: reason)
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool {
_ = self.textField.textField?(textField, shouldChangeCharactersIn: range, replacementString: string)
return keymanDelegate?.textField?(textField, shouldChangeCharactersIn: range, replacementString: string) ?? true
}
func textFieldShouldClear(_ textField: UITextField) -> Bool {
_ = self.textField.textFieldShouldClear?(textField)
return keymanDelegate?.textFieldShouldClear?(textField) ?? true
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
_ = self.textField.textFieldShouldReturn?(textField)
return keymanDelegate?.textFieldShouldReturn?(textField) ?? true
}
}