Disable Magnifying Glass in UITextField - iphone

Is there a way to prevent the user from moving the cursor in a UITextField? I'd like it to stay at the end of the string.

This is an old question, but I was looking for an answer to the same question, and found a solution.
It is actually quite simple to prevent the user from moving the cursor. Just subclass UITextField and provide the following implementation of caretRectForPosition:
- (CGRect)caretRectForPosition:(UITextPosition *)position
{
return [super caretRectForPosition:self.endOfDocument];
}

NO SUBCLASS needed.
You Could use UITextFieldDelegate. It will make disable magnifying glass & text selection.
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
textField.userInteractionEnabled = NO;
return YES;
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
textField.userInteractionEnabled = YES;
}
NB: This is just a bypass.

There's no way to prevent them from moving the cursor. You can, however, prevent them from editing the text except at the end by implementing the
– textField:shouldChangeCharactersInRange:replacementString:
method in your text field's delegate.
Edit: you can also set userInteractionEnabled to NO so that the user can't tap the field. Call becomeFirstResponder manually so that the field gets focus since the user can't tap to focus.

I'd suggest to check the gestureRecognizers property.
You will find a lot of them in the array and might want to either remove them all or to find the ones that triggers the event you want to intercept and remove/replace it.
I used it to remove copy/paste and magnifying glass functionalities from an UITextField

I haven't check if you can disable the magnifying glass, but the recommended way to selectively disable editing behavior in a UIResponder (and thus a UITextField) is to implement canPerformAction:withSender of UIResponder.
See UIResponder documentation.
Maybe if you return "NO" for the select and selectAll action you can disable it.
Another, more brutal, way is to intercept any touch event and reset the cursor to the end.

Related

How can I make an unknown UITextField resign first responder?

My view has two UITextFields and a UISwitch. If a user is edits a textField, and then immediately touches the switch (without pressing return), the text is left as they typed it, without AutoCorrect.
If I know which textField they were typing in, I can force the autocorrect to complete by calling [textField resignFirstResponder]. But the user could be typing in either textField, so I don't know which one to call.
How can I get around this? Is there a way of detecting which textField was being used? Or something simpler I haven't thought of?
One lovely way of doing this without having to keep track of which field is active:
// This causes the current responder (eg. an input field) to resignFirstResponder and
[self.endEditing:YES];
Replace [self.view endEditing:YES] with the below one...
[[UIApplication sharedApplication] sendAction:#selector(resignFirstResponder) to:nil from:nil forEvent:nil];
The uitextfielddelegate methods are called for the textfield on which the editing is in progress. So that way you needn't be facing the problem of detecting which text field is being edited.
So implement the uitextfielddelegate methods and assign the delegate of the text field to the class where you implement the methods and handle the responses in them.
The methods which you should be interested in are:
textFieldDidEndEditing:
Tells the delegate that editing stopped for the specified text field.
- (void)textFieldDidEndEditing:(UITextField *)textField
Parameters
textField
The text field for which editing ended.
Discussion
This method is called after the text field resigns its first responder status. You can use this method to update your delegate’s state information. For example, you might use this method to hide overlay views that should be visible only while editing.
Implementation of this method by the delegate is optional.
Availability
Available in iOS 2.0 and later.
Declared In
UITextField.h
You may keep track yourself which one is the current one, by using the textFieldDidBeginEditing delegate.

Hiding keyboard when clear button is pressed in UITextField

Is there any way to hide the keyboard when a clear button of UITextField is pressed?
Yes, there is, although I suspect that doing so would violate the Apple Human Interface Guidelines.
To do so, add the following method to your view controller's implementation file. Then make the view controller into your textfield's delegate.
- (BOOL) textFieldShouldClear:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
The downside to this approach is if you ever want to prevent the textfield from clearing, your code becomes messy. Instead you might try to define a custom method and then connect it to the valueDidChange method and check for an empty value.
-(IBAction)hideKeyboardFromTextField:(id)sender{
//TODO: Check if the previous value was longer than one character to differentiate
//between backspace and clear.
//check if the editing caused the box to be empty
if([[sender value] isEqualToString:#""] || [sender value] == nil)
[sender resignFirstResponder];
}
}
The problem here is that you can't easily differentiate between a tap on the clear button and a tap on the delete button when there is one character in the UITextField.
As I said in the beginning of my answer, this is not advisable in the first place and as the answers here have shown, it is not so easy to implement. I don't think it's worth the hassle, considering the difficulty involved and the fact that it doesn't result in optimal user experience.
This code is definitely working for me to hide the key board while clearing out the content of the textfield
- (BOOL)textFieldShouldClear:(UITextField *)textField
{
textField.text = #"";
return NO;
}
Yep. Call resignFirstResponder on the text field in the delegate's textFieldShouldClear: method.
In UITextFieldDelegate
- (BOOL)textFieldShouldClear:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
But there is a problem with this. From the manual, "The text field calls this method in response to the user pressing the built-in clear button. (This button is not shown by default but can be enabled by changing the value in the clearButtonMode property of the text field.) This method is also called when editing begins and the clearsOnBeginEditing property of the text field is set to YES."
Note that, this method is called when editing begins if clearsOnBeginEditing is set to YES. So if you call resignFirstResponder in this method then editing will not begin actually. So you need to set clearsOnBeginEditing to NO. Obviously then the text field won't be cleared when editing begins.
Another IMPORTANT matter not directly related to the question. Hiding the keypad after tapping clear button is not a familiar behavior and Apple does NOT like changing the behavior of standard items. You may get a rejection for this.
Try this code:
[TextField performSelector:#selector(resignFirstResponder) withObject:nil afterDelay:0.1];
For Swift
In your UITextFieldDelegate
func textFieldShouldClear(_ textField: UITextField) -> Bool {
textField.resignFirstResponse()
return true
}

Focus on next valid key view on iPhone

Is there an iPhone equivalent for the NSResponder methods -selectNextKeyView or -nextValidKeyView from Mac OS X? I know about the -becomeFirstResponder method, but finding out which view to call that on is not very pretty when view hierarchies get more complicated.
There must be some kind of way to find this out as when I press tab when in the iPhone Simulator, focus does properly go to the next UITextField. This made me wonder what exactly happens when I press tab. Any ideas?
Update: This does exactly what I want, but _nextKeyResponder is private API, so a no-no. Is there any way to do a 'fake' tab key press without using private API?
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
// Try to find next responder
UIView *nextResponder = (UIView *)[self.view _nextKeyResponder];
if (nextResponder) {
// Found next responder, so set it.
[nextResponder becomeFirstResponder];
[self.tableView scrollRectToVisible:[self.tableView convertRect:[nextResponder frame] fromView:nextResponder] animated:YES];
} else {
// Not found, so remove keyboard.
[textField resignFirstResponder];
}
return NO; // We do not want UITextField to insert line-breaks.
}
There is not a public iOS equivalent for NSResponder's -selectKeyView or -nextValidKeyView.
When the first responder is an instance of UITextField, pressing tab instantiates a private subclass of UIEvent which is passed to -[UIApplication sendEvent:], which in turn calls -[UIView _nextKeyResponder].
-[UIView _nextKeyResponder] doesn't work quite the way you think it does. It treats the key view chain as a loop, so your else block will never be reached. For the same reason, even if there was a public API for synthesizing keyboard events, you probably wouldn't want to use it.
Instead, you probably want something more like UIWebView's UIToolbar-based form input accessory. Its buttons can be enabled and disabled when appropriate, and its delegate handles the actual button press actions.
To implement such a delegate in a general way, however, it might be helpful to look at how -[UIView _nextKeyResponder] is implemented.
In the UITextField delegate -textFieldDidEndEditing:, switch between the various text fields (for example, by testing the text field's tag property).
When you match one text field, set another text field or other control to become the next responder.
I'm surprised nobody else appears to have solved this on iOS.
I devised a solution that handles both Tab and Shift+Tab to go forward and backward to any field you want on iOS, and doesn't use any private APIs.
Here is the write-up: http://weaklyreferenced.wordpress.com/2012/11/13/responding-to-the-tab-and-shift-tab-keys-on-ios-5-ios-6-with-an-external-keyboard/

Can't get rid of the keyboard in UITextView

I have a table and in one of the cells I keep a UITextView. When the user taps it the keyboard appears. I was trying various ways to get rid of it. My first approach was to detect a tap on the table cell of the UITextView, but since the text view takes most of it, it's not suitable. Then I tried to add a button to the toolbar and whenever the user presses it, the keybord disappears with resignFirstResponder, but it won't work. It seems that only when I'm in the same view as the UITextView resignFirstResponder works. So how can I get rid of the keyboard from a different view?
Thanks.
The method below uses the Return Key to dismiss the UITextView Keyboard.
In your Controller, set the UITextView's Delegate to self
like this:
myTextView.delegate=self;
Then add this method:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range
replacementText:(NSString *)text
{
// Any new character added is passed in as the "text" parameter
if ([text isEqualToString:#"\n"]) {
// Be sure to test for equality using the "isEqualToString" message
[textView resignFirstResponder];
// Return FALSE so that the final '\n' character doesn't get added
return FALSE;
}
// For any other character return TRUE so that the text gets added to the view
return TRUE;
}
This should work if you're not using the Return key as a true Return key (e.g. adding new line).
What do you mean "it won't work". If txtView is your UITe4xtView, do you mean that associating the button with an action that has [txtView resignFirstResponder] wont work? I've used this code before and it works for me
Without knowing the size of the controls, nor the intent, it's a bit hard to make a solid recommendation. However, if you're looking for a read-only text view, why not consider a UILabel? If it's going to contain a great deal of read-only text and you need rich formatting, consider a UIWebView with your formatting.
Of course, this answer could be completely inappropriate. Can you clarify your intentions, maybe show a screen shot of the app-in-progress (untapped, of course)?
try unchecking the 'Editable' option in the Text View Attributes window in Interface Builder.
this stops the keyboard from showing up if the user clicks on your TextView
i've use for that kind of problem, the folowing method
- (BOOL)textFieldShouldReturn: tf_some_text_field {
[tf_some_text_field resignFirstResponder];
[tf_another_text_field_in_the_same_view resignFirstResponder];
return YES;
}
hope it helps...

Hiding the Keyboard

I have a UISearchBar and on the delegate method I hide the keyboard when the text field is cleared:
- (void)searchBar:(UISearchBar *)filterBar textDidChange:(NSString *)filterText {
NSLog(#"filter: %#", filterText);
if ([filterText length] == 0) {
NSLog(#"hiding keyboard");
[filterBar resignFirstResponder ];
Now when I use the backspace button to clear out the search term all is good. The keyboard hides when the search turns to empty. Not so when I am pressing the "cross" button to clear out the search field altogether.
Well, not entirely true. I does call resignFirstResponder and hides the keyboard - you just can't see it because it comes right back up. I found this out by observing the keyboard show/hide events.
So how come the keyboard is shown again? How can I prevent this?
I've already tried to walk all subviews of the UISearchBar and also call resignFirstResponder on those ...but unless I did something wrong - that doesn't solve this either.
Update:
In fact I just got the keyboard to not disable the "Done" button :-D ...so I will "stop" going down that road as Kevin suggested. Still I would like to know why the keyboard came back up like this.
I would suggest you stop trying to do this. Hiding the keyboard when the field empties out is completely non-standard behavior and the user won't expect it. In situations like this it's far better to keep your behavior consistent with all the rest of the apps across the system.
I see you've accepted an answer and don't plan to continue in this vein, but I am curious whether you could achieve something like you wanted by implementing this:
- (BOOL)canBecomeFirstResponder
{
return !preventingKeyboardAppearance; // so to speak
}
- (void)searchBar:(UISearchBar *)filterBar textDidChange:(NSString *)filterText
{
// handle text
preventingKeyboardAppearance = YES;
[filterBar resignFirstResponder];
}
I'm not clear under what circumstances you would set preventingKeyboardAppearance back to NO, but I do wonder if this would work.
I basically agree with Kevin, but that doesn't help you so here goes:
Try looping through the subviews of the searchbar and find the sibling which is of the class UITextField. Then either set the delegate property of this text field to your ViewController's class and handle the callback there (e.g. textViewShouldReturn), or simply call resignFirstResponder directly on the text field. The former obviously needs to be done at init/load time while the latter can be done in your existing textDidChange callback.
Here are some more pointers:
http://discussions.apple.com/thread.jspa?threadID=1479468&tstart=0
http://discussions.apple.com/thread.jspa?messageID=8176608
-(BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
[textField resignFirstResponder] is not working some time so use this
[YorTextFieldName resignFirstResponder] it's working correctly not any other
function for hiding key bord