I have a UITextField in a Landscape view, and when I press the 'dismiss keyboard' button in the lower right of the UIKeyboard view, the keyboard does NOT disappear. Is there a way to programmatically listen for when this key was pressed? Or is there a connection I am not seeing that will make this keyboard go away?
This is iOS 4 and XCode 4. Thanks.
I had same problem today and I wondered, wy it works in Apple's KeyboardAccessory Sample Code.
So I did reverse engineering. The ViewController was not the mistake I made in my case.
In the implementation of UIApplicationDelegate there is the entry point of application, where root viewcontroller and window will be setup - (void) applicationDidFinishLaunching:(UIApplication *)application. If you forgot to add root viewcontrollers view to window as subview, the dismiss-keyboard-button wouldn't work in any view of your app.
#class ViewController;
#interface KeyboardAccessoryAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
ViewController *viewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet ViewController *viewController;
#end
...
- (void)applicationDidFinishLaunching:(UIApplication *)application {
[window addSubview:viewController.view];
[window makeKeyAndVisible];
}
Please don't forget to setup the outlets in the main xib file.
I dont know why this is related to keyboards behavior. But my theory is, that the responder chain is not linked to window, but it needs.
To dismiss the keyboard using the dismiss keyboard button you need to implement the delegate method
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
//Check if your text field is first responder, and if it is, have it resign
}
Alternatively, if you want to dismiss the keyboard by tapping outside of it, use
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
for (UIView* view in self.view.subviews)
{
if ([view isKindOfClass:[UITextField class]]) {
[view resignFirstResponder];
}
if ([view isKindOfClass:[UITextView class]]) {
[view resignFirstResponder];
}
}
}
you need to tell the text field that is accepting the keyboard input to no longer be the first responder.
[UITextField resignFirstRepsonder];
Related
I need to hide an UIImageView, from an action triggered by a UISwitch which is inside a popover.
I'm using this piece of code however it does nothing when tapping the UISwitch, probably because the UISwitch its inside a popover view.
This code works perfectly on iPhone, however on iPad does not work and the UIImageView does not hide. Why?
- (IBAction)toggleImage:(id)sender {
if ([sender isOn]){
self.myImage.hidden = NO;
} else {
self.myImage.hidden = YES;
}
}
UIImageView is connected to an outlet and UISwitch is connected to an outlet and action.
Please help, thank you.
Since the switch being interacted with is on the popover and the image view that we want to change is on the underlying (presenting) VC, the proper approach is to make the underlying VC a delegate of the popover.
// MyPopoverVC.h
#protocol PopoverDelegate <NSObject>
- (void)popover:(MyPopoverVC *)vc changedSwitchTo:(BOOL)on;
#end
#interface MyPopoverVC : UIViewController
#property (nonatomic, weak) id<PopoverDelegate>delegate;
// ...
#end
In the Popover VC's implementation (IMPORTANT: the switch's IBAction should be wired to the popover vc)...
- (IBAction)toggleImage:(UISwitch *)sender {
[self.delegate popover:self changedSwitchTo:sender.on];
}
In the presenting vc, declare it as conforming to that <PopoverDelegate> protocol. Before presenting the popover, initialize the delegate...
MyPopoverVC *myPopoverVC = [[MyPopoverVC alloc] init...
myPopoverVC.delegate = self;
Also in the presenting vc, implement the delegate protocol...
- (void)popover:(MyPopoverVC *) changedSwitchTo:(BOOL)on {
self.myImage.hidden = !on;
}
I can't figure out how enable iOS to pass events from a childViewController down to its parentviewcontroller.
My childviewcontroller is like an overlay it's root view is transparent and it's opaque views cover a dynamic area - potentially the the entire parentviewcontroller (thus the root view of the childviewcontroller has the same frame as the parent).
Though only the opaque part of the childViewController's views should receive events. All other events I would like to get forwarded in the responderChain down to the parentviewcontrollers views. Just as if all views were sharing one viewcontroller.
I have made an instance of this class:
#interface SilentView : UIView
#end
#implementation SilentView
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
UIView *hitView = [super hitTest:point withEvent:event];
if (hitView == self) {
return nil;
}
return hitView;
}
#end
the rootview of my childViewController. That works for me.
I need to dismiss keyboard which show itself when I click UITextField from childView. I need to do this in method (scrollViewWillBeginEditing) which is in parentViewController. How can I do it?
EDIT:
I have method in childViewController:
- (void)dismissKeyboard {
[self.textField resignFirstResponder];
NSLog(#"%#", self.textField.text);
}
and .h of childViewController:
#protocol VVInformationTableViewControllerDelegate<NSObject, UIScrollViewDelegate>
-(void)dismissKeyboard;
#end
#interface VVInformationTableViewController : UITableViewController <UITextFieldDelegate, UITableViewDelegate, UIScrollViewDelegate, VVInformationTableViewControllerDelegate>
#property (weak, nonatomic) id<VVInformationTableViewControllerDelegate> delegate;
and I try to call it in:
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
[self.infoTableController dismissKeyboard];
}
When it is call then NSLog print (null) and keyboard didn't dismiss, but when I call dismissKeyboard from childViewController then it print true value and keyboard dismiss.
Any help?
You can use the following code
[self.childView endEditing:Yes];
I have trouble w/ hiding toolbar when leave screen by segue.
Details: App has a few dozen screens, all of them are belonged the same navigation controller. A few screens have toolbar. For these a few screens in -(void)viewDidLoad I use
[self.navigationController setToolbarHidden:NO animated:NO];
and in -(void)viewWillDisappear:(BOOL)animated:
[self.navigationController setToolbarHidden:YES animated:YES];
so toolbar is visible only on necessary screens and the screen which needs toolbar controls the visibility. All work well when I navigate by "back" button.
The trouble starting when I try to navigate by segue like this (goto home & goto another branch).
[owner.navigationController popToRootViewControllerAnimated:NO];
[self performSegueWithIdentifier:SEGUE_NAME sender:self];
toolbar is stay visible in spite of calling -(void)viewWillDisappear which should hide toolbar.
are there any ideas how to perform these "ToolBarHidden" by right way.
thanks
PS: of course I could hide toolbar on every screen, but I want to avoid this unnecessary operations and want to know how to do it right.
**STEP1:** in your controller.h
#interface ViewController : UIViewController {
UIToolbar *bar;
}
#property (nonatomic, strong) IBOutlet UIToolbar *bar;
#end
**STEP2:** in your controller.m
#synthesize bar;
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.bar.hidden = NO;
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
self.bar.hidden = YES;
}
**STEP3:** connect in Intrface
hope this help you!
Why UISearchBar does not get Focus and keyboard does not appear when UIViewController is pushed to navigation controller for the 2nd time? It seems as no element on the whole view has a focus.
MY USE CASE: I have 2 View Controllers: A and B. Transition is A->B. A, B are pushed to navigation controller.
When I show B for the first time focus is set to the searchbar and keyboard appears.OK.
Then I go back to the A. And again from A->B. Now for the second time there is no focus and keyboard does not appear. It is WRONG.
MY CODE: On the B UIViewController IBOutlet connection to the searchbar is created:
#property (weak, nonatomic) IBOutlet UISearchBar *mySearchBar;
Delegate of the mySearchBar is also set.
I set focus on the searchbar in B UIViewController in viewDidAppear method:
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[self performSelector:#selector(setCorrectFocus) withObject:NULL afterDelay:0.2];
}
-(void) setCorrectFocus {
[self.mySearchBar becomeFirstResponder];
}
Transitions between controllers are done manually in code like this:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"myStoryboard" bundle:nil];
AController *a = [storyboard instantiateViewControllerWithIdentifier:#"A"];
[self.navigationController pushViewController:a animated:NO];
Try this
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self setCorrectFocus];
}
-(void)setCorrectFocus
{
[self.mySearchBar becomeFirstResponder];
}
After long searching I found Error. Somewhere in storyboard old connection for UISearchBar with the name mySearchbar was left. Another thing that I had to correct was that the method
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar;
returned NO, every time I went back to previous Controller. But it should return YES to be able to set focus on search bar next time.
Was strugling with the same - had a UISearchBar inside a UITextView's keyboard accessory and even after [self.searchBar becomeFirstResponder] was called, keyboard input was still received by the text view.
This is what finally helped:
[self.searchBar.window makeKeyAndVisible];
Apparently the keyboard accessory is part of a different UIWindow than the UITextField.
Note: To continue typing in the text view, you should then call something like [self.textView.window makeKeyAndVisible]; ...
Have you tried adding self.mySearchBar.delegate = self;
You should use strong in your property
#property (strong, nonatomic) IBOutlet UISearchBar *mySearchBar;
Always set strong in your property for IBOutlet. When you pop B from navigationController, mySearchBar has released, so you push back to B, [self.mySearchBar becomeFirstResponder] is not work.