简体   繁体   中英

iOS, the height of scrollView content size is equal to the content view's height, but it can still scroll vertically?

[_contentView mas_makeConstraints:^(MASConstraintMaker *make) {
    make.edges.mas_equalTo(_scrollTabs);
    make.height.mas_equalTo(_scrollTabs);
}];

[_scrollTabs mas_makeConstraints:^(MASConstraintMaker *make) {
    make.edges.mas_equalTo(self);
}];

self is a custom view. I set the constraints like this. Am I doing something wrong? Thanks!

Bottom line, if you unambiguously define the constraints between a content view and the scroll view (which will define the contentSize pursuant to TN2154 ) and then unambiguously define the constraints between the content view and its subviews, then, yes, it will correctly define the size of the scroll view's contentSize .

I would suggest using the view debugger, 在此输入图像描述 , and look at the constraints in the right panel:

查看调试器

In the particular screen snapshot, I've selected the third subview (dark blue) inside the content view inside the scroll view, and it tells us that the active constraints are:

  • offset 10 from leading edge of container (green)
  • offset 10 from trailing edge of container (green)
  • offset 10 from the subview above (dark red)
  • fixed height of 200 (I do this because this has no implicit height)
  • a width of the main view (bright red) less 20 (so that it occupies an appropriate amount of horizontal space, again because there is no implicit width)
  • offset 10 from the subview below (light blue)

So, you just click on your various subviews and the container, and confirm that the constraints are precisely what you intended. It's all to easy to miss a constraint and/or fail to activate one, and the whole thing falls apart.

By the way, sometimes it's not obvious what views the constraints are between, but if you tap on the constraints button, 在此输入图像描述 , when a view is selected, it will highlight just the views to which you have constraints (in this example, to the content view, to the subviews above and below, and the main view; since neither the scroll view (yellow) nor the first subview (purple) have any constraints to this third subview, so you just see their wire-frame, not their content):

在此输入图像描述


Note, this is an example, I thought that I'd show you the constraints I used so that auto layout can correctly calculate the contentSize based upon a content view and subviews with fully satisfied, unambiguous constraints:

let contentView = ContentView()
contentView.translatesAutoresizingMaskIntoConstraints = false
contentView.backgroundColor = randomColor()
scrollView.addSubview(contentView)

NSLayoutConstraint.activate([
    contentView.topAnchor.constraint(equalTo: scrollView.topAnchor),
    contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
    contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
    contentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor)
])

var previousView: UIView?

for _ in 0 ..< 4 {
    let subview = SomeSubview()
    subview.translatesAutoresizingMaskIntoConstraints = false
    subview.backgroundColor = self.randomColor()
    contentView.addSubview(subview)

    NSLayoutConstraint.activate([
        subview.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10),
        subview.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10),
        subview.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -20),
        subview.heightAnchor.constraint(equalToConstant: 200)
    ])

    if previousView != nil {
        subview.topAnchor.constraint(equalTo: previousView!.bottomAnchor, constant: 10).isActive = true
    } else {
        subview.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 10).isActive = true
    }

    previousView = subview
}

previousView?.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -10).isActive = true

What strikes me odd in your example is that you are setting both edges (which I assume is setting the top, bottom, leading, and trailing constraints) and height . Setting the height of the content view is not needed. You can just define the edges and you should be good. The height is dictated by the constraints of its subviews.

If your subviews appear to be laid out correctly but your scroll view's contentSize is not getting set correctly, then the culprit may be a missing bottom constraint between the last subview and your content view.

If you're still having problems, I'd suggest you create a simplified, yet complete example of your problem. The code that you've shared is insufficient. But we don't want to see all of your code nor your specific UI, either. Instead, create a stand-alone simplified example that manifests the problem you describe. Only if we can reproduce your problem can we help you solve it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM