我们能否在SwiftUI中禁用TextField的复制/粘贴选项?

12

我希望禁用SwiftUI中的TextField复制/粘贴选项。如何实现?


我认为目前在SwiftUI中无法实现此功能,因此您应该使用UITextField并遵循UIViewRepresentable协议。 - Mac3n
2个回答

5

以下方法适用于我:

  • 使用UITextField符合UIViewRepresentable协议。
import SwiftUI

struct ContentView: View {
    
    @State private var text = ""
    
    var body: some View {
        VStack {
            Text(text)
            UITextFieldViewRepresentable(text: $text) // Using it
                .frame(height: 44)
                .border(.red)
        }
    }
}

// MARK: UITextFieldViewRepresentable
struct UITextFieldViewRepresentable: UIViewRepresentable {
    
    @Binding var text: String
    typealias UIViewType = ProtectedTextField
    
    
    func makeUIView(context: Context) -> ProtectedTextField {
        let textField = ProtectedTextField()
        textField.delegate = context.coordinator
        return textField
    }
    
    // From SwiftUI to UIKit
    func updateUIView(_ uiView: ProtectedTextField, context: Context) {
        uiView.text = text
    }
    
    // From UIKit to SwiftUI
    func makeCoordinator() -> Coordinator {
        return Coordinator(text: $text)
    }
    
    class Coordinator: NSObject, UITextFieldDelegate {
        @Binding var text: String
        
        init(text: Binding<String>) {
            self._text = text
        }
        
        func textFieldDidChangeSelection(_ textField: UITextField) {
            text = textField.text ?? ""
        }
    }
}

// Custom TextField with disabling paste action
class ProtectedTextField: UITextField {
    override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        
        if action == #selector(paste(_:)) {
            return false
        }
        return super.canPerformAction(action, withSender: sender)
    }
}

2
使用UIViewRepresentable类制作包装器类,如下所示。
import SwiftUI

struct CustomeTextField: View {

    @State var textStr = ""


    var body: some View {
        VStack(spacing: 10) {
            Text("This is textfield:")
                .font(.body)
                .foregroundColor(.gray)

            TextFieldWrapperView(text: self.$textStr)
                .background(Color.gray)
                .frame(width: 200, height: 50)
        }
        .frame(height: 40)
    }
}


struct TextFieldWrapperView: UIViewRepresentable {

    @Binding var text: String

    func makeCoordinator() -> TFCoordinator {
        TFCoordinator(self)
    }
}

extension TextFieldWrapperView {


    func makeUIView(context: UIViewRepresentableContext<TextFieldWrapperView>) -> UITextField {
        let textField = UITextField()
        textField.delegate = context.coordinator
        return textField
    }


    func updateUIView(_ uiView: UITextField, context: Context) {

    }
}

class TFCoordinator: NSObject, UITextFieldDelegate {
    var parent: TextFieldWrapperView

    init(_ textField: TextFieldWrapperView) {
        self.parent = textField
    }

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

很好,这非常有用,可以在用户剪贴板上同时拥有图像时拦截粘贴操作。 - Lucas van Dongen
为什么 canPerformAction 没有被调用? - Muhammad Abbas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接