Landscape modal view with TPKeyboardAvoidingScrollView in FormSheet doesn't work
Hi,
I have a issue with a TPKeyboardAvoidingScrollView in a Modal View. The view never scroll when the keyboard s showed and hide the field that the user is editing.
Is it known issue?
The problem is with the form sheet presentation
I saw the error here! Let me explain it:
In UIScrollView+TPKeyboardAvoidingAdditions.m in the line 73 of this class you will see a if when it validate the ´firstResponder´ and you could see that the ´viewableHeight´ is:
CGFloat viewableHeight = self.bounds.size.height - self.contentInset.top - self.contentInset.bottom;
Then when the presentation style is a modalFormSheet this line of code doesn't work properly because the view is not the value to work around, you need to sum the bottom space below the modal (that translucent part), you could change that line to:
CGRect screenRect = [[UIScreen mainScreen] bounds]; CGFloat viewableHeight = screenRect.size.height - self.contentInset.top - self.contentInset.bottom;
Then you could get the real value that you need to move your scroll view up and show the textfield which the user is editing.
If anybody has a better solution please let me know.
I had the same problem. The following code displaces the content of a scrollview that lives inside of a modal regardless of whether the keyboard obscures anything. Modify it if you want to perform hit-testing and calculate the amount to displace by.
// UIView+KeyboardCovering.h
@interface UIView (KeyboardCovering)
- (CGFloat)heightCoveredByKeyboardOfSize:(CGSize)keyboardSize;
@end
// UIView+KeyboardCovering.m
#import "UIView+KeyboardCovering.h"
@implementation UIView (KeyboardCovering)
- (CGFloat)heightCoveredByKeyboardOfSize:(CGSize)keyboardSize {
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
CGRect frameInWindow = [self convertRect:self.bounds toView:nil];
CGRect windowBounds = self.window.bounds;
CGFloat keyboardTop;
CGFloat heightCoveredByKeyboard;
//Determine height of the view covered by the keyboard relative to current rotation
switch (orientation) {
case UIInterfaceOrientationLandscapeLeft:
keyboardTop = windowBounds.size.width - keyboardSize.width;
heightCoveredByKeyboard = CGRectGetMaxX(frameInWindow) - keyboardTop;
break;
case UIInterfaceOrientationLandscapeRight:
keyboardTop = windowBounds.size.width - keyboardSize.width;
heightCoveredByKeyboard = windowBounds.size.width - frameInWindow.origin.x - keyboardTop;
break;
case UIInterfaceOrientationPortraitUpsideDown:
keyboardTop = windowBounds.size.height - keyboardSize.height;
heightCoveredByKeyboard = windowBounds.size.height - frameInWindow.origin.y - keyboardTop;
break;
default:
keyboardTop = windowBounds.size.height - keyboardSize.height;
heightCoveredByKeyboard = CGRectGetMaxY(frameInWindow) - keyboardTop;
break;
}
return MAX(0.0f, heightCoveredByKeyboard);
}
@end
In your view controller:...
#import "UIView+KeyboardCovering.h"
- (void)viewDidLoad {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification object:nil];
}
// ...
- (void)keyboardWillShow:(NSNotification *)aNotification {
NSDictionary *userInfo = [aNotification userInfo];
CGSize keyboardSize = [userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
NSTimeInterval animationDuration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];
CGFloat heightCovered = [self.view heightCoveredByKeyboardOfSize:keyboardSize];
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, heightCovered, 0.0);
NSLog(@"Insets: %@", NSStringFromUIEdgeInsets(contentInsets));
NSLog(@"Scrollview: %@", self.scrollView);
CGPoint contentOffset = CGPointMake(0, heightCovered);
NSLog(@"Animating show");
[UIView animateWithDuration:animationDuration animations:^{
self.scrollView.contentOffset = contentOffset;
}];
}
// Called when the UIKeyboardDidHideNotification is sent
- (void)keyboardWillHide:(NSNotification *)aNotification {
NSTimeInterval animationDuration = [[aNotification userInfo] [UIKeyboardAnimationDurationUserInfoKey] floatValue];
NSLog(@"Animating hide");
[UIView animateWithDuration:animationDuration animations:^{
self.scrollView.contentOffset = CGPointZero;
}];
}