使用动画块调整UIScrollView的大小会移动其起始位置。

5

我正在处理一个问题,即当键盘会遮挡UITextField时,我需要将UIScrollView向上滚动。如果被遮挡,我会减小UIScrollView的高度,这个操作很好用。但是当我尝试增加UIScrollView的高度(回到原始大小)时,整个UIScrollView向上移动,然后以动画方式向下移动回到原始大小和位置。其原点会上移X个单位,并向下移动到应该在的位置,而不是视图高度向下扩展。

- (void)keyboardWillShow:(NSNotification *)n
{
    keyboardMove = self.rightScrollView.frame;
    offsetMove = self.rightScrollView.contentOffset;

    NSDictionary* userInfo = [n userInfo];

    CGSize keyboardSize = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    [UIView animateWithDuration:.25
                          delay:0
                        options:(UIViewAnimationOptionAllowUserInteraction)
                     animations:^
                     {
                         self.rightScrollView.frame = CGRectMake(self.rightScrollView.frame.origin.x, self.rightScrollView.frame.origin.y, self.rightScrollView.frame.size.width, (self.view.frame.size.height - (self.rightScrollView.frame.origin.y + keyboardSize.height)));
                     }
                     completion:nil];

    if ((activeTextField.frame.origin.y + activeTextField.frame.size.height) > self.rightScrollView.frame.size.height)
    {        
        float contentOffsetMove = (self.rightScrollView.contentOffset.y + (activeTextField.frame.origin.y - self.rightScrollView.frame.size.height) + activeTextField.frame.size.height + 10);

        self.rightScrollView.contentOffset = CGPointMake(self.rightScrollView.contentOffset.x, contentOffsetMove);
    }
}

- (void)keyboardWillHide:(NSNotification *)n
{
    if ((activeTextField.frame.origin.y + activeTextField.frame.size.height) > self.rightScrollView.frame.size.height)
    {
        [UIView animateWithDuration:.25
                              delay:0
                            options:(UIViewAnimationOptionAllowUserInteraction)
                         animations:^{
                             [self.rightScrollView setContentOffset:offsetMove animated:YES];

                             self.rightScrollView.frame = keyboardMove;
                         }
                         completion:nil];

    }
    else
    {
        [UIView animateWithDuration:.25
                              delay:0
                            options:(UIViewAnimationOptionAllowUserInteraction)
                         animations:^{
                             self.rightScrollView.frame = keyboardMove;
                         }
                         completion:nil];
    }
}

所以,当键盘隐藏时,self.rightScrollView.origin会向上移动X个点,然后动画到应该在的位置。我需要起点保持不变,高度增加(向下增长)。

有任何想法为什么它的行为怪异?


你解决了这个问题吗?我也遇到了完全相同的问题,但找不到解决方案。 - pnizzle
3个回答

3

我不知道您是否还对答案感兴趣,因为我发现这里的最后一次活动是一年前,但今天我在iOS 6中遇到了完全相同的问题,并决定与任何仍然感兴趣的人分享我的解决方案。

我注意到UIScrollView向上移动的偏移量是键盘高度的一半,但仅当UIScrollView的内容被偏移时才是如此。所以我的解决办法是,在动画之前,如果UIScrollView的内容偏移量大于0,则将UIScrollView向下移动相同的量。目前这在iPhone 4(3.5英寸显示屏)和iPhone 5(4英寸显示屏)上都可以很好地工作,但我不知道如果苹果公司决定修复这个 UIKit bug,会发生什么。

无论如何,为了清晰起见,这是我的代码:

- (void)keyboardWillHide:(NSNotification *)notification
{
    CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    if (self.scrollView.contentOffset.y > 0) {
        CGRect f = CGRectMake(0, keyboardSize.height / 2, self.scrollView.frame.size.width, self.scrollView.frame.size.height);
        self.scrollView.frame = f;
    }

    [UIView animateWithDuration:0.25 animations:^{
        self.scrollView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
    }];
}

2

我认为这可能是UIKit中的一个bug,但解决方法是使用scrollView的contentInset而不是调整frame。所以:

不要使用

self.rightScrollView.frame = CGRectMake(self.rightScrollView.frame.origin.x,
                                        self.rightScrollView.frame.origin.y,
                                        self.rightScrollView.frame.size.width,
                                        (self.view.frame.size.height - (self.rightScrollView.frame.origin.y + keyboardSize.height)));

self.rightScrollView.contentInset = UIEdgeInsetsMake(0, 0, keyboardSize.height, 0);

这确实移动了插入符,但并没有达到我想要的效果。现在,我缩小了我的框架,如果文本框的原点大于(即在框架下方),则将contentOffset向上移动滚动视图的内容。您的建议保持滚动视图的框架不变,只是移动插入符,导致一些文本框被键盘遮挡。 - Padin215
那么这就是一个滚动问题,不是吗?- (void)scrollRectToVisible:(CGRect) animated:(BOOL); 可能会有所帮助。 - Joony

0
你尝试过按照你想要的动画效果详细描述出来吗?例如,如果你想要高度增加,就直接这样做。而不是使用


self.rightScrollView.frame = keyboardMove; 

你可以这样做

CGRect f = self.rightScrollView.frame;
f.size.height += keyboardMove.size.height - f.size.height;
self.rightScrollView.frame = f; 

我一直在考虑这个问题。这里有另一个想法:如果这只发生在 UIScrollView 上,为什么不在动画之前尝试将 scrollEnabled 属性设置为 NO 呢? - Mundi
我自己仍然遇到这个问题。 - Will Larche

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接