【问题标题】:Prevent uiscrollview from scrolling further then certain point [duplicate]防止uiscrollview滚动到某个点[重复]
【发布时间】:2011-12-31 05:49:45
【问题描述】:

我有一个 UIScrollView,它具有创建宽度约为 7000 的内容的子视图。 现在我希望 UIScrollView 在 2000 年之后不再滚动。

我试过了:

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

但我仍然可以滚动到最后,如何防止这种情况发生?

【问题讨论】:

  • 也许您应该发布一些代码,即创建 ScrollView 及其内容。我无法重现该问题。
  • 我们将滚动视图实际上是 UIWebView 的一部分。 UIWebView 是否可能不允许设置 contentSize?
  • 您在访问 webView.scrollview 吗?仍然 setContentSize 为我工作。你是如何设置内容的?
  • 设置内容是什么意思?
  • 你的内容是什么?只是 url 请求?

标签: objective-c ios uiscrollview


【解决方案1】:

很难在没有看到您的 html 的情况下给出具体的答案,但我之前也遇到过类似的问题,我认为它实际上是您的 UIWebview,它实际上是滚动的,而不是滚动视图。在 UIWebview html 页面的某处,您很可能会有超大的内容。 webview 自然是要滚动的。就我而言,它是一段文本中的长 URL。我也看到垂直方向发生了这种情况。

您需要在超大 html 中找到容器元素,并将溢出设置为隐藏在 css 中。可能这是html中的body标签或者html标签或者你需要包装你的内容。

即;

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

你可能不得不玩以下标签

或者将容器div设置为width:100% & height:100%;

【讨论】:

    【解决方案2】:

    除非我误解了您的问题,否则这很简单。将此添加到包含 Web 视图的视图控制器中。

    - (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);
    }
    

    【讨论】:

      【解决方案3】:

      正如其他人所说,实现 uiscrollviewdelegate

      实现这些方法:

      - (void)scrollViewDidScroll:(UIScrollView *)scrollView
      
      - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
      
      - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
      
      - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
      
      - (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView
      
      - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
      

      希望这能解决您遇到的跳跃问题

      注意,在这些方法中放入与其他帖子类似的代码,例如

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

      起初性能可能会受到影响,如果这是真的,请开始取出某些委托方法,直到获得所需的行为

      【讨论】:

        【解决方案4】:

        好的 所以第一步,你的视图控制器必须实现 UISCrollViewDelegate, 您必须将控制器设置为 UIScrollView 的委托。

        然后,在你的控制器中实现这个委托方法:

        - (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];
            }
        }
        

        任何时候你通过 2000 / 停止值,滚动视图应该被带回来

        【讨论】:

          【解决方案5】:

          似乎webView 在页面加载后正在更改其scrollView contentSize

          在你的 init 中将 self 设置为 WebView 的代表:

          [webView setDelegate: self];
          

          并添加此方法:

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

          在我的测试用例中它工作正常。


          更新:

          调用 javascript 方法有时不会触发 webViewDidFinishLoad。所以最通用的技术就是 Key-Value Observing。

          在初始化中:

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

          还有这个方法:

          - (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)]; 
              }
          }
          

          不要忘记在dealloc的情况下删除观察者:

          [webView.scrollView removeObserver:self forKeyPath:@"contentSize"];
          

          【讨论】:

          • 用javascript修改body内容会改变contentSize吗?
          • 是的,javascript 可以改变contentSize 并且不会触发webViewDidFinishLoad。答案已更新为处理此问题的方法。
          【解决方案6】:

          我相信您上面的代码应该可以正常工作。 setContentSize 将防止 contentOffset 变大。但是,如果用户已经滚动到该区域之外,您可能必须自己(一次)设置 contentOffset 来开始。 (例如,尝试将其重置为 (0, 0)。)

          另外,您是否允许缩放?如果你有一个缩放!= 1,内容大小可能不是你想象的那样。在修改内容大小之前尝试将缩放设置为 1。

          【讨论】:

            【解决方案7】:

            如果超过 2000,您可以将内容偏移设置为 2000,这样就不会超出范围。

            实现此方法并将其设置为该滚动视图的委托

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

            编辑:我刚试过这个,效果很好。也许检查为什么setContentSize: 不起作用? 另一种方法,创建一个高度为 2000 的视图,将您的内容视图放入其中,然后将该视图添加为滚动视图的子视图。

            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];
            

            【讨论】:

            • 这会阻止用户进一步滚动,但由于不是每个像素都调用 scrollViewDidScroll,所以我得到了一个非常跳跃的效果。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2023-04-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多