UiTextField:不调用canPerformAction,caretRectForPosition,selectionRectsForRange(Swift 3)

时间:2016-10-28 15:43:11

标签: ios uitextfield swift3 ios10

我做了很多研究并且没有想法来解决这个问题。 有人可以告诉我为什么没有为MyTextField对象调用canPerformActioncaretRectForPositionselectionRectsForRange

我已经读过,只有当类继承自UITextField而不是UITextFieldDelegate时,才会调用这些函数。

我还尝试将覆盖放在函数定义的前面。但是Swift 3不喜欢这个:

方法不会覆盖其超类ViewController.swift中的任何方法

这应该不是问题,因为可以像这里所述删除覆盖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)
    }
}

1 个答案:

答案 0 :(得分:6)

问题是你的方法在Swift 3下没有正确的签名。

示例:

func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool {

应该是:

func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {

有关其他方法的信息,请参阅参考文档,并更新代码以使用正确的签名。

func caretRect(for position: UITextPosition) -> CGRect

func selectionRects(for range: UITextRange) -> [Any]