【问题标题】:Why UIScrollView don't work if you set leading and trailing anchors for subViews?如果您为子视图设置前导和尾随锚点,为什么 UIScrollView 不起作用?
【发布时间】:2021-06-09 18:27:54
【问题描述】:

例子:

class ViewController: UIViewController {

  let labelOne: UIView = {
    let label = UIView()
    label.backgroundColor = .red
    label.translatesAutoresizingMaskIntoConstraints = false
    return label
  }()

  let scrollView: UIScrollView = {
    let v = UIScrollView()
    v.translatesAutoresizingMaskIntoConstraints = false
    v.backgroundColor = .cyan
    v.contentSize = CGSize(width: 2000, height: 2000)
    return v
  }()


  override func viewDidLoad() {
    super.viewDidLoad()
    self.view.addSubview(scrollView)
    scrollView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 8.0).isActive = true
    scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 8.0).isActive = true
    scrollView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -8.0).isActive = true
    scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -8.0).isActive = true
    scrollView.addSubview(labelOne)
    
    labelOne.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 16.0).isActive = true
    labelOne.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 16.0).isActive = true
    labelOne.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: -16).isActive = true
    labelOne.heightAnchor.constraint(equalToConstant: 100).isActive = true
  }
}

附注 我知道如果我将内容视图放在 UIScrollView 中并在该内容中构建视图层次结构会更好,但我真的想知道为什么会发生这种情况

【问题讨论】:

  • 首先,不要设置.contentSize——使用自动布局。二、将子视图约束到scrollView的.contentLayoutGuide

标签: ios swift uiscrollview autolayout


【解决方案1】:

看看这个...

我们设置labelOne(红色视图):

  • 宽度为 1968 点(每边 2000 减去 16 点)
  • 高度为 100 分
  • 顶部,在滚动视图.contentLayoutGuide 顶部和前导的 16 点处前导和尾随
  • 底部距离滚动视图.contentLayoutGuide 底部 1884 分

所以:

class ViewController: UIViewController {
    
    let labelOne: UIView = {
        let label = UIView()
        label.backgroundColor = .red
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    let scrollView: UIScrollView = {
        let v = UIScrollView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .cyan
        // don't set this
        //v.contentSize = CGSize(width: 2000, height: 2000)
        return v
    }()
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addSubview(scrollView)
        scrollView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 8.0).isActive = true
        scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 8.0).isActive = true
        scrollView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -8.0).isActive = true
        scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -8.0).isActive = true
        scrollView.addSubview(labelOne)

        // don't constrain directly to scrollView
        //labelOne.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 16.0).isActive = true
        //labelOne.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 16.0).isActive = true
        //labelOne.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: -16).isActive = true
        //labelOne.heightAnchor.constraint(equalToConstant: 100).isActive = true
        
        // if we want horizontal scrolling of 2000-pts
        //  and labelOne to have 16-pts space on each side
        labelOne.widthAnchor.constraint(equalToConstant: 2000.0 - 32.0).isActive = true
        
        // labelOne height = 100
        labelOne.heightAnchor.constraint(equalToConstant: 100.0).isActive = true
        
        // use scrollView's Content Layout Guide
        let g = scrollView.contentLayoutGuide
        
        // labelOne 16-pts from top
        labelOne.topAnchor.constraint(equalTo: g.topAnchor, constant: 16.0).isActive = true
        
        // labelOne 16-pts from leading
        labelOne.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 16.0).isActive = true
        
        // labelOne 16-pts from trailing (so we can scroll 2000-pts
        labelOne.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -16.0).isActive = true
        
        // if we want vertical scrolling of 2000-pts
        //  and labelOne to be 100-pts tall with 16-pts on top
        //  constrain labelOne bottom (2000 - (100 + 16)) from content guide bottom
        labelOne.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: -(2000.0 - (100.0 + 16.0))).isActive = true

    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-19
    相关资源
    最近更新 更多