How to make a UITextField selectable but not editable? - ios

I hope that user can copy and paste the text but not edit them. I use a delegate UITextField method to implement this:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
return NO;
}
In this way although the text is selectable and not editable, but when you select the text, the keyboard always shows up, which is a little bit annoying cause you can not edit the text. So is there anyway to make text selectable and not editable, without showing the keyboard?

What you need is to allow the control to receive all user interaction events. So, do not return NO from textFieldShouldBeginEditing. Instead, do the following:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
return textField != _yourReadOnlyTextField;
}
This will allow the user to select the text and also to select options like Cut, Copy and Define from the popup menu.
UPDATE:
Also, for completeness, you may want to prevent the keyboard from showing up at all on readyonly textfields. So based on the accepted answer to this question: uitextfield hide keyboard?, you may want to add:
- (void)viewDidLoad
{
// Prevent keyboard from showing up when editing read-only text field
_yourReadOnlyTextField.inputView = [[UIView alloc] initWithFrame:CGRectZero];
}

Update for Swift users:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
return textField != self.yourReadOnlyTextField;
}
and when the view loads
override func viewDidLoad() {
super.viewDidLoad()
self.selfCodeEdit.inputView = UIView.init();
}

You should implement another UITextField's delegate method:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
return NO;
}
//UPDATE Also, there is a questions like this here How to disable UITextField's edit property?.

if you have more then one textFields you can do in this way
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if textField == firstTextField || textField == secondTextField {
return false
}
return true
}

You can do that directly through the storyboard.
Select your UITextView then in your Attributes inspector.
You have some behavior params :

Related

Obj-c - Disable uibutton if textView is empty?

I'm trying to disable my uibutton if a UITextView is empty with the below code. The button disables if the field is empty, however, when I use the below, the button doesn't seem to "enable" if the text view has values in it? Any idea why this is?
Edit/Update: I've updated my code below (problem half solved). In this scenario, my send button is disabled if the text view is empty. However, once I have text in my view and I press send, if I hit send a second time (and the text view is once again empty), send button is no longer disabled. Why is this?
- (void)viewDidLoad {
[super viewDidLoad];
self.sendButton.userInteractionEnabled = NO;
}
- (void)textViewDidChange:(UITextView *)textView {
self.sendButton.userInteractionEnabled = (textView.text.length > 0);
}
You have to implement UITextView delegate:
- (void)textViewDidChange:(UITextView *)textView {
sendButton.userInteractionEnabled = (textView.text.length > 0);
}
you must be setting text in self.replyField after viewDidLoad is executed.
try executing below code whenever you change the value in self.replyField:
if (self.replyField.text.length > 0) {
sendButton.userInteractionEnabled = YES;
}
else {
sendButton.userInteractionEnabled = NO;
}
you can use isEnabled instead of userInteractionEnabled
you should implement below delegate method for enabling and disabling button based on text values
optional func textField(_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool {
}

IOS: textField now formatting entry as a phone number throughout app

I used the method
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
to format some phone numbers that are typed into a textfield.
I have now noticed that my login screen which uses textFields has suddenly begun formatting the userid and password as phone numbers as well making it impossible to log in.
Can I infer from this that if you use the above method, it affects all textFields in your app?
If so, is there a workaround to only use it for phone numbers?
Thanks for any suggestions
I have 2 suggestions.
Use textFieldShouldBeginEditing to set a class var, here called "activeTextField", then in shouldChangeCharactersInRange compare with your text field
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
activeTextField = textField
return true
}
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if (textField == textPhono) {
//do your logic
}
}
Mark all of your phone text fields with especific tag for phones, then compare tag in "shouldChangeCharactersInRange"

Setting UITextField not editable or editable

I want to know how to disable UITextField, i.e I placed a UIButton in the frame of UITextField for design purpose.
When I tap my button in UITextField the keyboard appears, but I don't want the keyboard to be displayed!
Here is my code so far:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
return textField !=textfiled1;
return textField !=textfiled2;
}
You can enable or disable user interaction on the textfield using this property:
textField.userInteractionEnabled = NO;
In Swift 5
textField.isUserInteractionEnabled = false
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
return NO;
}
You can use this too
Accepted answer in Swift 4:
textField.isUserInteractionEnabled = false
I think your UIButton is not on UITextField. so bringToFromView first then your UIButton selector method called first. Because compiler check Event in hierarchy. if first control response the event then it wan't looking for next.
I have tested your scenario and its working fine at my end.
swift version of my Obj-C Answer
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
return false
}
Use the below property.
textField.userInteractionEnabled = NO;
you can achieve this with the help of:
If you want to disable editing you can do this
textField.editable = NO;
and if you want to make it editable again you can do this
textField.editable = YES;

Disable editing only for UITextField?

I tried the following ways:
properties enabled and "user interaction enabled";
method textFieldShouldBeginEditing:.
But they disable all the possible actions with text field. I need to disable the editing only but allow users to copy text value. How to implement this?
Implement and set the following UITextFieldDelegate:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
return NO;
}
This makes the field not editable while still retaining that select/copy functionality. The editing property is readonly and unrelated.
This might be helpful for you. Try
YourTextField.editing = NO;
Keep the enabled property on, and the user interaction on. Otherwise you won't be able to select the text.
set the delegate of the UITextField to the ViewController and implement :
Swift:
func textField(_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool {
return false
}
In addition to tasuhka's response, make sure
YourTextField.selectable = YES;

I need to validate two uitextfields differently. How do I do this?

One text field only takes alphabet characters and the other one is alphanumeric. I have defined shouldChangeCharactersInRange in my ViewController for one of them. Now I don't know where I'm supposed to define the logic for other uitextfield.
Can someone help me understand how this should work?
If they both have the same delegate, then they would both be validated in the same shouldChangeCharactersInRange method. You need to put an if-else clause in that method to check which text field is the sender. You need IBOutlets for the two text fields so you can do the comparison.
You have a couple options. If you have created iVars for your text fields, checking which one is calling shouldChangeCharactersInRange is as simple as ==. Below I've also shown that another option would be to assign tags to the text fields and check the tag of the sending text field.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
//Your first option
if (textField == myFirstTextField) {
//
}else{
//
}
//another option, if you don't want to create iVars you can assign tags to your text fields and do this
if (textField.tag == 99) {
//
}else{
//
}
}

Resources