iOS 7 back swipe gesture and keyboard dismissal - cocoa-touch

I have a standard UINavigationViewController with a standard UIInteractivePopGestureRecognizer for iOS 7. I also have these well known and widely-used methods:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
They work like this:
- (void)keyboardWillShow:(NSNotification *)notification{
CGFloat keyboardSlideDuration = [[[notification userInfo] objectForKey: UIKeyboardAnimationDurationUserInfoKey] floatValue];
UIViewAnimationOptions keyboardAnimationCurve = [[notification userInfo][UIKeyboardAnimationCurveUserInfoKey] integerValue]<<16;
if (keyboardIsUp || isAnimating) return;
isAnimating = YES;
[UIView animateWithDuration:keyboardSlideDuration delay:0 options:(keyboardAnimationCurve | UIViewAnimationOptionBeginFromCurrentState) animations:^{
_topConstraint.constant -= kTopConstraintR4Ratio;
[self.view layoutIfNeeded];
}completion:^(BOOL finished){
keyboardIsUp = YES;
isAnimating = NO;
}];
}
- (void)keyboardWillHide:(NSNotification *)notification{
CGFloat keyboardSlideDuration = [[[notification userInfo] objectForKey: UIKeyboardAnimationDurationUserInfoKey] floatValue];
UIViewAnimationOptions keyboardAnimationCurve = [[notification userInfo][UIKeyboardAnimationCurveUserInfoKey] integerValue]<<16;
if (isAnimating) return;
isAnimating = YES;
[UIView animateWithDuration:keyboardSlideDuration delay:0 options:(keyboardAnimationCurve | UIViewAnimationOptionBeginFromCurrentState) animations:^{
_topConstraint.constant = topConstraintOriginalValue;
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
keyboardIsUp = NO;
isAnimating = NO;
}];
}
The thing is that UIView animateWithDuration is triggered without any respect to duration when I swipe the view back with a gesture. The whole view turns into a mess - it animates slowly when I pop the view, but when the gesture isn't finished - the view jumps up.
It looks like this:
How do I get rid of this strange behavior? I don't want the view to move during the transition and I want it to stay still.
EDIT:
You can download the sample project using the link here:
https://www.dropbox.com/s/034lfy49ru4pelf/SampleProject.zip

Easy hack:
BOOL needAdjustContstrain;
Set needAdjustContstrain to YES in keyboardWillShow:
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
if (needAdjustContstrain) {
_topContstraint.constant -=40;
}
}

you need to call the layoutIfneeded method before the animation block . Check out the code below :
- (void)keyboardWillHide:(NSNotification *)notification{
CGFloat keyboardSlideDuration = [[[notification userInfo] objectForKey: UIKeyboardAnimationDurationUserInfoKey] floatValue];
UIViewAnimationOptions keyboardAnimationCurve = [[notification userInfo][UIKeyboardAnimationCurveUserInfoKey] integerValue]<<16;
if (isAnimating) return;
isAnimating = YES;
[self.view layoutIfNeeded];
[UIView animateWithDuration:keyboardSlideDuration delay:0 options:(keyboardAnimationCurve | UIViewAnimationOptionBeginFromCurrentState) animations:^{
_topContstraint.constant = 89;
//
} completion:^(BOOL finished) {
keyboardIsUp = NO;
isAnimating = NO;
}];}
Please check the link

Related

How to scroll in a tabelview when keyboards shows up?

I have a ScrollView in which there are TableViews. I set when the keyboard appears, the content above the keyboard should move, so the keyboard won't obscure anything. How can I scroll what is above the keyboard, only when the keyboard is up?
You can add add observer to check keyboard is showing or not.
NotificationCenter.default.addObserver(self,
selector: #selector(viewController.keyboardWillShow(notification:)),
name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self,
selector: #selector(viewController.keyboardWillHide(notification:)),
name: NSNotification.Name.UIKeyboardWillHide, object: nil)
func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo? [UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
print("Show")
}
}
func keyboardWillHide(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
print("Hide")
}
}
And then you need to do calculation for content to show when keyboard will appear and set content offset of scrollview.
You need to manage the height of UITableView when the keyboard is up and down. Notification will help to manage state of wheather keyboard is up or not. According to state, we can udpate UITableView's height.
-(void) keyboardWillShow:(NSNotification *)note{
// get keyboard size and loctaion
CGRect keyboardBounds;
[[note.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] getValue: &keyboardBounds];
NSNumber *duration = [note.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
NSNumber *curve = [note.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey];
// Need to translate the bounds to account for rotation.
keyboardBounds = [self.view convertRect:keyboardBounds toView:nil];
// animations settings
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:[duration doubleValue]];
[UIView setAnimationCurve:[curve intValue]];
// set views with new info
_containerBottom.constant = keyboardBounds.size.height;
CGRect rectTable = _tblMessages.frame;
rectTable.size.height -= keyboardBounds.size.height;
_tblMessages.frame = rectTable;
[self.view layoutIfNeeded];
[self scrollToBottom];
// commit animations
[UIView commitAnimations];
}
-(void) keyboardWillHide:(NSNotification *)note{
CGRect keyboardBounds;
[[note.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] getValue: &keyboardBounds];
keyboardBounds = [self.view convertRect:keyboardBounds toView:nil];
NSNumber *duration = [note.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
NSNumber *curve = [note.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey];
// animations settings
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:[duration doubleValue]];
[UIView setAnimationCurve:[curve intValue]];
CGRect rectTable = _tblMessages.frame;
rectTable.size.height += keyboardBounds.size.height;
_tblMessages.frame = rectTable;
// commit animations
[UIView commitAnimations];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// 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)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
// unregister for keyboard notifications while not visible.
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
}

UIKeyboardWillShowNotification not calling and only UIKeyboardWillHideNotification calling in iOS 9

All is working good till iOS 8.
But when user tap on text field control comes directly in UIKeyboardWillHideNotification notification
Log in console -Can't find keyplane that supports type 4 for keyboard iPhone-PortraitTruffle-NumberPad; using 675849259_PortraitTruffle_iPhone-Simple-Pad_Default
Here is the code--
`
In view did load
- (void)viewDidLoad {
[super viewDidLoad];
self.txtMobNumber.delegate = self;
self.txtMobNumber.keyboardType = UIKeyboardTypeNumberPad;
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:#"UIKeyboardWillShowNotification" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:#"UIKeyboardWillHideNotification" object:nil];
}
notification callback
- (void)keyboardWillShow:(NSNotification *)notification
{
// Save the height of keyboard and animation duration
NSDictionary *userInfo = [notification userInfo];
CGRect keyboardRect = [userInfo[#"UIKeyboardBoundsUserInfoKey"] CGRectValue];
[UIView beginAnimations:#"moveKeyboard" context:nil];
float height = keyboardRect.size.height-60;
self.view.frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y - height, self.view.frame.size.width, self.view.frame.size.height);
[UIView commitAnimations];
// [self setNeedsUpdateConstraints];
}
// Reset the desired height
- (void)keyboardWillHide:(NSNotification *)notification
{
// Reset the desired height (keep the duration)
NSDictionary *userInfo = [notification userInfo];
CGRect keyboardRect = [userInfo[#"UIKeyboardBoundsUserInfoKey"] CGRectValue];
[UIView beginAnimations:#"moveKeyboard" context:nil];
float height = keyboardRect.size.height-60;
self.view.frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y + height, self.view.frame.size.width, self.view.frame.size.height);
[UIView commitAnimations];
}
`
This can be related to simulator setup, see menu "Hardware > Keyboard > Connect Keyboard Hardware". If this option is ON, you will get UIKeyboardWillHideNotification, but never UIKeyboardWillShowNotification.

Is it possible to find the autocorrection text of UITextField is in OPEN/CLOSE state in iOS 8?

I am enabling the autocorrection option of UITextField to show the suggestion text. Here my proble is want to identify the suggestion text view is in OPEN state or CLOSE state.
or
Please any one give me an idea about this.
We can detect this change using keyboard height change notification as follows,
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(didReceiveKeyboardWillChangeFrameNotification:)
name:UIKeyboardWillChangeFrameNotification
object:nil];
- (void)didReceiveKeyboardWillChangeFrameNotification:(NSNotification *)notification
{
NSDictionary *userInfo = [notification userInfo];
CGRect keyboardEndFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
if (CGRectIsNull(keyboardEndFrame)) {
return;
}
UIViewAnimationCurve animationCurve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
NSInteger animationCurveOption = (animationCurve << 16);
double animationDuration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
[UIView animateWithDuration:animationDuration
delay:0.0
options:animationCurveOption
animations:^{
}
completion:^(BOOL finished) {
}];
}

UIScrollView scroll issue for UITextViews

I have a form which has multiple textfields and textviews. When keyboad is shown I update scrollview frame to prevent textfields hiding under keyboard.
I did follow this question and implement a similar solution.
It works with uitextfields actually but not for uitextviews.
When keyboard is shown scrollview height's is reduced as much as keyboard height and then scroll to focused uitextfield. But if the focused item is uitextview it just doesnt scroll while height of uiscrollview is reduced.
IB screenshots for my scrollview;
https://www.dropbox.com/s/a1iblh6nsdqy34t/Screenshot%202014-05-30%2021.44.32.png
https://www.dropbox.com/s/o2h8avt5w82r5eo/Screenshot%202014-05-30%2021.45.19.png
Here is the code;
// register for keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardDidHide:)
name:UIKeyboardDidHideNotification
object:nil];
Notification handler;
-(void)keyboardWillShow:(NSNotification *)n {
if(keyboardUp)
return;
NSDictionary* userInfo = [n userInfo];
// get the size of the keyboard
CGSize keyboardSize = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
const int movementDistance = -keyboardSize.height - keyboardPaddingToScrollView;
const float movementDuration = 0.30f;
int movement = movementDistance;
[UIView beginAnimations: #"anim" context: nil];
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration: movementDuration];
CGRect contentSize = self.view.frame;
contentSize.size.height += movementDistance;
[self.view setFrame:contentSize];
[UIView commitAnimations];
}
-(void)keyboardDidShow:(NSNotification *)n {
keyboardUp = true;
NSLog(NSStringFromCGRect(self.view.frame));
}
-(void)keyboardWillHide:(NSNotification *)n {
if(!keyboardUp)
return;
NSDictionary* userInfo = [n userInfo];
// get the size of the keyboard
CGSize keyboardSize = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
const int movementDistance = keyboardSize.height + keyboardPaddingToScrollView;
const float movementDuration = 0.30f;
int movement = movementDistance;
[UIView beginAnimations: #"anim" context: nil];
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration: movementDuration];
CGRect contentSize = self.view.frame;
contentSize.size.height += movementDistance;
self.view.frame = contentSize;
[UIView commitAnimations];
}
-(void)keyboardDidHide:(NSNotification *)n {
keyboardUp = false;
}

keyboard hides textfield for different orientation in ipad

In my iPad application, I have few textView and textField's. When I click on textField, the keyboard covers the textField. So I am implementing the below code to move the textview up. But on rotation to portraitUpsideDown its not working fine. It slides the screen down in opposite direction. So how do I solve this problem??
-(void) animateTextField: (UITextView *) textField up: (BOOL) up
{
int txtPosition = (textField.frame.origin.y - 540);
const int movementDistance = (txtPosition < 0 ? 0 : txtPosition); // tweak as needed
const float movementDuration = 0.3f; // tweak as needed
int movement = (up ? -movementDistance : movementDistance);
[UIView beginAnimations: #"anim" context: nil];
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration: movementDuration];
self.view.frame = CGRectOffset(self.view.frame, 0, movement);
[UIView commitAnimations];
}
-(void)textViewDidBeginEditing:(UITextView *)textField
{
[self animateTextField: textField up: YES];
}
-(void)textViewDidEndEditing:(UITextView *)textField
{
[self animateTextField: textField up: NO];
}
-(BOOL)textFieldShouldReturn:(UITextView *)theTextField
{
[theTextField resignFirstResponder];
return YES;
}
This solution is for iPhone, but it considers both orientations.
You can adapt a bit and voilá:
http://cocoawithlove.com/2008/10/sliding-uitextfields-around-to-avoid.html
Crazy,
Just add another function:
- (void) animateTextView: (UITextView*) textView up: (BOOL) up
{
const int movementDistance = 80; // tweak as needed
const float movementDuration = 0.3f; // tweak as needed
int movement = (up ? -movementDistance : movementDistance);
[UIView beginAnimations: #"anim" context: nil];
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration: movementDuration];
self.view.frame = CGRectOffset(self.view.frame, 0, movement);
[UIView commitAnimations];
}
Then call it like:
- (void)textViewDidBeginEditing:(UITextView *)textView {
[self animateTextView: textView up: YES];
}
- (void)textViewDidEndEditing:(UITextView *)textView {
[self animateTextView: textView up: NO];
}
If your method like this.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
Try this. I don't know exactly. But I am trying to help you. May be x and y coordinate cannot be changed in any orientation. so try this.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if(interfaceOrientation=UIInterfaceOrienationPotraitUpsideDown){
//Declare txtPos globally...
txtPos=(textField.frame.origin.y + 540);
}
if(interfaceOrientation=UIInterfaceOrienationPotrait)
{
txtPos=(textField.frame.origin.y - 540);
}
return(YES);
}
in animate method.
assign textPos to txtPosition variable..
You should use keyboard will show and will hide notification to capture keyboard event and adjust your view accordingly.
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardDidHideNotification object:nil];
}
- (void)keyboardWillShow:(NSNotification *)notification {
CGRect keyboardFrame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGFloat keyboardHeight = CGRectGetHeight(keyboardFrame);
CGFloat animationDuration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];
UIViewAnimationCurve animationCurve = [notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
UIViewAnimationOptions animationOption = animationCurve << 16;
[UIView animateWithDuration:animationDuration delay:0 options:animationOption animations:^{
// adjust height using keyboardHeight
} completion:^(BOOL finished) {
}];
}
- (void)keyboardWillHide:(NSNotification *)notification {
CGRect keyboardFrame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGFloat keyboardHeight = CGRectGetHeight(keyboardFrame);
CGFloat animationDuration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];
UIViewAnimationCurve animationCurve = [notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
UIViewAnimationOptions animationOption = animationCurve << 16;
[UIView animateWithDuration:animationDuration delay:0 options:animationOption animations:^{
// adjust height using keyboardHeight
} completion:^(BOOL finished) {
}];
}
This blog post explains this in detail
http://charlie.cu.cc/2015/10/solution-to-the-ios-software-keyboard-cover-part-of-the-ui/