【问题标题】:How to set up UIScrollView programatically to scroll horizontally using autoLayout如何以编程方式设置 UIScrollView 以使用 autoLayout 水平滚动
【发布时间】:2018-08-31 08:03:58
【问题描述】:

我正在尝试实现一种行为,即我在表格视图中有一个最小宽度的表单。所以基本上,如果屏幕很宽,视图只会垂直滚动,但当屏幕很窄时,表单会缩小到最小宽度,然后开始水平滚动,以免内容松动。所以,我需要使用 autoLayout 来设置这些约束,并且我想以编程方式进行(因为我正在使用框架)。

问题是,我根本无法让视图水平滚动。我已经阅读了我能找到的所有内容,并尝试了我能想到的所有内容,但没有任何效果。现在我尝试在我的视图中添加一张大图片并让它滚动两个方向,但我无法让它工作。

这是我的层次结构:

>UIView
>>UIScrollView
>>>ContentView (UIView)
>>>>ImageView

这是我的代码:

   override func viewDidLoad() {
    if scrollView == nil {
        scrollView = UIScrollView(frame: view.bounds)
        scrollView.backgroundColor = .groupTableViewBackground
        scrollView.isDirectionalLockEnabled = true
        scrollView.showsHorizontalScrollIndicator = true
    }
    if scrollView.superview == nil {
        view.addSubview(scrollView)

        scrollView.translatesAutoresizingMaskIntoConstraints = false
        scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
        scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true

        let contentView = UIView(frame: view.bounds)
        scrollView.addSubview(contentView)

        contentView.translatesAutoresizingMaskIntoConstraints = false
        contentView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
        contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
        contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
        contentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true

        let a = contentView.heightAnchor.constraint(equalTo: scrollView.heightAnchor)
        let b = contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor)
        a.priority = .defaultLow
        b.priority = .defaultLow
        a.isActive = true
        b.isActive = true

        let image = MyImage.icon(named: "myImage", of: CGSize(width: 1000, height: 1000))
        let imageView = UIImageView(image: image)

        imageView.translatesAutoresizingMaskIntoConstraints = false
        contentView.addSubview(imageView)

        imageView.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
        imageView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true

    }
    super.viewDidLoad()
}

当我调试视图层次结构时,我可以看到图像的大小仍然是正确的(1000, 1000),但是滚动视图的内容大小没有更新并且图片被截断,没有滚动。

<UIScrollView: 0x11ead5c00; frame = (0 0; 834 1112); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x1c8853800>; layer = <CALayer: 0x1c8c32240>; contentOffset: {0, -64}; contentSize: {834, 1112}; adjustedContentInset: {64, 0, 0, 0}>

<UIImageView: 0x11a89b000; frame = (0 0; 1000 1000); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x1c8231c80>>

我发现并查看了这个示例以编程方式设置滚动视图https://github.com/zaxonus/AutoLayScroll。它垂直滚动,但为此,我无法将其设置为水平滚动。

请帮忙,我忽略了什么?

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    要使您的示例 scrollView 内容大小为 1000x1000,只需将这些约束添加到 imageView

    imageView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
    imageView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
    

    没有它们,您的contentView 不知道它应该包装imageView,因此它的大小是根据低优先级约束ab 计算的

    【讨论】:

      【解决方案2】:

      感谢 Anton,我成功了!如果其他人正在尝试做我想做的事,我只是想分享我的最终解决方案。

      通过以下代码,您可以向 Eureka 框架 FormViewController (https://github.com/xmartlabs/Eureka) 的表单添加水平滚动功能。

      import UIKit
      import Eureka
      
      class MyScrollableViewController: FormViewController {
      
          var scrollView: UIScrollView!
          var minimumWidth: CGFloat = 500.0
      
          override func viewDidLoad() {
              if tableView == nil {
                  tableView = UITableView(frame: view.bounds, style: .grouped)
                  if #available(iOS 9.0, *) {
                      tableView.cellLayoutMarginsFollowReadableWidth = false
                  }
              }
              if scrollView == nil {
                  scrollView = UIScrollView(frame: view.bounds)
                  scrollView.backgroundColor = .groupTableViewBackground
                  scrollView.isDirectionalLockEnabled = true
                  scrollView.showsHorizontalScrollIndicator = true
              }
              if scrollView.superview == nil && tableView.superview == nil {
                  view.addSubview(scrollView)
      
                  scrollView.translatesAutoresizingMaskIntoConstraints = false
                  scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
                  scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
                  scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
                  scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
      
                  let contentView = UIView(frame: view.bounds)
                  scrollView.addSubview(contentView)
      
                  contentView.translatesAutoresizingMaskIntoConstraints = false
                  contentView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
                  contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
                  contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
                  contentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
      
                  let a = contentView.heightAnchor.constraint(equalTo: scrollView.heightAnchor)
                  let b = contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor)
                  a.priority = .defaultLow
                  b.priority = .defaultLow
                  a.isActive = true
                  b.isActive = true
      
                  contentView.addSubview(tableView)
                  tableView.translatesAutoresizingMaskIntoConstraints = false
                  tableView.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
                  tableView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
                  tableView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
                  tableView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
                  tableView.widthAnchor.constraint(greaterThanOrEqualToConstant: minimumWidth).isActive = true
              }
              // Has to be called after setting up the tableView since we override the Eureka default setup
              super.viewDidLoad()
      
              // Setup your Eureka form as usual
              form +++ Section()
                  <<< LabelRow { row in
                      row.title = "My first row"
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-22
        • 2015-11-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-15
        相关资源
        最近更新 更多