i have a simple app, it consist of 2 textview, 1 uiview as a coretext subclass, and then 1 scrollview. the others part is subviews from scrollview. I use this scrollview because i need to scroll the textviews and uiview at the same time. I already scroll all of them together, but the problem is, the keyboard hiding some lines in the textview. I have to change the frame of scrollview when keyboard appear, but it still not help.
This is my code :
UIScrollView *scrollView;
UIView *viewTextView;
UITextView *lineNumberTextView;
UITextView *codeTextView;
-(void) viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(keyboardWillAppear:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(keyboardWillDisappear:)
name:UIKeyboardWillHideNotification
object:nil];
self.scrollView.frame = CGRectMake(0, 88, self.codeTextView.frame.size.width,
self.codeTextView.frame.size.height);
scrollView.contentSize = CGSizeMake(self.view.frame.size.width, viewTextView.frame.size.height);
[scrollView addSubview:viewTextView];
CGAffineTransform translationCoreText = CGAffineTransformMakeTranslation(60, 7);
[viewTextView setTransform:translationCoreText];
[scrollView addSubview:lineNumberTextView];
[self.scrollView setScrollEnabled:YES];
[self.codeTextView setScrollEnabled:NO];
}
-(void)keyboardWillAppear:(NSNotification *)notification {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:[[[notification userInfo]
objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
CGRect keyboardEndingUncorrectedFrame = [[[notification userInfo]
objectForKey:UIKeyboardFrameEndUserInfoKey ] CGRectValue];
CGRect keyboardEndingFrame =
[self.view convertRect:keyboardEndingUncorrectedFrame
fromView:nil];
self.scrollView.frame = CGRectMake(0, 88, self.codeTextView.frame.size.width,
self.codeTextView.frame.size.height - keyboardEndingFrame.size.height);
[UIView commitAnimations];
}
-(void)keyboardWillDisappear:(NSNotification *) notification {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:[[[notification userInfo]
objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
CGRect keyboardEndingUncorrectedFrame = [[[notification userInfo]
objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect keyboardEndingFrame =
[self.view convertRect:keyboardEndingUncorrectedFrame
fromView:nil];
self.scrollView.frame = CGRectMake(0, 88, self.codeTextView.frame.size.width,
self.codeTextView.frame.size.height + keyboardEndingFrame.size.height);
[UIView commitAnimations];
}
can somebody help me please?
UPDATE
this is a pic from this problem :
some text still hiding by the keyboard after i do my code
UPDATE AGAIN
i think the keyboard still hiding the text because i set the textview scroll enable to be NO. is that right??
i have add this code to the keyboardwillappear method
codeBuilderSelectedRange = self.codeTextView.selectedRange;
[self.viewTextViewScroll setContentOffset:CGPointMake(0, (CGFloat)codeBuilderSelectedRange.location) animated:YES];
but it just make the textview dissappear from the view...can somebody tell the answer?
#pragma mark -------------------------
#pragma mark TextView delegate Methods
- (void)textViewDidBeginEditing:(UITextView *)textView {
UIView *parentView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 60, 44)];
UIButton *infoButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 6, 60, 32)];
[infoButton setBackgroundImage:[UIImage imageNamed: #"back-btn.png"] forState:UIControlStateNormal];
[infoButton setTitle:#"Done" forState:UIControlStateNormal];
infoButton.titleLabel.font = [UIFont systemFontOfSize:13.0f];
[infoButton addTarget:self action:#selector(resignTextView) forControlEvents:UIControlEventTouchUpInside];
[parentView addSubview:infoButton];
[infoButton release];
UIBarButtonItem *customBarButtomItem = [[UIBarButtonItem alloc] initWithCustomView:parentView];
[parentView release];
self.navigationItem.rightBarButtonItem = customBarButtomItem;
[customBarButtomItem release];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
[UIView commitAnimations];
CGRect frame = self.scrollView.frame;
self.scrollView.frame.size.height = 206;
//[self.view setContentOffset:CGPointMake(0,320)];
}
- (void)resignTextView {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
[UIView commitAnimations];
CGRect frame = self.scrollView.frame;
self.scrollView.frame.size.height = 460;
[messageTextView resignFirstResponder];
self.navigationItem.rightBarButtonItem = nil;
}
Here is some code that I have used. Basically, what we're going to do is animate the position of the view whenever a UITextField gets focus. To do this, we must make our UIViewController a delegate of our UITextFields
The first delegate method you need to implement is - (void)textFieldDidBeginEditing:(UITextField *)textField
static const CGFloat KEYBOARD_ANIMATION_DURATION = 0.3;
static const CGFloat MINIMUM_SCROLL_FRACTION = 0.2;
static const CGFloat MAXIMUM_SCROLL_FRACTION = 0.8;
static const CGFloat PORTRAIT_KEYBOARD_HEIGHT = 216;
static const CGFloat LANDSCAPE_KEYBOARD_HEIGHT = 162;
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
CGRect textFieldRect = [self.view.window convertRect:textField.bounds
fromView:textField];
CGRect viewRect = [self.view.window convertRect:self.view.bounds
fromView:self.view];
CGFloat midline = textFieldRect.origin.y + 0.5
* textFieldRect.size.height;
CGFloat numerator = midline - viewRect.origin.y
- MINIMUM_SCROLL_FRACTION * viewRect.size.height;
CGFloat denominator = (MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION)
* viewRect.size.height;
CGFloat heightFraction = numerator / denominator;
if (heightFraction < 0.0)
{
heightFraction = 0.0;
}
else if (heightFraction > 1.0)
{
heightFraction = 1.0;
}
UIInterfaceOrientation orientation =
[[UIApplication sharedApplication] statusBarOrientation];
if (orientation == UIInterfaceOrientationPortrait ||
orientation == UIInterfaceOrientationPortraitUpsideDown)
{
animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);
}
else
{
animatedDistance = floor(LANDSCAPE_KEYBOARD_HEIGHT * heightFraction);
}
CGRect viewFrame = self.view.frame;
viewFrame.origin.y -= animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
}
Now that the view has been 'pushed up' when a UITextField is selected, we want to make sure that we slide it back down when we're done:
- (void) textFieldDidEndEditing:(UITextField *)textField
{
CGRect viewFrame = self.view.frame;
viewFrame.origin.y += animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
This was taken from one of my favorite Cocoa blogs, Cocoa With Love. Cheezy name, but Matt's got some great posts on Objective-C development.
Specifically for UITextView (not UITextField)
you may have a look at the following tutorial: http://codingcluster.blogspot.in/2012/03/iphone-make-uitextview-move-up-when.html
i have implemented it and it is working as expected(at least for me)
Related
In my iPad im creating SplitView application. I have a UITableVewtable with multiple rows, each row/cell having three UITextField
When i tap on UITextField some fields are hide by the keyboard.
So im using TPKeyboardAvoidingScrollView framework but it does not works on ios 5.0+.
some times unable to scroll the scroll view on the table.
So I want to move the focussed cell to the middle/ just above the key board at every time
What should I use?
Thanks in Advance.
Try this code. Put this in your .h file :
CGFloat animatedDistance;
In your .m file :
static const CGFloat KEYBOARD_ANIMATION_DURATION = 0.3;
static const CGFloat MINIMUM_SCROLL_FRACTION = 0.2;
static const CGFloat MAXIMUM_SCROLL_FRACTION = 0.8;
static const CGFloat PORTRAIT_KEYBOARD_HEIGHT = 264;
static const CGFloat LANDSCAPE_KEYBOARD_HEIGHT = 352;
Add this static const before your #interface myclass () You can change the keyboard height values above as per your need. And then add the following code :
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
CGRect textFieldRect =
[self.view.window convertRect:textField.bounds fromView:textField];
CGRect viewRect =
[self.view.window convertRect:self.view.bounds fromView:self.view];
CGFloat midline = textFieldRect.origin.y + 0.5 * textFieldRect.size.height;
CGFloat numerator = midline - viewRect.origin.y - MINIMUM_SCROLL_FRACTION * viewRect.size. height;
CGFloat denominator =
(MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION) * viewRect.size.height;
CGFloat heightFraction = numerator / denominator;
if (heightFraction < 0.0)
{
heightFraction = 0.0;
}
else if (heightFraction > 1.0)
{
heightFraction = 1.0;
}
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
if (orientation == UIInterfaceOrientationPortrait ||
orientation == UIInterfaceOrientationPortraitUpsideDown)
{
animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);
}
else
{
animatedDistance = floor(LANDSCAPE_KEYBOARD_HEIGHT * heightFraction);
}
CGRect viewFrame = self.view.frame;
viewFrame.origin.y -= animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
CGRect viewFrame = self.view.frame;
viewFrame.origin.y += animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
what you want is to animate your view such as when you touch the textField it should go up and when you end typing it should go down. You can achieve this by implementing two UITextFiled delegate methods and some little animation as follows :
- (void)textFieldDidEndEditing:(UITextField *)textField
{
[self startAnimatingTextField: textField up: NO];
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[self startAnimatingTextField: textField up: YES];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.1];
[UIView setAnimationCurve: UIViewAnimationCurveLinear];
[UIView commitAnimations];
}
-(void)startAnimatingTextField:(UITextField *) textField up: (BOOL) up
{
const int distance = 120; /* modify conform your needs */
const float duration = 0.3f;
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];
}
Hope this helps !
First open the xib file and set the Content insets(In Scrollview Size) to 200
Now update following two methods as below in .m file.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cell=#"Cell";
Cell *customCell= (Cell *)[tableView dequeueReusableCellWithIdentifier:cell];
if (customCell==nil) {
NSArray *bundle = [[NSBundle mainBundle] loadNibNamed:#"Cell" owner:self options:nil];
for (id object in bundle) {
if ([object isKindOfClass:[Cell class]])
{
customCell = (Cell *)object;
break;
}
}
}
customCell.IBTxtfield.tag=indexPath.row;
return customCell;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField{
NSIndexPath *path=[NSIndexPath indexPathForRow:textField.tag inSection:0];
[IBtblView scrollToRowAtIndexPath:path atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
So I have about 7 textfields and 6 of them use a keyboard and the other uses a picker. The problem I'm having is that if the keyboard is open when the textfield that is linked to the picker is touched the keyboard won't dismiss and the picker appears under it. Here's my code
- (void) textFieldDidBeginEditing:(UITextField *)textField
{
pickerView.hidden = YES;
if ([textField isEqual:state])
{
[state resignFirstResponder];
[self textFieldFirstResponderOnDelay1];
}
else
{
pickerView.hidden = YES;
// This movie the view up so textfield isn't hidden by keyboard
CGRect textFieldRect =
[self.view.window convertRect:textField.bounds fromView:textField];
CGRect viewRect =
[self.view.window convertRect:self.view.bounds fromView:self.view];
CGFloat midline = textFieldRect.origin.y + 0.5 * textFieldRect.size.height;
CGFloat numerator =
midline - viewRect.origin.y
- MINIMUM_SCROLL_FRACTION * viewRect.size.height;
CGFloat denominator =
(MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION)
* viewRect.size.height;
CGFloat heightFraction = numerator / denominator;
if (heightFraction < 0.0)
{
heightFraction = 0.0;
}
else if (heightFraction > 1.0)
{
heightFraction = 1.0;
}
UIInterfaceOrientation orientation =
[[UIApplication sharedApplication] statusBarOrientation];
if (orientation == UIInterfaceOrientationPortrait ||
orientation == UIInterfaceOrientationPortraitUpsideDown)
{
animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);
}
else
{
animatedDistance = floor(LANDSCAPE_KEYBOARD_HEIGHT * heightFraction);
}
CGRect viewFrame = self.view.frame;
viewFrame.origin.y -= animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
}
-(void) viewDidLoad
{
pickerView = [[UIPickerView alloc] init];
pickerView.frame = CGRectMake(0, 245, 320, 216);
pickerView.delegate = self;
pickerView.hidden = YES;
pickerView.showsSelectionIndicator = YES;
state.inputView = pickerView;
[self.view addSubview:pickerView];
}
-(void)textFieldFirstResponderOnDelay1
{
pickerView.hidden=NO;
[pickerView reloadAllComponents];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
if([textField isEqual:state])
{
}
else
{
CGRect viewFrame = self.view.frame;
viewFrame.origin.y += animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
}
Instead of adding the pickerview as a subview of your main window, just set it as the input view for the appropriate textviews, then it will show/hide as the keyboard would normally:
textField.inputView = pickerView;
I have added some table and other vies in a scrollview. scrolling in tables are working fine. But in the parent scrollview, when scrolling, a vacillating vertical scrollbars are shown, sometimes it even come to the middle of the screen. sometime show at the left side of the screen. and not limited to the vertical scrollbar region. When I set the showsVerticalScrollIndicator = NO, it is not shown. But do you know why the scrollbar is moving around.
DashboardView is a subclass of UIScrollView.
dashboard=[[DashboardView alloc] initWithFrame:fullScreenRect];
dashboard.contentSize = CGSizeMake(320,700); // must do!
dashboard.showsVerticalScrollIndicator = YES;
dashboard.bounces = YES;
self.view = dashboard;
#implementation DashboardView
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
// Initialization code
}
return self;
}
- (void)drawRect:(CGRect)rect {
// Drawing code
}
- (void) layoutSubviews{
NSArray *views = self.subviews;
[UIView beginAnimations:#"CollapseExpand" context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
UIView *view = [views objectAtIndex: 0];
CGRect rect = view.frame;
for (int i = 1; i < [views count]; i++ ) {
view = [views objectAtIndex:i];
view.frame = CGRectMake(rect.origin.x, rect.origin.y + rect.size.height, view.frame.size.width, view.frame.size.height);
rect = view.frame;
}
[UIView commitAnimations];
}
Remember that scrollbars is subviews of scroll too. Exclude it from views array, before doing something with views.
Yap. that solved my problem. It seems Scrollbars are a kind of UIImageView. If anybody need it, this is my new code which works fine.
(void) layoutSubviews{
NSArray *views = self.subviews;
[UIView beginAnimations:#"CollapseExpand" context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
//CGRect fullScreenRect=[[UIScreen mainScreen] applicationFrame];
// [self.view insertSubview:balanceView belowSubview:profileView];
UIView *view = [views objectAtIndex: 0];
CGRect rect = view.frame;
for (int i = 1; i < [views count]; i++ ) {
view = [views objectAtIndex:i];
if ([view isMemberOfClass: [UIView class] ]) {
//CFShow(view);
view.frame = CGRectMake(rect.origin.x, rect.origin.y + rect.size.height, view.frame.size.width, view.frame.size.height);
rect = view.frame;
}
}
[UIView commitAnimations];
}
I have a UIToolbar at bottom of my view, and I have a UITextField in this toolbar. When I begin editing this field, it is hidden behind the keyboard. To see what I've typed, I want to move the toolbar up at the moment the keyboard is presented (and then move it back down when I've finished editing).
How do I move this UIToolbar up/down?
add your viewController class to the list of observers of UIKeyboardWillShowNotification/UIKeyboardWillHideNotification. then you can move your view to make your textView visible. You can also get animation parameters from this notifications to synchronize your animation with keyboard animation parameters of the current OS version. this code I've used for paging
- (void) viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(liftMainViewWhenKeybordAppears:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(returnMainViewToInitialposition:) name:UIKeyboardWillHideNotification object:nil];
}
- (void) viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
in the methods below I set two methods to handle keyboard notifications. and here are this methods:
- (void) liftMainViewWhenKeybordAppears:(NSNotification*)aNotification{
NSDictionary* userInfo = [aNotification userInfo];
NSTimeInterval animationDuration;
UIViewAnimationCurve animationCurve;
CGRect keyboardFrame;
[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
[[userInfo objectForKey:UIKeyboardBoundsUserInfoKey] getValue:&keyboardFrame];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationCurve:animationCurve];
[self.view setFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y - keyboardFrame.size.height, self.view.frame.size.width, self.view.frame.size.height)];
[UIView commitAnimations];
}
- (void) returnMainViewToInitialposition:(NSNotification*)aNotification{
NSDictionary* userInfo = [aNotification userInfo];
NSTimeInterval animationDuration;
UIViewAnimationCurve animationCurve;
CGRect keyboardFrame;
[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
[[userInfo objectForKey:UIKeyboardBoundsUserInfoKey] getValue:&keyboardFrame];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationCurve:animationCurve];
[self.view setFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y + keyboardFrame.size.height, self.view.frame.size.width, self.view.frame.size.height)];
[UIView commitAnimations];
}
Thanks that worked!
Here is a slight improvement:
- (void) liftMainViewWhenKeybordAppears:(NSNotification*)aNotification{
[self scrollViewForKeyboard:aNotification up:YES];
}
- (void) returnMainViewToInitialposition:(NSNotification*)aNotification{
[self scrollViewForKeyboard:aNotification up:NO];
}
- (void) scrollViewForKeyboard:(NSNotification*)aNotification up: (BOOL) up{
NSDictionary* userInfo = [aNotification userInfo];
// Get animation info from userInfo
NSTimeInterval animationDuration;
UIViewAnimationCurve animationCurve;
CGRect keyboardFrame;
[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
[[userInfo objectForKey:UIKeyboardBoundsUserInfoKey] getValue:&keyboardFrame];
// Animate up or down
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationCurve:animationCurve];
[self.view setFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y + (keyboardFrame.size.height * (up?-1:1)), self.view.frame.size.width, self.view.frame.size.height)];
[UIView commitAnimations];
}
Building on the answers above and using the convenience method [UIView animateWithDuration...]. Observe the will show/hide keyboard notifications and use these handlers.
- (void)keyboardWillShow:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
NSNumber *durationValue = info[UIKeyboardAnimationDurationUserInfoKey];
NSNumber *curveValue = info[UIKeyboardAnimationCurveUserInfoKey];
NSValue *endFrame = info[UIKeyboardFrameEndUserInfoKey];
[UIView animateWithDuration:durationValue.doubleValue
delay:0
options:(curveValue.intValue << 16)
animations:^{
self.navigationController.toolbar.frame = CGRectMake(0,
[endFrame CGRectValue].origin.y - self.navigationController.toolbar.bounds.size.height,
self.navigationController.toolbar.bounds.size.width,
self.navigationController.toolbar.bounds.size.height);
}
completion:nil];
}
- (void)keyboardWillHide:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
NSNumber *durationValue = info[UIKeyboardAnimationDurationUserInfoKey];
NSNumber *curveValue = info[UIKeyboardAnimationCurveUserInfoKey];
[UIView animateWithDuration:durationValue.doubleValue
delay:0
options:(curveValue.intValue << 16)
animations:^{
self.navigationController.toolbar.frame = CGRectMake(0,
self.view.bounds.size.height - self.navigationController.toolbar.bounds.size.height,
self.navigationController.toolbar.bounds.size.width,
self.navigationController.toolbar.bounds.size.height);
}
completion:nil];
}
Thank you so much for this; it works great. However, the code as presented has 2 limitations as I experienced them:
1) The view being repositioned simply slides up out of the screen rather than resizing to fit the space available after the keyboard appears
2) Repeat notifications due to switching text fields continue to apply the frame change, causing the view to incrementally fly off the screen.
The cause is that the above is a reposition relative to the view's current frame rather than a resize relative to the keyboard. Here are two amended lines of code which fix this:
In liftMainViewWhenKeybordAppears:, resize rather than reposition, relative to the keyboard:
keyboardFrame = [self.view.window convertRect:keyboardFrame toView:self.view.superview];
CGRect superviewFrame = [self.view.window convertRect:self.view.superview.frame toView:self.view];
[self.view setFrame:CGRectMake(self.view.frame.origin.x,
self.view.frame.origin.y,
self.view.frame.size.width,
superviewFrame.size.height - keyboardFrame.size.height)];
In returnMainViewToInitialposition:, change the animation to this setFrame: (essentially akin to the identity transform).
[self.view setFrame:CGRectMake(self.view.frame.origin.x,
self.view.frame.origin.y,
self.view.frame.size.width,
keyboardFrame.origin.y + keyboardFrame.size.height)];
Here is a more elegant solution using uiview category
#import <Foundation/Foundation.h>
#interface UIView(AnimationUtils)
-(void)scrollControlToCenter:(UIView *)view;
-(void)scrollViewToOriginalPosition;
#end
#import "UIView+AnimationUtils.h"
#implementation UIView(AnimationUtils)
#pragma mark ScrollView Methods
//Method Called whenever keyboard appears
- (void)scrollControlToCenter:(UIView *)view {
if([view isKindOfClass:[UITextField class]]){
CGRect viewFrame = [view frame];
float verticalDistance = 216.0f - viewFrame.origin.y - (2*viewFrame.size.height);
if(viewFrame.size.height >= (460 - 216)/2){
verticalDistance = 0;
}
[UIView beginAnimations:#"ScrollToCenter" context:nil];
[UIView setAnimationDuration:0.5];
[self setFrame:CGRectMake(0, verticalDistance, self.frame.size.width, self.frame.size.height)];
[UIView commitAnimations];
}else if([view isKindOfClass:[UITextView class]]){
[UIView beginAnimations:#"ScrollToTop" context:nil];
[UIView setAnimationDuration:0.5];
UIView *viewBG = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
[viewBG setTag:5];
[viewBG setBackgroundColor:[UIColor blackColor]];
[viewBG setAlpha:0.75];
[self addSubview:viewBG];
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, view.frame.size.height)];
[self setFrame:CGRectMake(0, -view.frame.origin.y , self.frame.size.width, self.frame.size.height)];
[self insertSubview:view atIndex:[self.subviews count] + 1];
[UIView commitAnimations];
}
}
-(void)scrollViewToOriginalPosition{
[UIView beginAnimations:#"ScrollToOriginal" context:nil];
[UIView setAnimationDuration:0.5];
for(UIView *view in self.subviews){
if(view.tag == 5){
[view removeFromSuperview];
}
}
[self setFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
[UIView commitAnimations];
}
#pragma mark -
#end
as title, can i position the UITableViewCellEditingStyleDelete button/icon to be within the tableviewcell of a grouped tableview rather than outside of it?
An excerpt from a Matt Gallagher blog post reveals a method
This is the original code to mimic the behavior you DON'T want:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[self setNeedsLayout];
}
- (void)layoutSubviews
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationBeginsFromCurrentState:YES];
[super layoutSubviews];
if (((UITableView *)self.superview).isEditing)
{
CGRect contentFrame = self.contentView.frame;
contentFrame.origin.x = EDITING_HORIZONTAL_OFFSET;
self.contentView.frame = contentFrame;
}
else
{
CGRect contentFrame = self.contentView.frame;
contentFrame.origin.x = 0;
self.contentView.frame = contentFrame;
}
[UIView commitAnimations];
}
So if we made a change, we can make it do what you do want:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[self setNeedsLayout];
}
- (void)layoutSubviews
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationBeginsFromCurrentState:YES];
[super layoutSubviews];
if (((UITableView *)self.superview).isEditing)
{
//don't resize and and move your frame here
CGRect contentFrame = self.contentView.frame;
contentFrame.origin.x = 0;
self.contentView.frame = contentFrame;
}
else
{
CGRect contentFrame = self.contentView.frame;
contentFrame.origin.x = 0;
self.contentView.frame = contentFrame;
}
[UIView commitAnimations];
}
You'll proabably have to tweak this, but it is a good start.