Swift'de bir TextField'e Yapıştırma nasıl devre dışı bırakılır?

Sayısal tuş takımına sahip bir TextField kodum var ve işlev yalnızca sayı içeriyorsa çalışır.

Kullanıcının uygulamayı çökmesine neden olacak tek seçenek, TextField 'a harfleri yapıştırması ve Tamam'ı tıklamasıdır.

TextField’e yapıştırmayı nasıl devre dışı bırakabilirim?

25
Devre dışı bırakma. Sayıların yapıştırılmasını önlemek için metin alanı temsilci yöntemlerini kullanın.
katma yazar matt, kaynak
Senin için kodunu yazmayacağım. UITextFieldDelegate'e bakın, göreceksiniz. Kitabımda benzer bir şey tartıştım: apeth.com/iOSBook/…
katma yazar matt, kaynak
Nasıl yaparım?
katma yazar Eliko, kaynak

12 cevap

Swift 3 için şu şekilde değiştirildi:

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

    return true
}
34
katma
Sadece her şeyi değil kesim seçeneğini devre dışı bırakmak istersem?
katma yazar a4arpan, kaynak
Teşekkürler mükemmel cevap
katma yazar Mehul, kaynak
"True" ifadesi bazı işlemlerde çökmeye neden olabilir, lütfen tüm işlemleri kontrol edin. @Andrey Gordeev
katma yazar Pramod More, kaynak
@ a4arpan Şunlardan birini kullanın: "action == #selector (cut (_ :))" veya "action == #selector (cut)" veya "action == #selector (UIResponderStandardEditActions.cut)"
katma yazar RowanPD, kaynak

Leonardo Savio Dabus ile aynı fikirdeyim, eğer siz yerdeysem tel kontrolü kullanırım ve sadece bir uyarı veririm, işleri kolaylaştırır. AMA, yapıştırma seçeneğini devre dışı bırakmak gerçekten uygulamanıza eklemek istediğiniz süslü bir özellikse, o zaman daha fazla iş yapmanız gerekir. Aşağıdaki adımları vereceğim.

1. Adım: UITextField öğesini genişleten başka bir sınıf oluşturmanız gerekir. Bu örnekte, CustomUITextField 'ımı yaptım.

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)
    }
}

Adım 2: Film şeridini ViewController'ınıza bağlayın. Normal durumda olduğu gibi bir IBOutlet bildirmeniz gerekir:

@IBOutlet var textFieldA: CustomUITextField?

@IBOutlet öğesinin yanındaki daireyi film şeridindeki textField öğesine bağlayın. O zaman, bu önemli ve ihmal edilmesi kolaydır:

  • Film şeridinize gidin
  • Hedef TextField’i tıklayın
  • Kimlik Denetçisini Seçin (üçüncüsü)
  • Sınıfı CustomUITextField olarak değiştirin

Hızlı anlık görüntü aşağıda verilmiştir.

enter image description here

İşte bu, umarım işe yarar.

Kredi:

Mainly reference from https://teamtreehouse.com/forum/disable-paste-in-uitextfielduitextview-swift

If you want to know more about the behavior of canPerformAction method, though isobjective-cversion, but the concepts are shared: How can I detect that a user has tapped a formatting button in a UIMenuController?

33
katma
mükemmel cevap.! Muhteşem.
katma yazar srivas, kaynak
Swift3 için: sınıf NoPasteUITextField: UITextField {func canPerformAction işlevini geçersiz kıl (_ action: Seçici, gönderici gönderen ile: Herhangi bir?) -> Bool {eğer eylem == #selector (UIResponderStandardEditActions.paste (_)) (eylem, Göndericiyle birlikte: gönderen)}}
katma yazar sfresko, kaynak
mükemmel! Teşekkürler
katma yazar Niib Fouda, kaynak

For Swift3

UIResponder​Standard​Edit​Actions has been added recently (iOS 10.0+) through which we can safely check if action is "paste" or not.

import UIKit

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

ayrıntılar

xCode 9.1, Swift 4

1. Çözüm

// 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. Çözüm usage

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

2. Çözüm

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. Çözüm usage

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]
6
katma

Gerçek hızlı versiyonunda (2.2'ye 3.0) bu fonksiyon kodu aşağıdakilere göre düzeltilmelidir:

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

    return true
}
4
katma

Aşağıdaki gibi yazarken dizenizdeki sayıları filtrelemek için metin alanınızın Gönderilmiş Olaylarına (düzenleme değişti) bir IBAction ekleyebilirsiniz.

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

UITextField için bir uzantı oluşturabilir ve canPerformAction öğesini geçersiz kılabilirsiniz:

override public func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool {
        return (action != "paste:") 
}
3
katma
TÜM textFields uygulamasında yapıştırmayı devre dışı bırakmaz mı?
katma yazar Fyodor Volchyok, kaynak
Öyle. Bana bunun niyetin gibiydi. Olmazsa - benim kötü (ama yine de bunu yapmanın zarif bir yolu).
katma yazar zaltzy, kaynak

Swift 4.1 bu kod ViewController ile iyi çalışıyor.

1) Tüm seçenekleri devre dışı bırak (kopyala, yapıştır, sil ..... vb)

extension UITextField {

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

2) Belirli bir seçeneği etkinleştirin (seçin, selectAll ... vb.)

extension UITextField {

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

If you want to Open Date Picker or Picker view on TEXTFIELD click then below code work.

Sınıfınıza aşağıdaki iki yöntemi ekleyin.

//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)
}

//MUST Implement

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

TextField için özel bir sınıf oluşturdum. Metin alanında eylemleri etkinleştirmek/devre dışı bırakmak istediğinizde bu olayı ele aldım. Kodu, ihtiyacınıza göre özelleştirebilirsiniz. Metin alanında etkinleştirmek/devre dışı bırakmak için isActionsEnabled true/false değerini ayarlayın.

Kullanmayı tercih et

super.canPerformAction (işlem, withSender: sender) döndürme

yerine

doğru geri dön

çünkü doğru dönmek bazı durumlarda çökmeye neden olabilir.

İşte kodum

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)
    }
}
0
katma
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
}

}

0
katma

Küçük bir kodla düzenleme, çünkü kesim veya başka bir işlev kullanmaya çalıştığınızda uygulama çökecektir. Aşağıdaki kod hızlıca 3 test edilmiş ve çok iyi çalışıyor

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)
    }
0
katma