【问题标题】:UiTextField: canPerformAction, caretRectForPosition, selectionRectsForRange are not called (Swift 3)UiTextField:canPerformAction、caretRectForPosition、selectionRectsForRange 未被调用(Swift 3)
【发布时间】:2017-03-11 13:20:26
【问题描述】:

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

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

我还尝试将 override 放在函数定义的前面。但是 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)
    }
}

【问题讨论】:

    标签: ios uitextfield swift3 ios10


    【解决方案1】:

    问题是您的方法在 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]
    

    【讨论】:

    • 很高兴为您提供帮助。请不要忘记接受可以解决您问题的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-12
    • 1970-01-01
    • 2015-05-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多