【问题标题】:Automatic adjustment of UIScrollView content offset with custom UIControl使用自定义 UIControl 自动调整 UIScrollView 内容偏移
【发布时间】:2014-11-24 16:28:53
【问题描述】:

UITextField 被添加到UIScrollview 时,滚动视图会自动调整其contentOffset,这样视图就不会被键盘遮挡。

我有一个自定义的UIControl,当它通过分配其inputView 属性成为第一响应者时,它也会显示一个键盘。相同的滚动行为不起作用。有没有办法配置 UIControl 以便在显示键盘时滚动视图保持可见?

我的猜测是,可以通过覆盖协议之一中定义的属性 UITextField 和此行为符合的其他类。但这些可能有点像迷宫。另请注意,这里的问题与滚动视图的contentInset 属性无关。滚动视图可以滚动以显示自定义控件,只是当控件成为第一响应者时它不会自动执行此操作。

【问题讨论】:

    标签: ios objective-c cocoa-touch uiscrollview uicontrol


    【解决方案1】:

    看起来这是由 Apple 使用 [UIFieldEditor scrollSelectionToVisible] 的内部私有方法处理的,如本博客所述:http://sugarrushva.my03.com/712423-disable-uiscrollview-scrolling-when-uitextfield-becomes-first-responder.html

    它似乎是通过逐步返回视图层次结构来做到这一点的,如果它找到父UIScrollView,它会滚动视图以将UITextField 带入可见视图。当您的自定义控件成为第一响应者时,您需要手动实现滚动,或者通过自省父视图来处理它。

    【讨论】:

    • 完美。提升视图层次结构对我来说似乎有点不舒服,但如果它有效,并且如果 API 没有提供预期的方法,它对我有用。我会用特定的 sn-ps 添加一个答案。
    【解决方案2】:

    @markflowers 为我指明了正确的方向。

    基于此,这是我写入控件以获得所需行为的内容:

    - (BOOL)becomeFirstResponder {
        if ([super becomeFirstResponder]) {
            [self scrollParentViewToFrame];
            return YES;
        }
        return NO;
    }
    
    - (void)scrollParentViewToFrame {
        UIScrollView *scrollView = self.parentScrollView;
        CGRect frame = [scrollView convertRect:self.bounds fromView:self];
        [self.parentScrollView scrollRectToVisible:frame animated:YES];
    }
    
    - (UIScrollView *)parentScrollView {
        return (UIScrollView *) [self closestParentWithClass:[UIScrollView class]];
    }
    

    请注意,如果控件不是滚动视图的直接后代,则不使用frame 属性。而是将边界转换为滚动视图的坐标空间。

    还需要在调用[super becomeFirstResponder] 之后执行滚动调整,以便它与用于调整滚动视图插图的键盘通知正确交互。

    我定义了在 UIView 类别中搜索最近的父滚动视图的方法,这使得递归搜索层次结构变得更加容易。

    - (UIView *)closestParentWithClass:(Class)class {
        if ([self isKindOfClass:class]) {
            return self;
        }
        // Recursively searches up the view hierarchy, returns nil if a view
        // has no superview.
        return [self.superview closestParentWithClass:class];
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-07
      • 1970-01-01
      • 1970-01-01
      • 2014-02-17
      相关资源
      最近更新 更多