How to pin a UIView to the bottom of its superview, but have it move when the keyboard appears? - ios

I have a UIView with a UIView and UITableView in it. The child UIView is for composition, it has textfield and a Send button like any messenger. How can I pin/fix this child UIView to the bottom of the Superview and keep it visibly on top of the UITableView? However the child UIView needs to also rise above the keyboard when its textfield is focused.

You can do this manually. You can sign up for getting keyboard notifications.
You can the following functions
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification object:nil];
There is a very good article about this on Apple Keyboard Management with code snippets.

The answer to your question is different for AutoLayout and for AutoResizingMasks (struts and springs) style layout.
For AutoLayout, the default for Xcode 6, what you would do would be to create a constraint to pin your view to the bottom of it's superview, as normal. Then you'd select that constraint in IB and control-drag it into the header file of your view controller, and create an IBOutlet for the constraint.
You can then write a notification handler for the keyboard will show notification, and in that handler, change the constant (offset) of your constraint property. The final step is to put a call to your superview's layoutIfNeeded method inside a UIView animation block. That causes the layout change from updating the constraint to be animated.
You then do the opposite for a keyboard will hide notification.
If you're doing struts-and-springs style layout, it's similar but simpler. You just create an outlet to the view that you want to move, and then make your keyboard will show notification handler use a UIView animation to animate a change to the view's center property .

Related

iPhone keyboard sizes

Is there a way to get the keyboard size programmatically before the keyboard is presented? In Objective-C
I need to set view.height constraint to be the same as keyboard.height programmatically. And it needs to happen before the keyboard is presented, so the view don't get this ugly constrain animation after the ViewController is presented.
I assume you present the keyboard by calling becomeFirstResponder on some UI component.
If the keyboard appears after your view is presented, you should check where that call is performed. Calling it in viewDidLoad or similarly early should cause the keyboard to be shown as the view animates in.
Your layout should also handle the keyboard changes properly. The keyboard size can change even after it's presented. For example the emoji/quick type keyboards are taller than the default keyboard.
You should perform your constraint changes in a combination of UIKeyboard[Will/Did]ShowNotification, UIKeyboard[Will/Did]HideNotification and UIKeyboardWillChangeFrameNotification. In your case, UIKeyboardWillShowNotification should do the trick.
The userInfo dictionary contains a lot of information about the keyboard. You find the final frame of the keyboard in UIKeyboardFrameEndUserInfoKey. If you animate the changes in your layout, you can use values in UIKeyboardAnimationCurveUserInfoKey and UIKeyboardAnimationDurationUserInfoKey to animate with the same animation as the keyboard.
- (void)viewDidLoad {
[super viewDidLoad];
// Don't forget to remove the observer when appropriate.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[self.textField becomeFirstResponder];
}
- (void)keyboardWillShow:(NSNotification *)notification {
CGFloat keyboardHeight = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;
[self.viewHeightConstraint setConstant:keyboardHeight];
// You can also animate the constraint change.
}
Such setup will also work if the keyboard is presented from the get-go.

ios force autolayout update on show keyboard

So, I have this view that is just a wrapper for the happy pink photo that i want to center in the view. I've been using two spacing views in between the Top Layout Guide and the top of the view that wraps the textbox and the send button at the bottom of the screen (the white ones). From the picture below you can see that is working just fine.
Now, since this is going to be a "leave your comment" page, the user needs to pull the keyboard up, and the autolayout noeeds to be updated accordingly. I tried to call [self.view setNeedsLayout], [self.view updateConstraints], [self.view layoutIfNeeded], but none of them does the trick. All I have is this:
You might object that I did something wrong in the autolayout, but then when I rotate the screen, the layout updates as expected, resizing the 2 spacing views and keeping the happy pink picture in the center:
How can I trigger a layout update?? I'm going crazy!!
Please tell me if you need any more informations
There could be many reasons why the layout is not behaving the way you want, It could be the constraints that define the height of the two white UIViews, the priority of the vertical hugging or compression resistance of this views, etc, but I guess this two views can be the source of the problem.
So, if the only purpose of the two white UIViews is to centre the pink photo I would suggest you get rid of them, instead you can put the pink photo inside a single UIView and centre the photo with a couple of alignment constraints
As you can see there are two align to centre constraints for the imageView, and three more constraints that help in case you support landscape orientation, if you are in landscape orientation the image probably won't fit in the blue view so you can add two greater than constraints and an aspect ratio constraint.
Now, the light blue view that contains the image only have four constraints: leading, trailing, top and a horizontal space constraint to the textField wrapper, so when the keyboard appears and move the textField wrapper up, the containerView shrinks and the image moves to the centre.
Add observers to notify you when the keyboard appears or disappears to adapt your view by the following:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
Then implement these methods.
- (void)keyboardWillShow:(NSNotification*)notification
{
CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
// the above is the keyboard size, implement prober view resizing as you wish, but i recommend a scrollview and you scroll it.
}
and then
- (void)keyboardWillHide:(NSNotification *)notification
{
//get everything back to original size or set the scrollview content size back to block scrolling.
}
at the end don't forget to remove yourself from being an observer for the keyboard when the view disappears
- (void)viewWillDisappear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}

How To move UITextView above the keyboard in iOS8?

In My app, I have an form with contains UITableView and inside UITableview I have place Mutiple UITextField and UITextView.
Whenever i click on UITextfield or UITextView Keypad comes up.
I am able to move the TextFiled UP when user click on UITextField ones they want to enter the data.But i am now able to move the TextView up when user want to enter the data.
Following is my code:
-(void)viewDidLoad
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardFrameDidChange:)
name:UIKeyboardDidChangeFrameNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification object:nil];
}
Can anyone help me out to move the UITextView UP above the keypad?
Thanks in Advance.
You can use this library
https://github.com/michaeltyson/TPKeyboardAvoiding
It will handle with frame when show hide keyboard for uitextfiled and uitextView.
And you make sure you do like this:
Adding a "container" view in the case of a ScrollView with constraints set to the superview is also a good practice as follows: ViewController -> UIScrollView (TPKeyboardAvoidingScrollView) -> UIView (container for UI elements) -> UITextView. If you want vertical scrolling set the height constraint to be '>='.
Use IQKeyboardManager to handle this problem.
Features:
1) CODELESS, Zero Line Of Code
2) Works Automatically
3) No More UIScrollView
4) No More Subclasses
5) No More Manual Work
6) No More #imports
And its available for both languages (Swift and Objective C)

Can I set frame of particular view programatically even if Auto Layout is enabled?

Suppose I am having a view controller A having 5 views inside it like labels, buttons. I have set constraint to 4 views. But, for 5th view, case is different. In portrait, I need different x,y positions and height and width. In landscape, I need different x,y positions and height and width. So, it is not possible to define constraints for that because it's a custom. I will only have to set frame programmatically wherever I wanted my view to be placed in different orientation.
Is there any solution for that?
After detecting the orientation you can use the IBOutlets of your connected control to set the frame for example :
[myView setFrame:CGRectMake(x,y,width,height)];
I hope this helps you.
EDIT
first create a constraint in the story board or your IB then create an outlet for that constraint for ex :
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *viewHeightConstraint;
then change this constraint programmatically like :
self.viewHeightConstraint.constant = 40;
Option 1
Add this to your viewcontroller,and use it to monitor your device orientation,than change your 5th view frame
-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator{
}
Option 2
In viewDidLoad add
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(change:) name:UIDeviceOrientationDidChangeNotification object:nil];
Then in this function you can monitor orientation change
-(void)change:(UIDeviceOrientation)orientation{
}
In dealloc,remove it
-(void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
}

TextField- KeyBoard Optimization - iOS [duplicate]

This question already has answers here:
How can I make a UITextField move up when the keyboard is present - on starting to edit?
(98 answers)
Closed 9 years ago.
Whenever I click on textfield, keyboard pops up and partially blocked other textfields as seen in the image, how could I manage it? I want whenever last textfield on the right bottom filled, then second row should be up and visible ! By the way, Scroll view on the top of ViewController.
-(void)ViewDidLoad
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil];
}
- (void)keyboardDidShow:(NSNotification *)notification
{
[self.view setFrame:CGRectMake(0,-260,1030,768)];
}
-(void)keyboardDidHide:(NSNotification *)notification
{
[self.view setFrame:CGRectMake(0,0,1030,768)];
}
Wrap your view in an UIScrollView!
You need to change the view size when the keyboard comes up and change it back when keyboard disappears. Use a scrollview and the keyboard notification or textfield delegate methods for when keyboard appears/disappears.
You need to setup observation of UIKeyboardWillChangeFrameNotification and UIKeyboardDidChangeFrameNotification or UIKeyboardDidShowNotification and UIKeyboardDidHideNotification. When you receive the notifications you will have the trigger to move/resize the content of your view and the size of the keyboard that's being displayed so you know how much to move/resize it.
You may also find it useful to act as the delegate of the text fields and implement textFieldDidBeginEditing:. When this method is called you know that the supplied text field should be visible. You can get the frame of the text field (which you may need to translate if there are multiple superviews before you get to the scroll view) and use it to scrollRectToVisible:animated: (or just set the contentOffset).

Resources