开发者

Automatic scroll to top doesn't work in UITableView

开发者 https://www.devze.com 2023-01-25 08:31 出处:网络
usually when tapping the top of the screen the tableview scr开发者_运维技巧olls all the way to the top. For some reason this doesn\'t work in one of my view controllers.

usually when tapping the top of the screen the tableview scr开发者_运维技巧olls all the way to the top. For some reason this doesn't work in one of my view controllers.

The hirarchy is as follows:

UIView

-> WebView

-> TableView

----->SearchBar

SearchDisplayController.

I think I have everything hooked up correctly (datasource, delegate, ...). I have a similar view controller where everything works. The only difference seems to be WebView, which is missing in the view controller where the tap-and-scroll-to-top works...

Any ideas?

Best regards, Sascha


You have probably added some view to your view hierarchy that is a UIScrollView or contains scroll views (e.g. UIWebView or UITextView). When you tap the status bar, iOS searches for the topmost scrollview with scrollsToTop set to YES and scrolls to its top.

Add this to your class:

- (void) disableScrollsToTopPropertyOnAllSubviewsOf:(UIView *)view {
    for (UIView *subview in view.subviews) {
        if ([subview isKindOfClass:[UIScrollView class]]) {
            ((UIScrollView *)subview).scrollsToTop = NO;
        }
        [self disableScrollsToTopPropertyOnAllSubviewsOf:subview];
    }
}

…and call

[self disableScrollsToTopPropertyOnAllSubviewsOf:myAddedSubview];

to solve the problem and let your table view scroll to top again.


You need to disable scrollsToTop on all but one of the scrollable views. Since UITableView is a descendant of UIScrollView, it's easy to do. However, if you want to disable it on the webview, it's a little trickier. This seems to work:

[webView.subviews objectAtIndex:0].scrollsToTop = NO;

But that is a little iffy since it's poking around in undocumented parts of the webview. It may stop working if Apple decides to rearrange the subviews.


Don't know what Apple were smoking but by design, the behaviour on iPhone is distinctly different from iPad. Apple's documentation does include a "Special Condsideration" note as follows...

On iPhone, the scroll-to-top gesture has no effect if there is more than one scroll view on-screen that has scrollsToTop set to YES.

So on iPhone you have to ensure that there is only ever one UIScrollView (or UITableView/UICollectionView/UIWebView etc) that has its scrollsToTop = YES.

Since scrollsToTop defaults to YES you have to explicitly set scrollsToTop = NO for the UIScrollView's you do not want to scroll when the user taps the status bar.


Apparently if you have more than one scrolling view (in your case the WebView and TableView) in a view controller, the "tap status bar to scroll to top" is disabled.

http://twitter.com/drance/status/2448035250438144

(Matt Drance is a former iPhoneOS developer evangelist and current iOS development rockstar)


Swift variant of opyh's answer. Upvote him!

func disableScrollsToTopPropertyOnAllSubviewsOf(view: UIView) {
    for subview in view.subviews {
        if let scrollView = subview as? UIScrollView {
            (scrollView as UIScrollView).scrollsToTop = false
        }
        self.disableScrollsToTopPropertyOnAllSubviewsOf(subview as UIView)
    }
}


I just wanted to add to this, if you are using a UITextView, it isn't the subviews that need the scrollsToTop adjusting, it's the actual UITextView, in short you need this code:

[myTextView setScrollsToTop:FALSE];

This should fix the problem (additionally, the 'disableScrollsToTopPropertyOnAllSubviewsOf' function doesn't work on the UITextViews).

Hope this helps someone!


I had this problem with just a tableview in the NIB. Very frustrating until I remembered I was programmatically adding a UITextView as the table view header. scrollsToTop=NO on the UITextView did the trick.


Set scrollsToTop = NO on all scroll views in the view, except for the one you want to scroll to top. That helps the system find the correct scroll view.

0

精彩评论

暂无评论...
验证码 换一张
取 消