Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent uiscrollview from scrolling further then certain point [duplicate]

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?

like image 483
Thizzer Avatar asked Feb 23 '23 09:02

Thizzer


2 Answers

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"];
like image 171
Evgeny Aleksandrov Avatar answered Feb 24 '23 23:02

Evgeny Aleksandrov


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];
like image 41
Bryan Chen Avatar answered Feb 24 '23 21:02

Bryan Chen