开发者

Position element to the bottom of the view

开发者 https://www.devze.com 2023-02-04 22:23 出处:网络
SHORT: When the view is shown on screen, it has a height of 460 points. When I slide it up to show the keyboard, it has a height of 480 points.

SHORT:

When the view is shown on screen, it has a height of 460 points. When I slide it up to show the keyboard, it has a height of 480 points.

LONG:

I have a view开发者_如何学Go that slides up when the keyboard appears.

I use the following code to calculate the new position of an input aligned to the bottom of the view:

self.view.bounds.size.height + self.view.frame.origin.y - inputHeight

It seems that self.view.bounds.size.height is 460 points and self.view.frame.origin.y is 0 when the keyboard is not displayed. This sound right, as the status bar accounts for 20 point at the top of the screen.

When the keyboard is displayed and the view is slided up by 216 points (height of the keyboard), I get a self.view.bounds.size.height of 676 and a self.view.frame.origin.y of -196, adding up to 480!

I need a better way to align the input to the bottom of the screen.


Is the idea behind this view to keep it attached to the top of the default system keyboard to extend the basic input functionality? If this is the case, which it sounds like it is, there is a much simpler built-in solution. Any class inheriting from UIResponder (any class that triggers the keyboard's appearance) can declare an Input Accessory View that will automatically stay attached to the top of the default keyboard.

EDIT: Okay, so that's not your situation. In that case, I'll share a method I've used in a few apps to translate various things with the keyboard's appearance manually. First, I prefer to get the details of the transformation from the system, instead of hardcoding values like 216. This keeps it nice and future-proof, in the (unlikely) event the keyboard's size is ever changed by Apple. This info is available in an NSNotification. To get the notification, register for it somewhere like this:

- (void)viewWillAppear:(BOOL)animated {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}

- (void)viewWillDisappear:(BOOL)animated {
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
}

Then, in the handlers:

- (void)_keyboardWillShow:(NSNotification *)notification {
    [self _animateWithKeyboardNotification:notification];
}

- (void)_keyboardWillHide:(NSNotification *)notification {
    [self _animateWithKeyboardNotification:notification];
}

And, for the main act:

- (void)_animateWithKeyboardNotification:(NSNotification*)keyboardNotification {
    /*   Animates a view with an animation constructed from the system keyboard
     *   animation properties.  The animation is a vertical translation to compensate
     *   for the area now covered by the keyboard.
     */

    UIViewAnimationCurve curve = [[keyboardNotification.userInfo valueForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];
    NSTimeInterval duration = [[keyboardNotification.userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    CGFloat keyboardHeight = [[keyboardNotification.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;

    // Set the transform based on the keyboard action: Translate up if showing, reset to identity when hiding
    CGAffineTransform animationTransform;
    if ([keyboardNotification.name isEqualToString:UIKeyboardWillShowNotification]) 
        animationTransform = CGAffineTransformMakeTranslation(0, -keyboardHeight);
    } else if ([keyboardNotification.name isEqualToString:UIKeyboardWillHideNotification]) {
        animationTransform = CGAffineTransformIdentity;
    }

    // Apply the animation.
    [UIView animateWithDuration:duration delay:0.0f options:curve animations:^ {
        self.view.transform = animationTransform;
    } completion:^ (BOOL finished) {
        // Completion handler, if needed.   
    }];
}

Now, with this exact method, I'm translating the entire view. You can tweak it to only translate your input view if you need to, or make any other small adjustments. I like this approach for its durability.

0

精彩评论

暂无评论...
验证码 换一张
取 消