【问题标题】:UIScrollView width is wider than screenUIScrollView 宽度比屏幕宽
【发布时间】:2018-05-30 00:02:40
【问题描述】:

我在 MyView 文件中以编程方式创建了一个滚动视图。

let myScrollView: UIScrollView = {
    let scrollView = UIScrollView()
    scrollView.translatesAutoresizingMaskIntoConstraints = false
    scrollView.isUserInteractionEnabled = true
    return scrollView
}()

使用可视化格式语言,我将所有约束都设置为 superView。

  func setupViews() {
    self.frame = UIScreen.main.bounds

    addSubview(myScrollView)

    addConstraintsWithFormat(format: "H:|[v0]|", views: myScrollView)
    addConstraintsWithFormat(format: "V:|[v0]|", views: myScrollView)    

}

我的 scrollView 有一个按钮和一个标签。

在 viewDidLayoutSubviews 的 viewController 中,我设置了 contentSize:

myView.myScrollView.contentSize = CGSize(width: self.view.frame.size.width, height: self.view.frame.size.height + 200)

一切正常:我可以滚动,myScrollView 的高度完美,但宽度仅适用于 iPhone X。

以下是 iPhone SE 的示例:

ScrollView 比屏幕宽。在 iPhone Plus 中,它比屏幕小。

我做错了什么,我该如何解决?

提前谢谢你!

【问题讨论】:

标签: swift uiscrollview width scrollview


【解决方案1】:

首先,永远不要在layoutSubviews() 中使用addSubview。这意味着您在每个布局中添加您的视图。您最终可能会在层次结构中拥有多个滚动视图。

其次,您可以只做一个scrollView.frame = bounds 并相应地计算您的实际contentSize。内容大小与滚动视图的frame 无关。您需要获得最底部的视图并获得他的最大值。 X轴也是如此。如果您希望内容仅垂直滚动,则可以使用 contentSize = CGSize(width: width, height: lastViewInScrollView.frame.maxY) 之类的内容。

如果您绝对需要 VFL,至少要正确计算您的 contentSize(即使用 scrollView 中包含的实际视图帧)

至于你的视图被布局在滚动视图之外,可能是你为这些视图设置了错误的尺寸。

【讨论】:

  • 弗朗西斯,感谢您的建议。我确实改变了你提到的但仍然有同样的问题。
【解决方案2】:

同时使用自动布局和滚动视图时,无需计算任何显式大小。在loadView 中创建滚动视图(纯程序化应用程序很可能会在此处创建)或viewDidLoad

override func loadView() {

    ...
    addScrollView()
    addScrollViewHeader()
    // add subviews
    addScrollViewFooter()

}

func addScrollView() {

    scrollView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(scrollView)
    scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    scrollView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1).isActive = true
    scrollView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 1).isActive = true

}

Apple 的文档中有一些规则可以使其与自动布局一起使用,例如,如果我没记错的话,不依赖于滚动视图本身来确定其中任何子视图的大小。但想法是确保最外层的视图(最顶部、最底部、最左侧、最右侧)锚定到滚动视图,并且滚动视图的内容大小会自动缩放。

所以我要做的是在顶部和底部创建透明视图,为我拉伸滚动视图的内容大小,然后中间的任何内容都会自动扩展和收缩滚动视图。我使用这些页眉/页脚视图而不是简单地向最顶层约束和最底层约束添加一个常量(在滚动视图的顶部和底部创建一些额外的填充)的原因是因为常量似乎被忽略了.视图和内容大小的边缘之间必须有表面上的“物理”接触才能拉伸它。

func addScrollViewHeader() {

    scrollViewHeader.isUserInteractionEnabled = false
    scrollViewHeader.translatesAutoresizingMaskIntoConstraints = false
    scrollView.addSubview(scrollViewHeader)
    scrollViewHeader.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
    scrollViewHeader.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
    scrollViewHeader.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
    scrollViewHeader.heightAnchor.constraint(equalToConstant: Shared.statusBarHeight + 32).isActive = true

}

// 中间的子视图

func addScrollViewFooter() {

    scrollViewFooter.isUserInteractionEnabled = false
    scrollViewFooter.translatesAutoresizingMaskIntoConstraints = false
    scrollView.addSubview(scrollViewFooter)
    scrollViewFooter.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
    scrollViewFooter.topAnchor.constraint(equalTo: lastView.bottomAnchor).isActive = true
    scrollViewFooter.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
    scrollViewFooter.heightAnchor.constraint(equalToConstant: 32).isActive = true

    // and the most important constraint to make it work
    scrollViewFooter.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true

}

【讨论】:

  • Mia 感谢您的帮助,但其他解决方案对我很有效。
猜你喜欢
  • 1970-01-01
  • 2018-12-04
  • 1970-01-01
  • 1970-01-01
  • 2013-08-05
  • 2017-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多