I have MyRootViewController which presents MyModalViewController modally on a button press. MyModalViewController contains a UISearchBar and I want this to display the usual [Cut|Copy|Paste|Select All] text options on a long press in it’s text field.
MyRootViewController presents custom UIMenuItems (via UIMenuController) on a long press, hence overrides - (BOOL)canBecomeFirstResponder and - (BOOL)canPerformAction:(SEL)action withSender:(id)sender and implements -(void)duplicate:(id)sender and -(void)delete:(id)sender.
The problem I have is that MyRootViewController is being asked which UIMenuItems to display for the UISearchBar inside MyModalViewController, when the user long presses inside it and is therefore displaying irrelevant menu items, instead of the usual [Cut|Copy|Paste|Select All] options for a text field.
My understanding is that this is happening because MyRootViewController is still in the responder chain, even though it is not currently visible.
The best solution I’ve come up with so far is to subclass UISearchBar and override - (BOOL)canPerformAction:(SEL)action withSender:(id)sender, returning YES for cut, copy, paste or Select All. This stops iOS going looking further down the responder chain. But this feels like a hack - I shouldn’t have to resort to this just to make a UISearchBar behave consistently with the rest of the system, just because I’m using UIMenuController elsewhere.
Does anyone know of a more technically correct solution to this problem?
You may choose to set menuItems property of [UIMenuController sharedController] only on long press. And set it to nil whenever UIMenuControllerWillHideNotification is thrown.
Related
I added a UITextField to my storyboard:
#property (weak, nonatomic) IBOutlet UITextField *nameField;
And it was working fine at first, but had some constraint issues which caused the view to not build correctly on an iPhone 5. So I messed with some of the constraints to get it to display correctly and now the keyboard never comes up/the UITextField refuses to respond to touches OR become active.
I tried setting a UITapGestureRecognizer to the nameField, didn't work.
I made sure there were no views blocking it (checked on the view debugger, and then explicitly called [self.view bringSubviewToFront:self.nameField]; in viewDidAppear)
I tried [self.nameField setUserInteractionEnabled:YES]; as well because why not.
So then I went to the storyboard, clicked on the text field and under the connection tab on the right side menu I looked at "Sent Events" and hooked up Touch Up Inside to an IBAction method:
- (IBAction)beginNameEdit:(id)sender {
NSLog(#"Edit begin");
BOOL accepted = [self.nameField becomeFirstResponder];
if (accepted) {
NSLog(#"accepted");
}
}
Nothing happens, (Edit begin did not print). (I touched up inside the boundary as well for sure, but whatever)
So then I hooked up Touch Down to the same exact IBAction.
This time, I started getting 'Edit begin' to print but the call to become first responder did nothing despite accepted actually getting printed (which means that according to Apple, the text field accepted first responder status)
I can't seem to make my textField active and so it's forever stuck on showing the placeholder text... It makes no sense, especially because I would be shocked if playing with some of the auto layout constraints could have any sort of effect.
Any suggestions?
Ok, and in classic the-answer-is-the-last-thing-you'd-expect fashion:
I was using the simulator to test the app. Turns out the keyboard doesn't always come up when you're using the simulator because it auto-detects the fact you have an ACTUAL keyboard on the computer you are using. So instead of a keyboard coming up on the simulator it was silently becoming the first responder and waiting for me to type something on my computer's keyboard.
Why the keyboard was coming up earlier and not now, I have no clue. But I'll leave this up in case anyone else comes across this issue.
I'm working on a custom keyboard for iOS which will have its own search field (similarly implemented by PopKey).
My keyboard's textfield is able to take the focus with becomeFirstResponder and I'm able to give it up by using resignFirstResponder. However after I resign focus, the host app has a difficult time retaking focus despite touching the form. The app's textfield will still show the text cursor blinking.
Any ideas? Thanks
The solution is a hack, as of right now you can't really give the host app its focus back.
Subclass a UITextField and on its delegate implement
textFieldShouldBeginEditing by returning NO.
Add a BOOL property isSelected that gets set to YES in touchesBegan (not to be confused with the default selected property)
In your keyboard's keyPressed method, if searchField.isSelected, manipulate the searchField.text. Else, manipulate textDocumentProxy like normal.
Add a clear button and method that wipes searchField.text and searchField.isSelected, allowing any further keystrokes to return to the textDocumentProxy
Add an animation that replicates the blinking type cursor
I have a UITableViewController where I'm working with a custom UITableViewCell. The cell contains an image, labels and buttons. Everything is working as expected except of the buttons. When pressing the button, nothing happens. Only the cell gets selected.
I made a connection in IB from the button to my custom TweetTableViewCell class.
#property (weak, nonatomic) IBOutlet UIButton *cellFollowButton;
- (IBAction)followButtonTappedonCell:(id)sender;
I'm writing some text to the console in my followButtonTappedonCell action. But when pressing the button, nothing happens. It seems to me that some view consumes the tap before it arrives to the button. To make it more confusing... When I add a button in may UITableViewController programatically like this:
[cell.cellFollowButton addTarget:self action:#selector(customActionPressed) forControlEvents:UIControlEventTouchDown];
[cell addSubview:cell.cellFollowButton];
...it just works.
I read in other articles that disabling "User Interaction Enabled" solved similar problems, but it doesn't in my case.
I'm sure that many others must have run into this problem when using buttons in UITableViewCells. Any help is highly appreciated.
I'm using Xcode 5 for iOS 7.
If your cell is in a nib, make sure the root object is a UITableViewCell and NOT a UIView
I would recommend you to go through this link. It has clear description of your problem. However, I've tried to extract needed info.
Many types of events rely on a responder chain for event delivery. The responder chain is a series of linked responder objects. It starts with the first responder and ends with the application object. If the first responder cannot handle an event, it forwards the event to the next responder in the responder chain.
A responder object is an object that can respond to and handle events. The UIResponder class is the base class for all responder objects, and it defines the programmatic interface not only for event handling but also for common responder behavior. Instances of the UIApplication, UIViewController, and UIView classes are responders, which means that all views and most key controller objects are responders.
In your Case, when you are writing event methods in your customTableViewCell class, your methods are not being called. this is because, TableViewCell is not participating in Responder chain.
next thing is, check whether "User Interaction is enabled " or not for your Cell. You can find it under View section of "Attribute inspector".
I am hoping if someone can help me resolve an IOS/XCode question.
I need to have a UITextView created inside a UITableViewCell, this UITextView has responds to a user click, upon which a UIPopoverController will be displayed so that a sub-UITableView is displayed (inside the UIPopoverController) allowing a user to select from a list of choices (lines of text). After the user select the choice (one of the line of text), that line of text will then be displayed inside the said UITextView. First problem I am having is that when the user click on the UITextView the keyboard gets displayed instead of the UIPopoverController. How do I go about disabling ie. calling resignFirstResponder so that instead of the keyboard displaying, I get the UIPopoverController coming up instead. Would someone be kind enough to share similar codes? or point me to some sample of how this can be done? Thanks so much in advance.
You can use following delegate method to detect when textView is tapped and show your popOverController accordingly, return 'NO' in the delegate method so that no keyboard will appear...
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
// code to show popOverController
return NO;
}
(I'm targetting iOS 2.0 for the time being.)
I have a class which subclasses UITextField and implements the UITextFieldDelegate protocol.
At first, I did not set the class as its own delegate, and when I clicked in the field, the keyboard popped up automatically. So far, so good.
I send the setReturnKeyType: message with UIReturnKeyDone, so it changes the bottom-right button to say Done.
The problem was, when I clicked Done or pressed [Return], nothing happened - the keyboard wouldn't go away.
I tried adding self as an observer for the end editing notification, but it never got called when Done was clicked; from a Google search it seems that only gets fired when the field resigns as the first responder - which is the bit I can't get to happen.
I then found answers on here that suggested adding self as the delegate and handling textFieldShouldReturn:. The problem is, as soon as I add self as the delegate, the keyboard no longer pops up when you click the field (and it doesn't gain focus) - it seems it isn't becoming first responder.
I tried handling textFieldShouldBeginEditing: and returning YES (docs say that should be the default if not overridden), and that got called, but made no difference. In my ignorance I tried [textField becomeFirstResponder] and was rewarded with a stack overflow (now I know that is called in response to trying to become first responder).
I'm now thoroughly stuck!
Can anyone help? I just want the keyboard to go away when the user clicks Done or presses [Return].
Are you using an xib or doing it programatically? If you are using an xib then you may have forgotten to connect the delegate in File's Owner.
(BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
Try This one.
My fault. Turns out you're not supposed to set a text field's delegate to itself - there are complications due to unhandled selectors being forwarded to its delegate. If it doesn't respond to a selector the message goes to its delegate... which is itself, which we already know doesn't respond. Hence, an infinite loop.
Using a separate object as the delegate worked perfectly.
Hopefully this will help someone else avoid the same problem.