Prevent uiscrollview from scrolling further then c

2019-03-21 07:10发布

This question already has an answer here:

I have a UIScrollView which has subviews that create a content with a width of about 7000. Now I want the UIScrollView to not scroll any further then 2000.

I tried:

[scrollView setContentSize:CGSizeMake(768.0, 2000.0)];  
[scrollView setClipsToBounds:YES];

But I can still scroll to the end, how do I prevent this?

7条回答
孤傲高冷的网名
2楼-- · 2019-03-21 07:33

You can set content offset to 2000 if it is more than 2000 so it won't go beyond the bound.

Implement this method and set it to the delegate of that scrollview

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (scrollView.contentOffset.x > 2000) {
        CGPoint offset = scrollView.contentOffset;
        offset.x = 2000;
        [scrollView setContentOffset:offset animated:YES];
    }
}

Edit: I just tried this, and it works fine. Maybe check why setContentSize: is not working? Another approach, make a view with heigh of 2000, put your content view inside it, and add that view as subview of scrollview.

UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 600, 7000)];
label.numberOfLines = 60;
label.font = [UIFont systemFontOfSize:100];
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.view.frame];

NSMutableString *str = [[NSMutableString alloc] initWithCapacity:300];
for (int i = 0; i < 60; i++)
    [str appendFormat:@"%d\n", i];
label.text = str;

[scrollView addSubview:label];
[scrollView setContentSize:CGSizeMake(600, 2000)];
[self.view addSubview:scrollView];
查看更多
forever°为你锁心
3楼-- · 2019-03-21 07:36

It's seems that webView is changing its scrollView contentSize after page loading.

In your init set self as a delegate of WebView:

[webView setDelegate: self];

And add this method:

- (void)webViewDidFinishLoad: (UIWebView *)webView {
    [webView.scrollView setContentSize: CGSizeMake(768.0, 2000.0)]; 
}

In my test case it's working fine.


UPDATED:

Calling javascript methods sometimes does not trigger webViewDidFinishLoad. So the most universal technique will be Key-Value Observing.

In init:

[webView.scrollView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil];

And somewhere this method:

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
    UIScrollView * scrlView = (UIScrollView *) object;
    if ([keyPath isEqual:@"contentSize"]) {
        NSLog(@"New contentSize: %f x %f",scrlView.contentSize.width,scrlView.contentSize.height);
        if(scrlView.contentSize.width!=768.0||scrlView.contentSize.height!=2000.0)
        [scrlView setContentSize:CGSizeMake(768.0, 2000.0)]; 
    }
}

Do not forget to remove observer in case of dealloc:

[webView.scrollView removeObserver:self forKeyPath:@"contentSize"];
查看更多
看我几分像从前
4楼-- · 2019-03-21 07:47

I believe your code above should work fine. setContentSize will prevent the contentOffset from getting larger. You may have to start, though, by setting contentOffset yourself (once) if the user has already scrolled outside that area. (Try resetting it to (0, 0), for example.)

Also, are you permitting zooming? If you have a zoom != 1, the content size may not be what you think it is. Try setting zoom to 1 before modifying the content size.

查看更多
霸刀☆藐视天下
5楼-- · 2019-03-21 07:53

Hard to give specific answer without seeing your html but I've had a similar problem before and i think its actually your UIWebview thats actually scrolling and not the scrollview. somewhere on the page in the UIWebview html you will most probably have oversize content. THe webview naturally wants to scroll. In my case it was a long URL in a paragraph of text. I have also seen this happening vertically.

You need to find the container element to your oversize html and set the overflow to hidden in the css. It may be that this is the body tag or the html tag in the html or you need to wrap your content.

ie;

<div style="overflow:hidden">
    Overflowing text
</div>

Failing that you may have to play with the following tag

Or set the container div to width:100% & height:100%;

查看更多
贼婆χ
6楼-- · 2019-03-21 07:54

Unless I'm misunderstanding something in your question this is straightforward. Add this to your view controller containing the web view.

- (void)viewDidLoad
{
    // other stuff
    self.webView.delegate = self;
    self.webView.scrollView.bounces = YES;
    // load your webView here
}

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    CGSize contentSize = self.webView.scrollView.contentSize;
    CGFloat maxContentWidth = contentSize.width;
    if (maxContentWidth > 2000) {
        maxContentWidth = 2000;
    }
    self.webView.scrollView.contentSize = CGSizeMake(maxContentWidth, contentSize.height);
}
查看更多
可以哭但决不认输i
7楼-- · 2019-03-21 07:55

Ok So first step, your view controller must implement UISCrollViewDelegate, and you must set your controller as a delegate for your UIScrollView.

Then, implement this delegate method in your controller:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    static float stopx = 2000.0f;

    if (scrollView.contentOffset.x >= stopx) {
        CGPoint stop = scrollView.contentOffset;
        stop.x = stopx;
        [scrollView setContentOffset:stop animated:NO];
    }
}

Anytime you get pass 2000 / stops value, the scrollview should be brought back

查看更多
登录 后发表回答