1

I'm developing a chat app in ios and I have custom tableview and UIView with some textfield ane button on the bottom. I would like to move UIView and Tableview with keyboard when Textfield is activated. I have this obserer :

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasShown:) name:UIKeyboardWillShowNotification object:nil];

and then the keyboardWasShown method :

- (void)keyboardWasShown:(NSNotification*)aNotification{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
NSNumber *number = [info objectForKey:UIKeyboardAnimationDurationUserInfoKey];
double duration = [number doubleValue];
    [UIView animateWithDuration:duration animations:^{

        CGRect frame = textInputView.frame;
        if (UIDeviceOrientationIsPortrait([UIDevice currentDevice].orientation))
        {
            self.kHeight = kbSize.height;
        }
        else if(UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation))
        {
            self.kHeight = kbSize.width;
        }
        NSLog(@"keyboard up y =%f",self.kHeight);
        frame.origin.y -= self.kHeight;
        textInputView.frame = frame;

        frame = bubbleTable.frame;
        frame.size.height -= self.kHeight;
        bubbleTable.frame = frame;
    }];

It is working, but you notice that UIview doesn't move smoothly like in facebook or viber app. So I would like to ask what is the common approach for this. Thank you a lot!

beretis
  • 899
  • 1
  • 9
  • 24
  • Have you tried embedding your views within a scroll view, and changing the scroll view's content offset instead of the view's frame? – Kamaros Oct 16 '13 at 15:46
  • No I haven't I'm pretty new to Ios, and I didn't find reason for this, but. Im not sure how, but I will try. – beretis Oct 16 '13 at 15:50

3 Answers3

2

Embed your views in a scroll view (if you're using an Interface Builder, you can just click on your views, and Editor->Embed In->Scroll View from the top menu. Here's some sample code:

- (void)keyboardWasShown:(NSNotification *)notification
{
    NSDictionary *info = [notification userInfo];
    CGSize kbSize = [info[UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    // Flip kbSize if landscape.
    if (UIInterfaceOrientationIsLandscape([[UIDevice currentDevice] orientation])) {
        kbSize = CGSizeMake(kbSize.height, kbSize.width);
    }

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 1.0);
    [scrollView setContentInset:contentInsets];
    [scrollView setScrollIndicatorInsets:contentInsets];

    CGPoint scrollPoint = CGPointMake(0.0, [bubbleTable frame].origin.y - kbSize.height);
    [scrollView setContentOffset:scrollPoint animated:YES];
}
Kamaros
  • 4,536
  • 1
  • 24
  • 39
  • so I embeded tableview and textEditview in scroll view, but now the textEditView is located under visible screen and you have to scroll down for it, I wasn't able to fix it just with constraints. Do you have any idea? – beretis Oct 17 '13 at 13:31
  • If this is just an issue when the keyboard is shown, replace `[bubbleTable frame]` with `[textInputView frame]`. I was under the impression that the table view was at the bottom. If this is an issue when the keyboard is not visible, then your constraints are ambiguous. Scrolling is only necessary when the `contentSize` of the scroll view exceeds the size of the scroll view itself. – Kamaros Oct 17 '13 at 14:52
  • But in Xcode 5, there is a bug I guess and I'm not able to set positions with constrains correctly.Similar problem is described there: http://stackoverflow.com/questions/19036228/uiscrollview-scrollable-content-size-ambiguity-xcode-5-ios-7-interface-builder – beretis Oct 17 '13 at 21:29
  • Have you tried the "Add Missing Constraints" command? It's accessible from the last button in the group of four buttons that you usually set constraints from. – Kamaros Oct 17 '13 at 22:34
2

Swift 3

You can always move any view, or UIKit object by having a reference for its constraints (i.e. using Outlets)

@IBOutlet weak var someViewBottomConstraint: NSLayoutConstraint!

Then, register a notification in viewWillLayoutSubviews()

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow), name: .UIKeyboardWillShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide), name: .UIKeyboardWillHide, object: nil)
}

Once you done that, you need the 2 methods you're calling in viewWillLayoutSubviews()

func keyboardWillShow(_ notification: NSNotification) {
    let keyboardSize: CGSize = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue.size
    let height = min(keyboardSize.height, keyboardSize.width)
    someViewBottomConstraint.constant = height // you can add a value to the height to move it up/down.
    self.view.layoutIfNeeded() // this will auto animate the view motion with the keyboard

}

func keyboardWillHide() {
    someViewBottomConstraint.constant = 0 
    self.view.layoutIfNeeded()
}
Ennabah
  • 2,303
  • 2
  • 20
  • 39
0

Try this animation (experiments with options):

[UIView animateWithDuration:duration
                          delay:0
                        options:UIViewAnimationOptionAllowUserInteraction|UIViewAnimationOptionBeginFromCurrentState
                     animations:^{
                         //your animation
                     }
                     completion:nil];
user2828120
  • 233
  • 4
  • 13