[英]Disabling automatic scrolling of UITableView when editing UITextField inside UITableViewCell
I'm using custom UITableViewCell
s inside my UITableView
.我在
UITableViewCell
使用自定义UITableView
。 Each of these UITableViewCell
s is pretty high and contains a UITextField
at the top.这些
UITableViewCell
的每一个都非常高,并且在顶部包含一个UITextField
。
When a user taps the UITextField
in order to edit it, a keyboard appears and the UITableView
scrolls automatically so that the cell is at the top of the screen.当用户点击
UITextField
以对其进行编辑时,会出现一个键盘并且UITableView
自动滚动,以便单元格位于屏幕顶部。
The problem is that this scrolls the UITableView
to the bottom of the UITableViewCell
, not the top.问题是,这种滚动
UITableView
在底部UITableViewCell
,不上头。 When the UITableViewCell
is high and edited the UITextField
is at the top so you can't see the UITextField
.当
UITableViewCell
高并且编辑时UITextField
位于顶部,因此您看不到UITextField
。 I know how to scroll the UITableView
programmatically, but I just don't know how to disable this automatic scrolling so that I can scroll the UITableView
on my own.我知道如何以编程方式滚动
UITableView
,但我只是不知道如何禁用这种自动滚动,以便我可以自己滚动UITableView
。 How can I do this?我怎样才能做到这一点?
The autoscroll-behavior is located in the UITableViewController
functionality. autoscroll-behavior 位于
UITableViewController
功能中。
To disable the automatic scrolling I found two ways:要禁用自动滚动,我找到了两种方法:
UITableViewController
simply a UIViewController
- set the datasource and delegate on your own.UIViewController
代替UITableViewController
- 自行设置数据源和委托。viewWillAppear
method and don't call [super viewWillAppear: animated]
viewWillAppear
方法,不要调用[super viewWillAppear: animated]
With both solution you disable not only the Autoscroll, but also some other nice but not essential features, that are described in the overview of Apple´s class reference:使用这两种解决方案,您不仅可以禁用 Autoscroll,还可以禁用其他一些不错但不是必需的功能,这些功能在 Apple 的类参考概述中有所描述:
https://developer.apple.com/documentation/uikit/uitableviewcontroller https://developer.apple.com/documentation/uikit/uitableviewcontroller
Define properties for your UITableViewController
:为您的
UITableViewController
定义属性:
@property (nonatomic) BOOL scrollDisabled;
@property (nonatomic) CGFloat lastContentOffsetY;
Before you call becomeFirstResponder
:在调用
becomeFirstResponder
之前:
// Save the table view's y content offset
lastContentOffsetY = tableViewController.tableView.contentOffset.y;
// Enable scrollDisabled
scrollDisabled = YES;
Add the following code to your table view controller:将以下代码添加到您的表视图控制器:
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (self.scrollDisabled) {
[self.tableView setContentOffset:CGPointMake(0, lastContentOffsetY)];
}
...
}
After you call resignFirstResponder
, set scrollDisabled = NO
.调用
resignFirstResponder
,设置scrollDisabled = NO
。
You can do the following:您可以执行以下操作:
- (void)registerForKeyboardNotifications
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification object:nil];
}
- (void)unregisterForKeyboardNotifications
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardDidShowNotification object:nil];
}
- (void)keyboardWillShow:(NSNotification *)notification
{
self.tableView.scrollEnabled = NO;
}
- (void)keyboardDidShow:(NSNotification *)notification
{
double delayInSeconds = 0.3;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
self.tableView.scrollEnabled = YES;
});
}
Then implement this UIScrollViewDelegate method然后实现这个 UIScrollViewDelegate 方法
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (! self.tableView.scrollEnabled)
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
}
!!! !!! But be warned, that if the user taps in a location in the UITextField that will be covered by the Keyboard, then it won't scroll.
但请注意,如果用户点击 UITextField 中将被键盘覆盖的位置,则它不会滚动。
From my point of view, the best thing to do is to make sure that all the cells from top to then one with the UITextField included, will be visible when then Keyboard will show.从我的角度来看,最好的办法是确保从顶部到包含 UITextField 的所有单元格在显示键盘时都可见。
The best way is to subclass UITableView
and then override setContentOffset(_ contentOffset: CGPoint, animated: Bool)
and not to call super.setContentOffset(_ contentOffset: CGPoint, animated: Bool)
.最好的方法是
UITableView
然后覆盖setContentOffset(_ contentOffset: CGPoint, animated: Bool)
而不是调用super.setContentOffset(_ contentOffset: CGPoint, animated: Bool)
。 In this method is where the view controller is doing the automatic scroll.在此方法中,视图控制器正在执行自动滚动。
override func setContentOffset(_ contentOffset: CGPoint, animated: Bool)
{
//Do nothing
}
The issue for me was not so much that it scrolled but that it took the text view being edited off the screen.对我来说,问题不在于它滚动,而是将正在编辑的文本视图从屏幕上移开。
So instead of preventing the scrolling, I just rescroll the tableview to where I want when the editing is triggered, like this:因此,我没有阻止滚动,而是在触发编辑时将 tableview 重新滚动到我想要的位置,如下所示:
public func textViewShouldBeginEditing(textView: UITextView) -> Bool {
dispatch_async(dispatch_get_main_queue()) {
tableViewController.tableView.scrollToRowAtIndexPath(self.indexPath!, atScrollPosition: UITableViewScrollPosition.Middle, animated: true)
}
return true
}
您可以禁用自动内容插入调整,如下所示:
tableView.contentInsetAdjustmentBehavior = .never
Unfortunately, overriding -viewWillAppear: doesn't work for me in iOS 8.不幸的是,在 iOS 8 中覆盖 -viewWillAppear: 对我不起作用。
Here is my solution (as in UITableViewController implementation):这是我的解决方案(如 UITableViewController 实现):
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] removeObserver:self.tableView name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self.tableView name:UIKeyboardWillHideNotification object:nil];
}
Since the auto-scrolling behaviour is invoked by UIKeyboard's show/hide notifications, so just NOT observe them.由于自动滚动行为是由 UIKeyboard 的显示/隐藏通知调用的,所以不要观察它们。
Did you try to set "scrollsToTop" - tableview's property to NO.您是否尝试将“scrollsToTop” - tableview 的属性设置为 NO。 By default it is YES.
默认情况下是 YES。
You can try doing the following:您可以尝试执行以下操作:
self.tableView.scrollEnabled = NO;
This should disable the scrollview in the tableview.这应该禁用 tableview 中的滚动视图。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.