【问题标题】:UIScrollView AutoLayout Vertical OnlyUIScrollView AutoLayout 仅垂直
【发布时间】:2014-11-16 20:45:46
【问题描述】:

我想让 AutoLayout 与 UIScrollView 一起工作,但遇到了一些麻烦。这是我所做的:

  1. 在主视图内添加UIScrollView,框架为:[顶部:0,左侧:0,宽度:320,高度:568]

  2. UIScrollView 内添加UIView“ContentView”,边框和背景颜色为黑色:[顶部:0,左侧:0,宽度:320,高度:568]

  3. 设置UIScrollView 约束:[顶部:0,底部:0,左侧:0,右侧:0]

  4. 设置“ContentView”约束:[顶部:0,底部:0,左侧:0,右侧:0]

  5. 对齐“ContentView”内的项目

  6. 将主视图 bgcolor 设置为灰色(查看发生了什么)

这是问题的截图:

1

由于某种原因,约束使内容视图位于屏幕中间。此外,它向各个方向滚动。我希望内容只能在垂直方向上滚动,如UITableView。所以我不能像下面这样移动它:

我做错了什么?我已经检查了我在 StackOverflow 和 Google 中可以找到的所有教程和答案,实际上没有人遇到奇怪的问题,所以我寻求帮助。

编辑:我还添加了 ContentView 的宽度和高度作为约束,但这也没有帮助。

【问题讨论】:

    标签: ios objective-c swift uiscrollview autolayout


    【解决方案1】:

    您可以完全使用约束来做到这一点,而且非常简单。

    UIScrollView 只需要了解它内部的宽度和空间。所以它需要有一些东西固定到LeadingTrailingTopBottom 约束。内容的宽度和高度也需要固定(这并不意味着我必须指定它。我仍然可以使用约束来实现这一点。)

    1. 根据需要添加UIScrollView 和位置。
    2. UIScrollView 内添加 UIView 以获取内容。
    3. 将内容UIViewLeadingTrailingTopBottom约束设置为0。
    4. Equal Width 约束添加到UIScrollViewUIView。这将使其仅垂直滚动。
    5. 您现在需要设置内容UIView 的高度。然后,您可以指定内容视图的高度 (blech) 或使用其中包含的控件的高度,方法是确保底部控件被限制在内容视图的底部。

    我这样做了,效果很好。

    【讨论】:

    • 这是我一直在寻找的答案。我的 contentView 等于 UIScrollView 的超级视图。谢谢
    • 谢谢,等宽约束是我需要的。
    【解决方案2】:

    要禁用水平滚动,可以在 (void)scrollViewDidScroll 方法中设置内容大小。

    [self.scrollView setContentOffset: CGPointMake(0, self.scrollView.contentOffset.y)];
    

    您还需要设置方向锁定,以便一次只使用 1 个滚动方向。 https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIScrollView_Class/index.html#//apple_ref/occ/instp/UIScrollView/directionalLockEnabled

    self.scrollView.directionalLockEnabled = YES;
    

    【讨论】:

    • 谢谢!水平滚动已禁用。
    • 没有问题。。关于自动布局问题,你是使用界面生成器还是通过代码使用自动布局?
    • 我正在使用界面生成器。我将约束左右更改为-16,它起作用了。我不相信它是正确的行为。有没有办法让它与 0 一起工作?
    • 我对界面生成器不太熟悉。我通常在代码中使用 constraintsWithVisualFormat 方法。但是,也许尝试删除 contentView 的约束。我通常在 layoutSubviews 中为我的滚动视图中的子视图设置 contentView 大小。
    • self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * _pageCount, self.scrollView.frame.size.height);这就是我过去的做法,尽管我在 uiscrollview 中翻阅不同的视图。
    【解决方案3】:

    总结 Leszek S 的回答:

    为了有一个垂直滚动的视图,滚动视图内的所有视图都必须设置 宽度约束。轻松设置为滚动视图的超级视图。

    原因是只要它的子视图都不需要水平滚动,滚动视图就不会水平滚动。例如,如果您有一个标签,设置为 0 行,自动布局将尝试使标签尽可能宽,然后再开始添加行和换行符。如果标签上没有明确的宽度限制,它只会使滚动视图内容区域更宽。滚动视图的尾随约束将被忽略。

    如果您有大量视图,您可能希望将它们放在一个包含视图中,就像在该视频中一样。就我而言,我只有 5 或 6 个标签,它们可以动态改变高度,但不应该改变宽度,所以我只是让它们的宽度与滚动视图相同。还有宾果游戏,垂直滚动视图,其标签会根据文本而增大或缩小。

    【讨论】:

      【解决方案4】:

      我编写了一个允许垂直滚动但不能水平滚动内容的函数。它在滚动视图中创建一个宽度有限的 UIView,并将所有滚动视图子视图嵌入其中。

      TegScrolledContent.createContentView(scrollView)
      

      https://github.com/exchangegroup/scrollable-content-ios

      【讨论】:

      • 感谢 evegenii,当我在左右横向切换时,您的图书馆真的在我的登录视图中帮助了我。
      【解决方案5】:

      在 Xcode 12.1 垂直滚动视图设置中使用 Swift 4-5 测试

      1. 添加滚动视图并将顶部、底部、左侧和右侧约束设置为 0。
      2. 通过在大小检查器中取消选择来删除滚动视图“内容布局指南”。
      3. 将 uiview 添加到滚动视图。

      4.我们需要设置uiview相对于滚动视图的约束。控制点击uiview,然后附加到滚动视图。

      1. 这带来了两者之间的限制。

      1. 按住 shift 可选择多个。我们需要添加 Equal Widths、Equal Heights、Leading、Trailing、Top 和 Bottom。

      1. 将等高编辑为:Superview 优先级从 1000 改为 250。

      1. 现在添加内容。为简单起见,我在属性检查器中添加了一个带有 0 行的图像和一个标签,并且确实加载了很多文本。

      1. 最终结果!

      【讨论】:

        【解决方案6】:

        除了@derek 的回答,我想补充一点,总是在 scrollViewDidScroll 中设置 contentOffset 会导致性能问题。所以请只检查 x 是否不为 0 然后设置 contentOffset

            if(contentOffset.x != 0){
                setContentOffset(CGPointMake(0, contentOffset.y), animated: false)
            }
        

        是的,滚动视图

        directionalLockEnabled = true
        

        【讨论】:

          【解决方案7】:

          为内容视图提供明确的高度和宽度限制

          【讨论】:

          • 我做了 -> 宽度:568,高度:320。没有运气
          • 也许你的内容视图被它的子视图缩小了。您是否遇到自动布局异常?
          • 没有,没有一个。事情就是这样。我开始使用约束值,并为前导和尾随约束设置 -16 实际上将视图固定在中间......我真的不想依赖这样的数字。这个问题的原因可能是什么?你说的收缩机是什么意思?此外,现在即使滚动视图工作,它也不会滚动到所需的位置。
          【解决方案8】:

          下面是我用来实现仅垂直滚动视图的 sn-p。 它的工作原理是将内容视图添加为滚动视图的子视图,然后将该内容视图的宽度限制为父滚动视图的宽度。从那时起,所有的子视图都应该添加到内容视图而不是滚动视图。

          // View that will contain content of scroll view. Width is constrained to the width of the scroll view.
          UIView *contentView = [[UIView alloc] init];
          contentView.translatesAutoresizingMaskIntoConstraints = NO;
          [scrollView addSubview:contentView];
          
          views[@"contentView"] = contentView;
          [scrollView addConstraint:[NSLayoutConstraint constraintWithItem:contentView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0.0]];
          [scrollView addConstraint:[NSLayoutConstraint constraintWithItem:contentView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0]];
          [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[contentView]|" options:0 metrics:nil views:views]];
          
          // Now, add all your subviews to contentView
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-04-26
            • 2015-11-10
            • 2015-02-04
            • 1970-01-01
            • 2012-11-19
            相关资源
            最近更新 更多