Disabling automatic scrolling of UITableView when editing UITextField inside UITableViewCell
Solution 1
The autoscroll-behavior is located in the UITableViewController
functionality.
To disable the automatic scrolling I found two ways:
- Use instead of the
UITableViewController
simply aUIViewController
- set the datasource and delegate on your own. - Override the
viewWillAppear
method and don't call[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:
https://developer.apple.com/documentation/uikit/uitableviewcontroller
Solution 2
Define properties for your UITableViewController
:
@property (nonatomic) BOOL scrollDisabled;
@property (nonatomic) CGFloat lastContentOffsetY;
Before you call 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
.
Solution 3
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
- (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.
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.
Solution 4
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)
. In this method is where the view controller is doing the automatic scroll.
override func setContentOffset(_ contentOffset: CGPoint, animated: Bool)
{
//Do nothing
}
Solution 5
You could disable the automatic content inset adjustment like so:
tableView.contentInsetAdjustmentBehavior = .never
animal_chin
Updated on July 09, 2022Comments
-
animal_chin almost 2 years
I'm using custom
UITableViewCell
s inside myUITableView
. Each of theseUITableViewCell
s is pretty high and contains aUITextField
at the top.When a user taps the
UITextField
in order to edit it, a keyboard appears and theUITableView
scrolls automatically so that the cell is at the top of the screen.The problem is that this scrolls the
UITableView
to the bottom of theUITableViewCell
, not the top. When theUITableViewCell
is high and edited theUITextField
is at the top so you can't see theUITextField
. I know how to scroll theUITableView
programmatically, but I just don't know how to disable this automatic scrolling so that I can scroll theUITableView
on my own. How can I do this? -
animal_chin over 12 yearstried it yet, but it didn't work...scrollToTop doesn't handle this... thanks for answer anyway!
-
Kudit over 11 yearsThis does not prevent the automatic scrolling the UITableViewController does when tapping on a text field within a UITableViewCell
-
Cocoadelica over 11 yearsI had the same problem and solution 2 worked. I've tested this in iOS 5.0.0 and upwards and it holds so far (current release is 6.1.2). I can't vouch for it in 4 but hey, it's 2013, so we can probably say 5.0 is the lowest supported os right now.
-
meaning-matters over 10 yearsProblem with this is that the insets are not adapted to accommodate the keyboard, at least not in iOS 7.0.6. This means that more code will be needed to do this by hand: catching keyboard notifications, ... Ugly.
-
Fidel López about 9 yearsCan't believe I didn't know about this till today.. I was having problems with TPKeyboardAvoiding.. Thanks!!
-
Nikolay Spassov almost 9 years-scrollViewDidScroll: does indeed get called when automatic scrolling happens, this here is the best solution
-
pkc456 over 8 yearsPoint no2 works on 9.1. Good answer @Dominic. Thanks
-
coolcool1994 almost 8 yearsOption 2 is so weird. I suddenly had the automatic scrolling disable, and I didn't have super view will appear thingy XDXDXD. How could that change everything LOL
-
ryanipete over 7 yearsI wouldn't ever override viewWillAppear: without calling super. UITableViewController subclasses UIViewController, and Apple "requires" all UIViewController subclasses to call super. From the UIViewController documentation: "If you override this method, you must call super at some point in your implementation."
-
Pushpendra about 7 yearsi am using
UITableViewController
if i don't usesupper.viewWillApper()
function then my footer is not coming on the top ofkeyBoard
what should i do for thatMeans i want to stop auto scrolling and want footer view on the top of keyboard while editing
-
Sophy Swicz almost 7 yearsThis isn't a scrollview problem, is a tableViewController class. The correct answer was the override viewWilAppear
-
simonthumper over 6 yearsis this still working for you? Can't get it working in iOS 11 / Xcode 9
-
Olle Lind over 4 yearsThis was the correct answer for me for a UITableView with UITextView in the cells.
-
Felix Marianayagam almost 4 yearsThis won't work as the keyboard will obscure the cells beneath it.