I am using keyboardWasShown and keyboardWillBeHidden notification for sliding the view to get the visible text view.
I have a UITabBar application with six tabs.
In each view I am using the UINavigationController.
In the detail view of each UITableViewCell I am using the keyboard notifications.
So the problem is that the keyboard notifications work for the first time that I will use . on on the other tabs it won't work .
The code is as follows :
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWasHidden:)
name:UIKeyboardDidHideNotification
object:nil];
and the methods
- (void)keyboardWasShown:(NSNotification *)aNotification {
if ( keyboardShown )
return;
NSDictionary *info = [aNotification userInfo];
NSValue *aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
CGSize keyboardSize = [aValue CGRectValue].size;
NSTimeInterval animationDuration = 0.300000011920929;
CGRect frame = self.view.frame;
frame.origin.y -= keyboardSize.height-100;
frame.size.height += keyboardSize.height-100;
[UIView beginAnimations:#"ResizeForKeyboard" context:nil];
[UIView setAnimationDuration:animationDuration];
self.view.frame = frame;
[UIView commitAnimations];
viewMoved = YES;
keyboardShown = YES;
}
- (void)keyboardWasHidden:(NSNotification *)aNotification {
if ( viewMoved && tvAddreview) {
NSDictionary *info = [aNotification userInfo];
NSValue *aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
CGSize keyboardSize = [aValue CGRectValue].size;
NSTimeInterval animationDuration = 0.300000011920929;
CGRect frame = self.view.frame;
frame.origin.y += keyboardSize.height-100;
frame.size.height -= keyboardSize.height-100;
[UIView beginAnimations:#"ResizeForKeyboard" context:nil];
[UIView setAnimationDuration:animationDuration];
self.view.frame = frame;
[UIView commitAnimations];
viewMoved = NO;
}
keyboardShown = NO;
}
you should dothis in eachClass like this:
-(void) viewWillAppear: (BOOL)animated
{
[super viewWillAppear:animated];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self
selector:#selector(keyboardWasShown:)
name:UIKeyboardWillShowNotification
object:nil];
[nc addObserver:self
selector:#selector(keyboardWasHidden:)
name:UIKeyboardWillHideNotification
object:nil];
}
- (void) viewWillDisappear: (BOOL)animated{
[super viewWillDisappear:animated];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
[nc removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
}
because the notifications are on the application level not to your class level. So if you have added them in one class and not in all classes, then going to the next class. the notification will still call the the key keyboardWasShown: and the other from the class in which you added the notifications hence your local variables like...
viewMoved = YES;
keyboardShown = YES;
will throw the bad excess exceptions
In your case it is also required to do in all 6 view controllers
Hope this helps.
Related
I want my view to scroll down when keyboard hides, the thing is that for the first time the view comes from outside of its frame(first image I have attached) but if I hide keyboard for the second time the view scrolls down in a correct way(second figure).
Here is the code related to this part:
- (void)viewDidUnload
{
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification
object:self.view.window];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardDidHide:)
name:UIKeyboardDidHideNotification
object:nil];
}
- (void)keyboardDidShow:(NSNotification *)notification
{
[_scrollView setScrollEnabled:TRUE];
}
- (void)keyboardDidHide:(NSNotification *)notification
{
[UIView animateWithDuration:4 animations:^{
NSDictionary* info = [notification userInfo];
//---obtain the size of the keyboard---
NSValue* aValue = [info objectForKey:UIKeyboardFrameEndUserInfoKey];
CGRect keyboardRect = [self.view convertRect:[aValue CGRectValue] fromView:nil];
//---resize the scroll view back to the original size (without keyboard)---
CGRect viewFrame = [self.view frame];
viewFrame.size.height += keyboardRect.size.height;
self.scrollView.frame = viewFrame;
}];
}
I have a UISearchBar that needs to be compressed (see screenshot) and then expand to a larger size when it is touched or isActive.
How would I go about doing this? Currently my search bar is placed in the view via IB.
thanks
Use this delegate of the search bar :
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
[self setTheSearchBarWithRect:newRect];//newRect is CGRect;
}
-(void)setTheSearchBarWithRect:(CGRect)frame{
[UIView animateWithDuration:(1.5f)
delay:0
options: UIViewAnimationOptionCurveEaseInOut
animations:^{
yourSearchBar.frame = frame;
}
completion:^(BOOL finished){
}];
}
and in the below delegate call the above function with its original frame.
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar;
- (void)searchBarCancelButtonClicked:(UISearchBar *) searchBar;
I would suggest adding a NSNotifcation listener for the keyboard showing/hiding notifications and based on this adjust the UISearchBar frame:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self selector:#selector(adjustFrame:) name:UIKeyboardWillShowNotification object:nil];
[nc addObserver:self selector:#selector(adjustFrame:) name:UIKeyboardWillHideNotification object:nil];
}
We need to remove the listener when the view is going to disappear:
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[nc removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}
And now we need the 2 custom functions to adjust the frame:
- (void)adjustFrame:(NSNotification *) notification {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
[UIView setAnimationBeginsFromCurrentState:YES];
if ([[notification name] isEqual:UIKeyboardWillHideNotification]) {
// revert back to the normal state.
self.searchBar.frame = CGRectMake (100,50,100,self.searchBar.frame.size.Height);
}
else {
//resize search bar
self.searchBar.frame = CGRectMake (10,50,200,self.searchBar.frame.size.Height);
}
[UIView commitAnimations];
}
You should just change search bar frame (location and size) on editing start and ending.
for example:
on start
sbar.frame = CGRectMake(sbar.frame.origin.x - 100., sbar.frame.origin.y, sbar.frame.size.x + 100., sbar.frame.size.y);
on edit end just back control at original place:
sbar.frame = CGRectMake(sbar.frame.origin.x + 100., sbar.frame.origin.y, sbar.frame.size.x - 100., sbar.frame.size.y);
Hi can someone help me create this feature, I would like to have a text box at the bottom of my app, and as soon as the user clicks on it, it should raise that text box to the middle of screen right above the keyboard. Similar to skype app, thanks!
Try This
#define kKeyboardAnimationDuration 0.3
#interface YourViewController:UIViewController
{
BOOL keyboardIsShown;
}
And then in your implementation
- (void)viewDidLoad
{
// register for keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:self.view.window];
// register for keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:self.view.window];
keyboardIsShown = NO;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
// unregister for keyboard notifications while not visible.
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
// unregister for keyboard notifications while not visible.
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
}
#pragma mark - Keyboard Events
- (void)keyboardWillShow:(NSNotification *)n
{
if (keyboardIsShown)
{
return;
}
NSDictionary* userInfo = [n userInfo];
CGSize keyboardSize = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
CGRect viewFrame = self.view.frame;
viewFrame.origin.y-= (keyboardSize.height);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:kKeyboardAnimationDuration];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
keyboardIsShown = YES;
}
- (void)keyboardWillHide:(NSNotification *)n
{
NSDictionary* userInfo = [n userInfo];
CGSize keyboardSize = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
CGRect viewFrame = self.view.frame;
viewFrame.origin.y+= (keyboardSize.height);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:kKeyboardAnimationDuration];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
keyboardIsShown = NO;
}
Can anyone explain how best to emulate the behaviour the "accessory view" (in inverted comma's as I don't actually believe it to be an accessory view) in iOS 5's Messages.app displays, in that I want a view that gives the impression it's fixed to the top of the keyboard, but which remains on screen when the keyboard is dismissed.
It's probably a separate view that gets re-positioned using an animation that has the same duration as the keyboard animation.
Try observing the UIKeyboardWillShowNotification and UIKeyboardWillHideNotification and in your handlers get the keyboard's animation duration and frame and start your own animation to re-position the view so that it will appear to move along with the keyboard. Some similar code I use is below:
- (void)registerKeyboardNotifications {
// Register for keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
}
- (void)unregisterKeyboardNotifications {
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
}
- (void)keyboardWillShow:(NSNotification*)aNotification {
NSDictionary* info = [aNotification userInfo];
CGRect kbFrameBeginFrame = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
CGRect kbFrameEndFrame = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
NSTimeInterval animDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
UIViewAnimationCurve animCurve = [[info objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];
NSLog(#"\nFrame Begin = %#\nFrame End = %#\nAnimation Duration = %f\nAnimation Curve = %i",
NSStringFromCGRect(kbFrameBeginFrame), NSStringFromCGRect(kbFrameEndFrame), animDuration, animCurve);
_showKeyboard = YES;
[self adjustUIForKeyboard:kbFrameEndFrame.size animDuration:animDuration];
}
- (void)keyboardWillHide:(NSNotification*)aNotification {
NSDictionary* info = [aNotification userInfo];
CGRect kbFrameBeginFrame = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
CGRect kbFrameEndFrame = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
NSTimeInterval animDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
UIViewAnimationCurve animCurve = [[info objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];
NSLog(#"\nFrame Begin = %#\nFrame End = %#\nAnimation Duration = %f\nAnimation Curve = %i",
NSStringFromCGRect(kbFrameBeginFrame), NSStringFromCGRect(kbFrameEndFrame), animDuration, animCurve);
_showKeyboard = NO;
[self adjustUIForKeyboard:kbFrameEndFrame.size animDuration:animDuration];
}
/**
* Adjust the UI elements so that views are visible when keyboard is visible or hidden
*/
- (void)adjustUIForKeyboard:(CGSize)keyboardSize animDuration:(NSTimeInterval)duration {
[UIView animateWithDuration:duration
animations:^(void) {
// When keyboard is showing we adjust up and vice versa for a hidden keyboard
if (_showKeyboard) {
// Set your view's frame values
} else {
// Set your view's frame values
}
}
completion:NULL];
}
-(void)viewWillAppear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:self.view.window];
[super viewWillAppear:animated];
}
-(void)viewWillDisappear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[super viewWillDisappear:animated];
}
-(void)keyboardWillShow:(NSNotification *)notif
{
NSDictionary*info=[notif userInfo];
NSValue* aValue= [info objectForKey:UIKeyboardBoundsUserInfoKey];
CGSize keyboardSize=[aValue CGRectValue].size;
float bottomPoint= (text1.frame.origin.y+text1.frame.size.height+5);
//float bottomPoint= (text2.frame.origin.y+text2.frame.size.height+5);
//float bottomPoint= (text3.frame.origin.y+text3.frame.size.height+5);
scrollAmount=keyboardSize.height - (self.view.frame.size.height - bottomPoint);
if(scrollAmount > 0)
{
moveViewUp = YES;
[self scrollTheView:YES];
}
else
moveViewUp = NO;
}
}
-(void)scrollTheView:(BOOL) movedUp
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
CGRect rect = self.view.frame;
if(movedUp)
{
rect.origin.y -= scrollAmount;
}
else
{
rect.origin.y += scrollAmount;
}
self.view.frame = rect;
[UIView commitAnimations];
}
-(BOOL)text1ShouldReturn:(UITextField *)theTextField
{
[theTextField resignFirstResponder];
if(moveViewUp)
[self scrollTheView:NO];
return YES;
}
I have written this code to scroll the view but it is not returning when the keyboard disappears.
You have not subscribed to the UIKeyboardWillHideNotifcation, only Show - thus it will not do anything when the keyboard hides.