Reputation: 16114
I am using PPRevealSideViewController. I have two ViewControllers in it. The middle one is a subclass of SideSwipeTableViewController and the left one is a subclass of UIViewController, that has a tableView inside it. Example apps for PPRevealSideViewController and SideSwipeTableViewController are both supporting scrollsToTop property for UITableView at least for the TableView that is in the mid of PPRevealSideViewController. But when I use both of these classes, scrollsToTop stops working.
I know this is similar question, but I have tried everything, I have read all posts, that google gives me about this problem, but still couldn't solve it. So I decided to ask it here, I don't have any ideas even what to do, to make scrollsToTop work.
self.window.rootViewController = self.revealSideViewController;
Where
- (PPRevealSideViewController *)revealSideViewController
{
if (! _revealSideViewController) {
_middleTableViewController = [MiddleTableViewController new];
UINavigationController *middleNavController = [[UINavigationController alloc] initWithRootViewController:_middleTableViewController];
_revealSideViewController = [[PPRevealSideViewController alloc] initWithRootViewController:middleNavController];
_revealSideViewController.delegate = self;
}
return _revealSideViewController;
}
- (void) preloadSidePanel
{
AppDel.systemTableViewController = [SystemTableViewController new];
AppDel.systemTableViewController.parent = self;
[self.revealSideViewController preloadViewController:AppDel.systemTableViewController
forSide:isLeftHanded ? PPRevealSideDirectionLeft : PPRevealSideDirectionRight
withOffset:_offset];
}
And I set in this systemTableViewController this:
_tableView = [[UITableView alloc] initWithFrame:frame style:UITableViewStylePlain];
[self.view addSubview:_tableView];
_tableView.scrollsToTop = NO;
However, it doesn't help.
Upvotes: 4
Views: 4514
Reputation: 313
I know this is quite an old one but hope this can help. Following the rule that scrollsToTop doesn't work if more than one UIScrollView, or its subclasses, has got it set to YES (default value), a sanity check is probably worth to check who's actually messing up with this behaviour. The simple method below loop over the subviews of your view and logs the scrollsToTop value of all the UIScrollView in your view. Preferably to be called in your viewDidAppear method.
- (void)checkForScrollViewInView:(UIView *)view {
for (UIView *subview in [view subviews]) {
if ([subview isKindOfClass:[UIScrollView class]]) {
NSLog(@"scrollsToTop enabled: %i in scroll view %@", ((UIScrollView *)subview).scrollsToTop, subview);
}
if (subview.subviews.count > 0) {
[self checkForScrollViewInView:subview];
}
}
}
This is just a debug code indeed. Once you find the scrollsToTop value for each one of the UIScrollView subclasses just make sure only one is set to YES.
Upvotes: 0
Reputation: 3456
I thought I was cursed by the ghost of Jobs because I tried every possible solution from all related questions here on StackOverflow, and I could not get my scrollviews to cooperate.
If none of the above answers work for you- make sure you don't have a UIScrollView
or a subclass inside your tableview cells. Looping through your view's subviews and disabling scrollsToTop
will do nothing if your tableView has not already loaded it's subviews.
The solution that worked for me was creating a public disableScrollsToTop
method on my UITableViewCell subclass that sets the scrollsToTop
property of its scrolling subview to NO
.
The code I used (with names generalized):
MYViewController.m
- (void)viewDidLoad
{
// ... your initialization code
[self setupScrollViewScrolling];
}
- (void)setupScrollViewScrolling
{
self.horizontalScrollView.scrollsToTop = NO;
self.tableView.scrollsToTop = YES;
}
// Note that I am using Xibs here, and your implementation for storyboards/xibless will be slightly different.
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:
MyTableViewCell *cell;
static NSString *identifier = @"IdentifierForCell";
if (!(cell = [self.tableView dequeueReusableCellWithIdentifier:identifier]))
{
[[NSBundle mainBundle] loadNibNamed:@"MYTableViewCell" owner:self options:nil];
cell = self.tableViewCell;
self.tableViewCell = nil;
// ... cell initialization code
[cell disableScrollsToTop];
}
return cell;
}
And of course, disableScrollsToTop
is just
MYTableViewCell.m
- (void)disableScrollsToTop
{
self.subviewThatScrolls.scrollsToTop = NO;
}
Another way (that is arguably more extensible) this could be done is wrapping UITableView's reloadData
method, and after the reload calling a recursive scrollview-checking method like what @Dominic_Sander listed above, although I have not checked this solution since I am done messing with this problem.
Upvotes: 0
Reputation: 10096
If you have tried all the solutions mentioned in similar threads here and have not succeeded in "scrollsToTop repair" you only need to subclass main UIWindow of your App.
@interface CustomWindow : UIWindow
@end
@implementation CustomWindow
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
if (point.y <= 20) {
//do something to scroll appropriate UIScrollView to top
}
return YES;
}
Use this in AppDelegate:
#import "CustomWindow.h"
@interface AppDelegate : UIResponder
@property (nonatomic,strong) CustomWindow *window;
@end
This solution allows one to set any UIScrollView of your App to be scrolled to top ignoring general scrollsToTop mechanism.
All you need is to have a global link pointing to "active" UIScrollView at the moment.
Upvotes: 1
Reputation: 22962
I hope this class can be to help. In my app we're having multiple webviews and scrollviews. This makes it all much easier. :)
https://gist.github.com/hfossli/6776203
Good luck!
Upvotes: 1
Reputation: 2704
With the following little Extension of UIView
I solved the same issue. Because these property doesn' ´t only exist on UITableView
, but also on UIScrollView
and ancestors (e.g. UICollectionView
).
@implementation UIView (UIViewPimp)
- (void) disableScrollsToTopPropertyOnMeAndAllSubviews {
if ([self isKindOfClass:[UIScrollView class]]) {
((UIScrollView *)self).scrollsToTop = NO;
}
for (UIView *subview in self.subviews) {
[subview disableScrollsToTopPropertyOnMeAndAllSubviews];
}
}
@end
I call these new method in the viewDidLoad
-Method and then I set the property of the desired UITableView
explicit.
- (void)viewDidLoad
{
[super viewDidLoad];
[self.view disableScrollsToTopPropertyOnMeAndAllSubviews];
self.myTableView.scrollsToTop = YES;
}
Upvotes: 5
Reputation: 4805
Scroll to top works only if there is only one scroll view(or any subclass of scroll view. In your case it is table view) is visible.
Even if there are multiple scroll views visible, only one should have this property set then only it will work.
Also if the delegate returns NO in scrollViewShouldScrollToTop, it will not work.
Upvotes: 8