当 UITextField 成为第一响应者时禁用 UIScrollView 滚动
当嵌入 UIScrollView
中的 UITextField
成为第一响应者时(例如,用户输入某个字符),UIScrollView
会滚动到该字符自动字段。有什么办法可以禁用它吗?
When a UITextField
embedded in a UIScrollView
becomes the first responder (for example, by the user typing in some character), the UIScrollView
scrolls to that Field automatically. Is there any way to disable that?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
建立在 Moshe 的答案...子类
UIScrollView
并重写以下方法:将其留空。工作完成了!
在斯威夫特中:
Building on Moshe's answer... Subclass
UIScrollView
and override the following method:Leave it empty. Job done!
In Swift:
我一直在为同样的问题而苦苦挣扎,最后我找到了解决方案。
我研究了如何通过跟踪调用跟踪来完成自动滚动,并发现当在
UITextField
[UIFieldEditor rollSelectionToVisible] >。此方法似乎作用于UITextField
最近祖先的UIScrollView
。因此,在
textFieldDidBeginEditing
上,通过使用大小相同的新UIScrollView
包装UITextField
(即将视图插入到UITextField
及其超级视图),这将阻止自动滚动。最后删除textFieldDidEndEditing
上的这个包装器。代码如下:
希望这有帮助!
I've been struggling with the same problem, and at last I've found a solution.
I've investigated how the auto-scroll is done by tracking the call-trace, and found that an internal
[UIFieldEditor scrollSelectionToVisible]
is called when a letter is typed into theUITextField
. This method seems to act on theUIScrollView
of the nearest ancestor of theUITextField
.So, on
textFieldDidBeginEditing
, by wrapping theUITextField
with a newUIScrollView
with the same size of it (that is, inserting the view in between theUITextField
and it's superview), this will block the auto-scroll. Finally remove this wrapper ontextFieldDidEndEditing
.The code goes like:
hope this helps!
我在禁用作为
UITableView
单元格的UITextView
的自动滚动时遇到了同样的问题。我能够使用以下方法解决它:定义
scrollViewWillBeginDragging
用于在用户自己启动滚动时恢复默认滚动行为。I had the same issue with disabling auto-scrolling of a
UITextView
being a cell ofUITableView
. I was able to resolve it using the following approach:Defining
scrollViewWillBeginDragging
is used for restoring the default scrolling behaviour, when the user himself initiates scrolling.正如 Taketo 提到的,当
UITextField
成为第一响应者时,其类型为UIScrollView
的第一个父视图(如果存在)将滚动以使该UITextField< /代码> 可见。最简单的技巧是将每个 UITextField 简单地包装在
UIScrollView
中(或者理想情况下,将所有 UITextField 包装在一个虚拟UIScrollView
中)。这与 Taketo 的解决方案非常相似,但它应该为您提供稍微更好的性能,并且在我看来,它将使您的代码(或 Interface Builder 中的界面)更加清晰。As Taketo mentioned, when a
UITextField
is made first responder, its first parent view that is of typeUIScrollView
(if one exists) is scrolled to make thatUITextField
visible. The easiest hack is to simply wrap each UITextField in aUIScrollView
(or ideally, wrap all of them in a single dummyUIScrollView
). This is very similar to Taketo's solution, but it should give you slightly better performance, and it will keep your code (or your interface in Interface Builder) much cleaner in my opinion.根据 Luke 的回答,要处理他的解决方案完全禁用自动滚动的问题,您可以有选择地禁用它,如下所示:
这样,您可以在 Interface Builder 中完全设置它以禁用自动滚动,但可以完全控制任何时候重新启用它(尽管我不知道你为什么想要这样做)。
Building on Luke's answer, to handle the issue that his solution completely disables auto-scroll, you can disable it selectively as follows:
This way, you can completely set it up in Interface Builder to disable the auto-scroll, but have full control at any time to re-enable it (though why you'd want to is beyond me).
它看起来像包含 UITextfield 的 UIScrollview,自动调整其内容偏移量;当文本字段将成为第一响应者时。
这可以通过首先在相同大小的滚动视图中添加文本字段,然后添加到主滚动视图中来解决。而不是直接添加到主滚动视图中
It looks like UIScrollview which contains UITextfield, auto adjusts its content offset; when textfield is going to become first responder.
This can be solved by adding textfield in scrollview of same size first, and then adding in to main scroll view. instead of directly adding in to main scrollview
我就是这样做的:
非常简单,您可以为任何scrollRectToVisible返回您自己的contentOffset。
这样,您就不会损害事物的正常行为和流程 - 只需在同一渠道中提供相同的功能,并进行您自己的改进。
This is the way I do it:
It is very simple, you get to return your own contentOffset for any scrollRectToVisible.
This way you are not harming the normal behaviour and flow of things - just providing the same functionality in the same channel, with your own improvements.
我已经尝试过@TaketoSano的答案,但似乎不起作用..我的情况是我没有滚动视图,只有一个带有多个文本字段的视图。
最后,我找到了一个解决方法。我需要两个默认的键盘通知名称:
UIKeyboardDidShowNotification
;UIKeyboardWillHideNotification
键盘何时隐藏。这是我使用的示例代码:
这里,
(CGRect){{272.f, 226.5f}, {480.f, 315.f}}
是隐藏键盘时视图的默认框架。(CGRect){{272.f, 55.f}, {480.f, 315.f}}
是键盘显示时视图的框架。顺便说一句,视图的帧变化将自动应用动画,这真的很完美!
I've tried @TaketoSano's answer, but seems not works.. My case is that I don't have a scrollview, just a view with several text fields.
And finally, I got a workaround. There're two default notification names for keyboard that I need:
UIKeyboardDidShowNotification
when the keyboard did show;UIKeyboardWillHideNotification
when the keyboard will hide.Here's the sample code I used:
Here, the
(CGRect){{272.f, 226.5f}, {480.f, 315.f}}
is view's default frame when keyboard is hidden. And(CGRect){{272.f, 55.f}, {480.f, 315.f}}
is view's frame when keyboard did show.And b.t.w., the view's frame changing will be applied animation automatically, this's really perfect!
我有一个集合视图,其顶部有一个文本字段,模仿
UITableView.tableHeaderView
。此文本字段位于负内容偏移空间中,因此不会干扰集合视图的其余部分。我基本上正在检测用户是否正在滚动视图中执行滚动,以及文本字段是否是第一响应者,以及滚动视图是否滚动到滚动视图内容插图的顶部之外。这个确切的代码不一定对任何人都有帮助,但他们可以操纵它以适应他们的情况。I have a collection view with a text field at the very top, mimicking the
UITableView.tableHeaderView
. This text field is located in the negative content offset space so that it doesn't interfere with the rest of the collection view. I basically am detecting whether or not the user is performing the scrolling in the scroll view and whether or not the text field is first responder and if the scroll view is being scrolled beyond the top of the scroll view's content inset. This exact code won't necessarily help anyone but they could manipulate it to fit their case.我不知道 UIScrollView 的任何属性允许这样做。恕我直言,如果能够禁用它,用户体验会很差。
也就是说,可以子类化
UIScrollView
并重写它的一些方法,以在滚动之前检查UITextfield
不是第一响应者。I don't know of any property of
UIScrollView
that would allow that. It would be poor user experience to be able to disable that, IMHO.That said, it may be possible to subclass
UIScrollView
and override some of its methods to check that theUITextfield
is not a first responder before scrolling.当您选择文本字段时停止滚动视图滚动的更简单方法是在 viewController::viewWillAppear() 中,不要调用 [super viewWillAppear];
然后您可以根据需要控制滚动。
An easier way to stop the scrollview scrolling when you select a textField is in your viewController::viewWillAppear() DO NOT call [super viewWillAppear];
You can then control the scroll as you wish.