UITableView move up when keyboard is active - ios

I have UITableView with UITextfields as the subview in contentView.
They work and all, but when I select the bottom ones, they are getting covered by the keyboard, so I want the UITableView to scroll up.
Here is my current code:
-(void)keyboardWillShow:(NSNotification*)notification {
NSValue *keyboardFrameValue = [[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey];
CGRect keyboardFrame = [[self view] convertRect:[keyboardFrameValue CGRectValue] fromView:nil];
[UIView animateWithDuration:0.3 animations:^{
[constraint setConstant:keyboardFrame.size.height];
[self.myTableView layoutIfNeeded];
}];
}
-(void)keyboardWillHide:(NSNotification *)notification {
[UIView animateWithDuration:0.3 animations:^{
[constraint setConstant:0];
[self.myTableView layoutIfNeeded];
}];
}
The problem with this is that it messes up the data, textfields are being added to the wrong Cells and stuff.
Hope that anyone can help out.

If possible, use an UITableViewController, the keyboard is handled automatically.
Otherwise, adjust the contentInset property of the table view as outlined by Apple.

Related

Extra space above keyboard view iOS

I have added code for pushing table view above keyboard. I have change the bottomLayout constraint of table view. But, he i set the constraint, there is an extra space above keyboard.
I have added sample code for keyboard showing notification.
- (void)keyboardWillShow:(NSNotification*)notification
{
CGRect rect = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect rectInView = [self.view rect fromView:nil];
[UIView animateWithDuration:0.25 animations:^{
self.bottomLayoutConstraint.constant = rectInView.size.height;
[self.view layoutIfNeeded];
}];
}
After this i got the following output in the keyboard.

UIView automatically moving by uitextfield keyboard

So i have a really weird problem at my hands and hours of search has provided nothing.
I have a uiview containing a uitextfield. Now initially this view is outside of the visible screen with coordinates like x=-500,y=-500.
However in response to a button press this view animates and moves into the center of the screen.
Now whenever i tap on a uitextfield that is the subview of this view.This view moves back to its original coordinates outside the screen.
I have frantically checked my code and there is nothing that is moving the view outside again once its in. Any help in explaining this very unfamiliar behaviour would be really appreciated.
This code moves the view onto the screen
- (IBAction)Register:(id)sender {
//(self.view.frame.size.width/2)-(self.SignUp_Screen.frame.size.width/2);
//self.login_Screen.hidden = YES;
self.blurView.hidden = NO;
//self.SignUp_Screen.layer.zPosition = 5;
NSLog(#"Register");
self.SignUp_Screen.hidden = NO;
[UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
self.SignUp_Screen.frame = CGRectMake(35, 50,self.SignUp_Screen.frame.size.width , self.SignUp_Screen.frame.size.height);
} completion:^(BOOL finished) {
}];
}
and these are the delegate methods for the textfield
-(void)textFieldDidEndEditing:(UITextField *)textField
{
NSLog(#"TextFieldEndEditing");
[textField resignFirstResponder];
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
NSLog(#"textFieldShouldReturn");
[textField resignFirstResponder];
return YES;
}
As Wezly hints at, if you are using autolayout, you don't modify the frame directly anymore. That's the old world. You want to have an Outlet / property for the constraint and animate it.
[UIView animateWithDuration:0.25
animations:^{
SignUp_Screen.centerXConstraint.constant = ...;
SignUp_Screen.centerYConstraint.constant = ...;
[SignUp_Screen layoutIfNeeded];
}];
See here and here for more details.
You should not modify frame if you are using auto layout. You should animate view by animating constraint's constant. For example:
NSLayoutConstraint *viewY; //constraint from superview top to view top
viewY.constant = 100;
[self.view setNeedsUpdateConstraints];
[UIView animateWithDuration:0.3f animations:^{
[self.view layoutIfNeeded];
}];
The way i solved this problem was by linking an IBOutlet to the constraint I wanted to change and then animating it's constant value.
.h
#interface ViewController : UIViewController {
IBOutlet NSLayoutConstraint *constraintHandle;
}
.m
[UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
constraintHandle.constant = self.view.center.x;
[SignUp_Screen layoutIfNeeded];
} completion:^(BOOL finished) {
}];
Don't forget to link the IBOutlet to your constraint in your storyboard or xib.

View not laid out properly when keyboard is hidden

I have a TextView. When keyboard appears, part of the TextView is hidden behind keyboard. So, I decrease its height by decreasing its bottom constraint(with its superview's bottom) so that user can scroll and see whole text.
But issue is when keyboard disappears its not resizing TextView's height to original. But when I tap on it, it shows whole text same as in first image.
How it looks normally :
How it looks when keyboard has appeared :
How it looks when keyboard has disappeared :
Now, if I tap on TextView it looks same as first image. i.e. resizes to have proper size :
Code : self.messageView is TextView.
// Called when keyboard is going to be displayed
- (void)keyboardWillShow:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
// get animation info from userInfo
NSTimeInterval animationDuration;
CGRect keyboardFrame;
[[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
[[info objectForKey:UIKeyboardFrameBeginUserInfoKey] getValue:&keyboardFrame];
// Save constant to set back later
self.bottomConstant = self.noticeMessageBottom.constant;
// Change bottom space constraint's constant
self.noticeMessageBottom.constant = keyboardFrame.size.height + 8.0f;
[UIView animateWithDuration:animationDuration delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
[self.messageView setNeedsLayout];
[self.messageView layoutIfNeeded];
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
} completion:nil];
[self.messageView flashScrollIndicators];
}
// Called when keyboard is going to be hidden
- (void)keyboardWillHide:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
// get animation info from userInfo
NSTimeInterval animationDuration;
CGRect keyboardFrame;
[[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
[[info objectForKey:UIKeyboardFrameBeginUserInfoKey] getValue:&keyboardFrame];
// Reset contentOffset
self.messageView.contentOffset = CGPointZero;
// Change bottom space constraint's constant
self.noticeMessageBottom.constant = self.bottomConstant;
[UIView animateWithDuration:animationDuration delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
[self.messageView setNeedsLayout];
[self.messageView layoutIfNeeded];
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
} completion:nil];
}
Update : I set background color to TextView and saw that height is changed properly but part of the text is not visible. It becomes visible when I tap on it.
Note : This happens only if TextView's contentOffset is (0,0).i.e user has not scrolled it. If user has scrolled it and contentOffset is not (0,0) then it works fine.
I just unchecked scroll enabled property of TextView in storyboard and its not giving that issue any more.

UITableView setEditing doesn't animate label constraint change

So, I have a custom tableview cell in tableview and when I set the editing mode on with the [self.tableView setEditing:YES animated:YES]; code.
It sets the editing mode but the problem is that my label on the cell just teleports to it's new location as it is pushed left when the reorder control shows itself. How can I animate the constraint change when the editing happens?
Picture of the my tableview cell:(The right constraint clearly increases when the editing goes on but it's not animated and I want it to be)
Edit: Here is my cell's setEditing.
I have tried to do it in many ways but the animation just doesn't work for some reason, the change happens instantly.
-(void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
if (editing) {
[UIView animateWithDuration:0.25f
delay:0.0f
options:UIViewAnimationOptionCurveEaseIn
animations:^{
self.labelConstraint.constant = 100;
[self layoutIfNeeded];
}
completion:^(BOOL finished)
{
}];
}
}
Worked for me if I change constraint before animation block
- (void) setEditing:(BOOL)editing animated:(BOOL)animated
{
[self layoutIfNeeded];
self.containerLeftConstraint.constant = editing ? EditingIndent : 0.0f;
[UIView animateWithDuration:0.3
animations:^{
[self layoutIfNeeded];
}];
}

How to remove view in Objective C

I have a View (CupsViewController) with a Label and when it's clicked, TableView (AddressTableController) slides from the bottom of the screen and stays in the lower half.
In TableView, when Ok Buttonis pressed, I want to change value of Labeland remove TableViewwith animation (that is, slide to the bottom).
Here is my code:
CupsViewController
Method called when click on Label
- (IBAction)showPop:(id)sender
{
addressTableController = [[AddressTableController alloc]initWithStyle:UITableViewStyleGrouped];
[addressTableController setDelegate:self];
[[self view] addSubview:[addressTableController myTableView]];
[UIView animateWithDuration:1.0 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
[[addressTableController myTableView] setFrame:CGRectMake(0, kScreenHeight * 0.5, kScreenWidth, kScreenHeight * 0.5)];
} completion:nil];
}
Method called from AddressTableControllerwhen Buttonis pressed
- (void)addressTableController:(AddressTableController *)viewController didChooseValue:(int)value {
direccionLabel.text = [[[[myAppDelegate usuarioActual] cups] objectAtIndex:value] direccion];
[addressTableController.view removeFromSuperview];
}
Image
As you can see, I've tried with removeFromSuperviewbut it does nothing. How can I slide TableViewto the bottom?
It seems that you myTableView property returns a different view, not the one that is referenced in the view property. So you basically add the former as a subview ([[self view] addSubview:[addressTableController myTableView]];), but try to remove the latter ([addressTableController.view removeFromSuperview];).
Just do
[[addressTableController myTableView] removeFromSuperview];
instead of
[addressTableController.view removeFromSuperview];
Here you go. Cheers, mate! :)
P.S.
if you want to animate the view out, you can do it like this
[UIView animateWithDuration:1.0 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
// animation code...
} completion:^(BOOL finished) {
[[addressTableController myTableView] removeFromSuperview];
}];

Resources