使用自定义 UIControl 自动调整 UIScrollView 内容偏移
Posted
技术标签:
【中文标题】使用自定义 UIControl 自动调整 UIScrollView 内容偏移【英文标题】:Automatic adjustment of UIScrollView content offset with custom UIControl 【发布时间】:2014-11-24 16:28:53 【问题描述】:当UITextField
被添加到UIScrollview
时,滚动视图会自动调整其contentOffset
,这样视图就不会被键盘遮挡。
我有一个自定义的UIControl
,当它通过分配其inputView
属性成为第一响应者时,它也会显示一个键盘。相同的滚动行为不起作用。有没有办法配置 UIControl
以便在显示键盘时滚动视图保持可见?
我的猜测是,可以通过覆盖协议之一中定义的属性 UITextField
和此行为符合的其他类。但这些可能有点像迷宫。另请注意,这里的问题与滚动视图的contentInset
属性无关。滚动视图可以滚动以显示自定义控件,只是当控件成为第一响应者时它不会自动执行此操作。
【问题讨论】:
【参考方案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];
【讨论】:
以上是关于使用自定义 UIControl 自动调整 UIScrollView 内容偏移的主要内容,如果未能解决你的问题,请参考以下文章
如何:在iOS中使用StackView View从XIB自我调整自定义视图