I have done a lot of research and ran out of ideas to solve this.
Can someone please tell me why the canPerformAction
, caretRectForPosition
, selectionRectsForRange
are not called for the MyTextField Object.
I have read that these functions are only called if the class inherits from UITextField
and not from UITextFieldDelegate
.
I also tried to put override in front of the function definition. But Swift 3 does not like this:
Method does not override any method from its superclass ViewController.swift
This should not be a problem because the override can be removed like stated here: Swift protocols: method does not override any method from its superclass
import Foundation
import UIKit
class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate
//, UITextFieldDelegate
{
@IBOutlet var my_text_field: MyTextField!
@IBOutlet var my_text_field_delegate: MyTextFieldDelegate!
var pickerView = UIPickerView()
var pickOption = ["test1",
"test2",
"test3",
"test3",
"test4",
"test5"]
override func viewDidLoad()
{
super.viewDidLoad()
//let pickerView = UIPickerView()
pickerView.delegate = self
pickerView.showsSelectionIndicator = true
my_text_field.inputView = pickerView
my_text_field_delegate.inputView = pickerView
//my_text_field_delegate.delegate = self
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return pickOption.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return pickOption[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
my_text_field_delegate.text = pickOption[row]
print("ViewController picker hit \(row)")
}
// number of columns to display
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
}
/////////////////////////////////////////////////////
class MyTextField: UITextField//, UITextFieldDelegate
{
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
// this is only needed if class inherits from UITextFieldDelegate
//delegate = self
}
required override init(frame: CGRect) {
super.init(frame: frame)
// this is only needed if class inherits from UITextFieldDelegate
//delegate = self
}
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// why these functions are not called?
// they should because the class inherits form UITextField and not from UITextFieldDelegate
func caretRectForPosition(position: UITextPosition!) -> CGRect {
print("MyTextField caretRectForPosition")
return CGRect.zero
}
func selectionRectsForRange(range: UITextRange) -> [AnyObject] {
print("MyTextField selectionRectsForRange")
return []
}
func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool {
print("MyTextField canPerformAction")
UIMenuController.shared.isMenuVisible = false
if action == #selector(UIResponderStandardEditActions.paste(_:)) {
print("no paste")
return false
}
return super.canPerformAction(action, withSender:sender)
}
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// these functions are only called if class inherits from UITextFieldDelegate
func textFieldDidBeginEditing(_ textField: UITextField) {
print("MyTextField focused")
}
func textFieldDidEndEditing(_ textField: UITextField) {
print("MyTextField lost focus")
}
func textFieldShouldBeginEditing(_ state: UITextField) -> Bool {
print("MyTextField textFieldShouldBeginEditing")
return true
}
}
///////////////////////////////////////////////////////////
class MyTextFieldDelegate: UITextField, UITextFieldDelegate
{
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
delegate = self
createBorder()
}
required override init(frame: CGRect) {
super.init(frame: frame)
delegate = self
createBorder()
}
func createBorder(){
let border = CALayer()
let width = CGFloat(2.0)
border.borderColor = UIColor(red: 55/255, green: 78/255, blue: 95/255, alpha: 1.0).cgColor
border.frame = CGRect(x: 0, y: self.frame.size.height-width, width: self.frame.size.width, height: self.frame.size.height)
border.borderWidth = width
self.layer.addSublayer(border)
self.layer.masksToBounds = true
//print("border created")
}
func textFieldDidBeginEditing(_ textField: UITextField) {
print("MyTextFieldDelegate focused")
}
func textFieldDidEndEditing(_ textField: UITextField) {
print("MyTextFieldDelegate lost focus")
}
func textFieldShouldBeginEditing(_ state: UITextField) -> Bool {
print("MyTextFieldDelegate textFieldShouldBeginEditing")
return true
}
// these functions are not called
func caretRectForPosition(position: UITextPosition!) -> CGRect {
print("MyTextFieldDelegate caretRectForPosition")
return CGRect.zero
}
func selectionRectsForRange(range: UITextRange) -> [AnyObject] {
print("MyTextFieldDelegate selectionRectsForRange")
return []
}
func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool {
print("MyTextFieldDelegate canPerformAction")
// Disable copy, select all, paste
if action == #selector(UIResponderStandardEditActions.copy(_:)) ||
action == #selector(UIResponderStandardEditActions.selectAll(_:)) ||
action == #selector(UIResponderStandardEditActions.paste(_:))
{
return false
}
// Default
return super.canPerformAction(action, withSender: sender)
}
}
The problem is that your methods do not have the proper signature under Swift 3.
Example:
func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool {
should be:
func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
See the reference documentation for the other methods and update your code to use the proper signatures.
func caretRect(for position: UITextPosition) -> CGRect
func selectionRects(for range: UITextRange) -> [Any]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With