【问题标题】:UIScrollView scroll vertically by touch and horizontally programmaticallyUIScrollView 通过触摸垂直滚动并以编程方式水平滚动
【发布时间】:2011-06-13 01:53:12
【问题描述】:

我查看了 stackoverflow,但无法找到完全回答我的问题的答案。如果我遗漏了什么,请指出正确的问题。

这是我的场景--

我最初有一个设置垂直窗口大小的情况,所以我很容易通过这样做来完全限制滚动 --

CGRect scrollContainer = CGRectMake(0, 0, 320, 440);
self.baseView = [[UIScrollView alloc] initWithFrame:scrollContainer];
self.baseView.contentSize = CGSizeMake(6400, 440);
self.baseView.bounces = NO;
self.baseView.pagingEnabled = NO;
self.baseView.scrollEnabled = NO;

根据手机的移动,我可以通过编程方式滚动 --

CGPoint scrollOffset = CGPointMake(x*20, 0);
[self.baseView setContentOffset:scrollOffset];

在我的新要求中,垂直内容急剧增加,因此我将拥有这样的 contentSize

self.baseView.contentSize = CGSizeMake(6400, 4400);

我仍然想以编程方式水平滚动,但让用户能够通过触摸仅垂直滚动。所以,我假设我不得不说scrollEnabled = YES。但这让用户可以双向滚动。

我是否必须捕获触摸事件并覆盖它们?我如何识别它是水平滚动还是垂直滚动?如果它是对角滚动动作会发生什么?

在这一点上我有点无能为力,所以任何输入将不胜感激。

【问题讨论】:

    标签: iphone objective-c ios ios4 uiscrollview


    【解决方案1】:

    您可能可以通过嵌套两个UIScrollViews 来做到这一点。

    内部滚动视图将具有实际内容的contentSize,其实际尺寸将是屏幕宽度和与contentSize 相同的高度 禁用滚动。

    外部滚动视图的contentSize 与外部滚动视图的尺寸相同,它的实际尺寸将是启用滚动的屏幕尺寸。

    这样,用户可以在外部视图上上下滚动,而您可以使用内部视图以编程方式控制水平偏移。

    这有点复杂,但至少你不必子类化。 :D

    (也只适用于 iOS 3.0+)但这似乎不是问题)

    [请参阅“嵌套滚动视图”中的“iOS 滚动视图编程指南”部分]

    【讨论】:

    • 我不确定我是否理解。如果我想垂直滚动,其中一个滚动视图的内容大小必须大于屏幕大小,对吗?那是内部滚动视图还是外部滚动视图?
    • 今晚我会试试这个并提供反馈。欣赏答案。 innerscrollview = 禁用滚动的整个内容大小。 outerscrollview.width = 屏幕宽度 .. 将 innnerscrollview 添加到 outerscrollview 并为 outerscrollview 启用屏幕交互。听起来对吗?
    • @Kal 内部的scrollView也只有屏幕宽度宽度,但是它的contentSize就是完整的contentSize。它的高度是 contentSize.height。因此,启用触摸的外部滚动视图滚动整个内部滚动视图(它具有 contentSize = innerScrollView.size),并且您可以从代码中控制内部滚动视图的水平 contentOffset,因为用户没有机会改变它。
    • 这行得通。直到我尝试过,我才意识到这是多么容易。感谢您为我指明正确的方向。
    【解决方案2】:

    您可以使用UISwipeGestureRecognizer 将一系列触摸事件识别为垂直或水平滑动。

    // ensure that automatic scrolling is not enabled
    scrollView.scrollEnabled = NO;
    
    UISwipeGestureRecognizer *swipeRecognizer = [[UISwipeGestureRecognizer alloc] 
                                               initWithTarget:self 
                                               action:@selector(handleGesture:)];
    swipeRecognizer.direction = UISwipeGestureRecognizerDirectionUp | UISwipeGestureRecognizerDirectionDown;
    [scrollView addGestureRecognizer:swipeRecognizer];
    [swipeRecognizer release];
    

    在您的handleGesture: 方法中,您现在可以适当地调整scrollOffset。阅读UIGestureRecognizer了解更多详情。

    【讨论】:

      【解决方案3】:

      我也认为两个滚动视图是这里的答案。如果您不想嵌套它们,请将它们的数据链接到控制器中:

      有一个滚动视图保存您的内容并禁用了用户交互,我们称之为contentScrollView,还有一个顶部相同大小的不可见滚动视图interactionScrollView。在两者的委托控制器中,实现

      - (void)scrollViewDidScroll:(UIScrollView *)scrollView
      {
          if (scrollView == interactionScrollView)
          {
              CGPoint offset = CGPointMake(yourProgrammaticallySetHorizontalOffset,interactionScrollView.contentOffset.y);
              [contentScrollView setContentOffset:offset];
          }
      }
      

      您也可以通过这种方式链接缩放。

      【讨论】:

      • 感谢您的回答。我今天会试试这个并提供反馈。
      【解决方案4】:

      另一种可能性,因为您可能并不真正需要水平滚动滚动,您只需要设置内容的偏移量:

      正常将你的contentView放入scrollView,但是将scrollView的contentSize设置为CGPointMake(scrollView.size.width,content.size.height)。这意味着 scrollView 永远不会水平滚动。

      现在,您可以从您的代码中水平移动内容:content.frame = CGRectOffset(content.frame, yourPreferredOffset, 0)

      我没有对此进行测试,但我认为它会起作用,并且只需要一个滚动视图。您还可以将帧变化的东西放入动画中,使其看起来像一个滚动(它就是)而不是突然的内容变化。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-18
        • 1970-01-01
        • 1970-01-01
        • 2021-11-13
        • 2014-01-09
        相关资源
        最近更新 更多