rgamber
rgamber

Reputation: 5849

Disable cursor and copy/paste in UITextView (swift)

I have a UITextField for which I am using UIPickerView as its inputView. The user can select a value from the picker, and the selected value gets populated into my TextInput.
This arrangement works fine, but with the following issues:

1) I want to disable the cursor that still shows in the UITextField.
I tried disabling the UITextField, but then it does not respond to touches and then the UIPickerView does not show - which makes it useless.
2) Since the picker is shown and the keyboard is not wen the user taps on the text-field, the user cannot type anything, but still can paste text copied from else where by long pressing. How can I disable this?

I am not able to find the relevant information online. Should I be using a Label or a Button for this instead of the UITextInput?

Upvotes: 11

Views: 12834

Answers (5)

Piyush Sanepara
Piyush Sanepara

Reputation: 1417

SWIFT 4

Create TextField.swift file & change import Foundation to import UIKit & add following code in TextFeild.swift file

import UIKit

class TextFeild: UITextField {

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        // write code here what ever you want to change property for textfeild. 
    }

    override func caretRect(for position: UITextPosition) -> CGRect {
        return CGRect.zero
    }

    override func selectionRects(for range: UITextRange) -> [Any] {
        return []
    }

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

Go to main.storyboard, select that textfield & change its custom class to TextField

Xcode Image

Upvotes: 4

brandonscript
brandonscript

Reputation: 72885

Totally silly hack, but if you set the text field's tint color in the UIView section of the Interface Builder property inspector to match the background color, the cursor will appear invisible:

Upvotes: 2

mr.sosa
mr.sosa

Reputation: 691

Like TonyMkenu said, you need to subclass UITextField and then implement the methods he has above. Here's the Swift for those of you who don't know Objective C:

override func caretRectForPosition(position: UITextPosition!) -> CGRect {
    return CGRect.zeroRect
}

override func selectionRectsForRange(range: UITextRange) -> [AnyObject] {
    return []
}

override func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool {
    // Disable copy, select all, paste
    if action == Selector("copy:") || action == Selector("selectAll:") || action == Selector("paste:") {
        return false
    }
    // Default
    return super.canPerformAction(action, withSender: sender)
}

Upvotes: 8

TonyMkenu
TonyMkenu

Reputation: 7667

I think the easy way is to make it with a button instead UITextField

Sorry - this is not for Swift it's for Obj-C but this is the idea:

To do what you want with UITextField you have to subclass the UITextField and try to use this code to disable/hide caret and input (copy/paste)

- (CGRect) caretRectForPosition:(UITextPosition*) position
{
    return CGRectZero;
}

- (NSArray *)selectionRectsForRange:(UITextRange *)range
{
    return nil;
}

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
    if (action == @selector(copy:) || action == @selector(selectAll:) || action == @selector(paste:))
    {
        returnNO;
    }
    return [super canPerformAction:action withSender:sender];
}

example from here: http://b2cloud.com.au/tutorial/disabling-the-caret-and-text-entry-in-uitextfields/

Anyway... this is a "functional" example: https://github.com/hackiftekhar/IQDropDownTextField

Upvotes: 9

user3386109
user3386109

Reputation: 34829

The UITextField delegate can implement the textFieldShouldBeginEditing method. If that method always returns NO, then the cursor will never appear and the long press won't be allowed.

When the method is called, you can display the UIPickerView. However, the UIPickerView cannot be an inputView. It would need to be the child of a standard UIView that you animate in from the bottom. Or you could just use the hidden property of the UIView to hide/show the view as needed.

Upvotes: 1

Related Questions