使用自定义 UIControl 自动调整 UIScrollView 内容偏移量



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

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

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

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

似乎通过向上跨入视图层次结构来做到这一点,如果它找到父UIScrollView,它会滚动视图以使UITextField进入可见视图。当自定义控件成为第一响应者时,您需要在自定义控件上手动实现滚动,或者通过自省父视图来处理它。

我被

@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];
}

最新更新