如何在Swift的TextField中禁用Pasting?

时间:2015-04-12 23:55:12

标签: swift uitextfield paste

我有一个带有数字键盘的TextField,只有当数字包含数字时,该功能才会运行。

用户崩溃应用的唯一选择是他是否会在TextField中粘贴字母,然后点击确定。

如何在TextField中禁用粘贴?

14 个答案:

答案 0 :(得分:41)

我同意Leonardo Savio Dabus,如果我是你,我将使用字符串检查并发出警告,这会让事情变得更容易。但是,如果禁用粘贴选项是一个非常想要放入应用程序的奇特功能,那么您需要做更多的工作。我将提供以下步骤。

步骤1:您需要创建另一个扩展UITextField的类。在此示例中,我创建了CustomUITextField

import Foundation
import UIKit  // don't forget this

class CustomUITextField: UITextField {
    override func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool {
        if action == "paste:" {
            return false
        }        
        return super.canPerformAction(action, withSender: sender)
    }
}

第2步:使用ViewController连接故事板。您需要像正常情况一样声明IBOutlet

@IBOutlet var textFieldA: CustomUITextField?

@IBOutlet旁边的圆圈连接到情节提要中的textField。那么,这很重要且容易被忽略:

  • 转到您的故事板
  • 单击目标TextField
  • 选择Identity Inspector(第3个)
  • 将班级更改为CustomUITextField

下面提供了快照。

enter image description here

那就是它,希望这有效。

<强>信用卡:

主要参考https://teamtreehouse.com/forum/disable-paste-in-uitextfielduitextview-swift

如果您想了解更多关于canPerformAction方法的行为,尽管是Objective-C版本,但是这些概念是共享的:How can I detect that a user has tapped a formatting button in a UIMenuController?

答案 1 :(得分:41)

对于 Swift 3 ,它已更改为:

override public func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
    if action == #selector(copy(_:)) || action == #selector(paste(_:)) {
        return false
    }

    return true
}

答案 2 :(得分:19)

Swift3

最近添加了

UIResponder​Standard​Edit​Actions(iOS 10.0+),通过它我们可以安全地检查操作是否“粘贴”。

SELECT ID, COL1, COL2 FROM MYTABLE WHERE (? BETWEEN COL1 AND COL2)

答案 3 :(得分:16)

详细

  • Xcode 9.1,Swift 4
  • Xcode 10.2(10E125),Swift 5

解决方案1 ​​

// class TextField: UITextField
extension UITextField {

    open override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        return action == #selector(UIResponderStandardEditActions.cut) || action == #selector(UIResponderStandardEditActions.copy)
    }
}

解决方案1用法

let textField = UITextField(frame: CGRect(x: 50, y: 120, width: 200, height: 50))
textField.borderStyle = .roundedRect
view.addSubview(textField)

解决方案2

enum ResponderStandardEditActions {
    case cut, copy, paste, select, selectAll, delete
    case makeTextWritingDirectionLeftToRight, makeTextWritingDirectionRightToLeft
    case toggleBoldface, toggleItalics, toggleUnderline
    case increaseSize, decreaseSize

    var selector: Selector {
        switch self {
        case .cut:
            return #selector(UIResponderStandardEditActions.cut)
        case .copy:
            return #selector(UIResponderStandardEditActions.copy)
        case .paste:
            return #selector(UIResponderStandardEditActions.paste)
        case .select:
            return #selector(UIResponderStandardEditActions.select)
        case .selectAll:
            return #selector(UIResponderStandardEditActions.selectAll)
        case .delete:
            return #selector(UIResponderStandardEditActions.delete)
        case .makeTextWritingDirectionLeftToRight:
            return #selector(UIResponderStandardEditActions.makeTextWritingDirectionLeftToRight)
        case .makeTextWritingDirectionRightToLeft:
            return #selector(UIResponderStandardEditActions.makeTextWritingDirectionRightToLeft)
        case .toggleBoldface:
            return #selector(UIResponderStandardEditActions.toggleBoldface)
        case .toggleItalics:
            return #selector(UIResponderStandardEditActions.toggleItalics)
        case .toggleUnderline:
            return #selector(UIResponderStandardEditActions.toggleUnderline)
        case .increaseSize:
            return #selector(UIResponderStandardEditActions.increaseSize)
        case .decreaseSize:
            return #selector(UIResponderStandardEditActions.decreaseSize)
        }
    }

}

class TextField: UITextField {

    var allowedActions: [ResponderStandardEditActions] = [] {
        didSet {
            if !allowedActions.isEmpty && !notAllowedActions.isEmpty {
                notAllowedActions = []
            }
        }
    }

    var notAllowedActions: [ResponderStandardEditActions] = [] {
          didSet {
            if !allowedActions.isEmpty && !notAllowedActions.isEmpty {
                allowedActions = []
            }
        }
    }

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

        if !allowedActions.isEmpty {
            return allowedActions.map{ $0.selector }.contains(action)
        }

        if !notAllowedActions.isEmpty {
            return !notAllowedActions.map{ $0.selector }.contains(action)
        }
        return super.canPerformAction(action, withSender: sender)
    }
}

解决方案2用法

let textField = TextField(frame: CGRect(x: 50, y: 50, width: 200, height: 50))
textField.borderStyle = .roundedRect
view.addSubview(textField)
textField.allowedActions = [.copy, .cut]
//textField.notAllowedActions = [.copy, .cut]

答案 4 :(得分:4)

您可以为UITextField创建扩展程序并覆盖canPerformAction

override public func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool {
        return (action != "paste:") 
}

答案 5 :(得分:4)

在实际的swift版本(2.2转到3.0)中,此功能代码必须重构为:

override public func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool {
    if action == #selector(NSObject.copy(_:)) || action == #selector(NSObject.paste(_:)) {
        return false
    }

    return true
}

答案 6 :(得分:4)

迅速4.1,此代码可与ViewController一起正常工作。

1)禁用所有选项(复制,粘贴,删除...等)

extension UITextField {

    open override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        return false
    }
}

2)启用特定选项(选择,全选...等等)

extension UITextField {

open override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
    return action == #selector(UIResponderStandardEditActions.select(_:)) || action == #selector(UIResponderStandardEditActions.selectAll(_:))
}

答案 7 :(得分:3)

您可以将IBAction附加到文本字段的已发送事件(编辑已更改),以便在键入时从字符串中过滤非数字:

@IBAction func changedTextAction(sender: UITextField) {
    sender.text = String(Array(sender.text).map{String($0)}.filter{ $0.toInt() != nil }.map{Character($0)} )
}

答案 8 :(得分:1)

class CustomUITextField: UITextField {
    override public func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        if action == #selector(cut(_:)) ||
           action == #selector(copy(_:)) ||  
           action == #selector(UIResponderStandardEditActions.paste(_:)) || 
           action == #selector(UIResponderStandardEditActions.select(_:)) || 
           action == #selector(UIResponderStandardEditActions.selectAll(_:)) || 
           action == #selector(UIResponderStandardEditActions.delete(_:)) ||  
           action == #selector(UIResponderStandardEditActions.makeTextWritingDirectionLeftToRight(_:)) ||  
           action == #selector(UIResponderStandardEditActions.makeTextWritingDirectionRightToLeft(_:)) || 
           action == #selector(UIResponderStandardEditActions.toggleBoldface(_:)) || 
           action == #selector(UIResponderStandardEditActions.toggleItalics(_:)) || 
           action == #selector(UIResponderStandardEditActions.toggleUnderline(_:)) || 
           action == #selector(UIResponderStandardEditActions.increaseSize(_:)) || 
           action == #selector(UIResponderStandardEditActions.decreaseSize(_:)) 
        {
             return false
        };
        return true
    }
}

答案 9 :(得分:1)

我为textField创建了一个自定义类。我想在文本字段上启用/禁用操作时处理了这种情况。您可以根据自己的要求自定义代码。设置isActionsEnabled true / false以启用/禁用textfield上的操作。

喜欢使用

  

返回super.canPerformAction(action,withSender:sender)

而不是

  

返回true

因为在某些情况下返回true可能会导致崩溃。

这是我的代码,

open class MyTextFieldEffect : UITextField {

    var isActionsEnabled = true {
        didSet {
            reloadInputViews()
        }
    }

override open func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        /* disable particular actions
        if (action == #selector(paste(_:)) || action == #selector(copy(_:)) || action == #selector(select(_:)) || action == #selector(cut(_:)) || action == #selector(delete(_:)) || action == #selector(replace(_:withText:))  || action == #selector(select(_:))  || action == #selector(selectAll(_:)) || action == #selector(insertText(_:)) || action == #selector(draw(_:))) && !isActionsEnabled {
            return false
        }
        return super.canPerformAction(action, withSender: sender)
                                           */

       //disable all actions
        if !isActionsEnabled {
            return false
        }

        return super.canPerformAction(action, withSender: sender)
    }
}

答案 10 :(得分:1)

快速5

如果您想阻止应用程序中每个文本字段的粘贴操作

extension UITextField {
    override open func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        return action == #selector(UIResponderStandardEditActions.paste(_:)) ?
            false : super.canPerformAction(action, withSender: sender)
    }
}

编辑

如果要阻止将选择器作为输入视图的文本字段的粘贴操作,请添加guard,如下所示:

extension UITextField {
    override open func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        guard inputView != nil else { return super.canPerformAction(action, withSender: sender) }

        return action == #selector(UIResponderStandardEditActions.paste(_:)) ?
            false : super.canPerformAction(action, withSender: sender)
    }
}

警告:第二种解决方案将允许用户粘贴在数字字段上。

答案 11 :(得分:0)

使用代码进行小编辑,因为当您尝试使用剪切或其他任何功能时,应用程序将崩溃。以下代码在swift 3上测试并且运行良好

override public func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        if action == #selector(copy(_:)) || action == #selector(paste(_:)) {
            return false
        }
        return super.canPerformAction(action, withSender: sender)
    }

答案 12 :(得分:0)

如果要在TEXTFIELD上打开日期选择器或选择器视图,请单击下面的代码。

在您的课程中添加以下两个方法。

//Hide Menu View
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {

    if YOURTEXTFIELD.isFirstResponder {
        DispatchQueue.main.async(execute: {
            (sender as? UIMenuController)?.setMenuVisible(false, animated: false)
        })
        return false
    }

    return super.canPerformAction(action, withSender: sender)
}

//必须实施

func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
            return false
}

答案 13 :(得分:0)

我确实使用了这段代码。工作正常。

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

    if YOURTEXTFIELD.isFirstResponder {
        DispatchQueue.main.async(execute: {
            (sender as? UIMenuController)?.setMenuVisible(false, animated: false)
        })
        return false
    }

    return super.canPerformAction(action, withSender: sender)
}