在 Swift 中以编程方式添加时,UIScrollView 根本不滚动?

Posted

技术标签:

【中文标题】在 Swift 中以编程方式添加时,UIScrollView 根本不滚动?【英文标题】:UIScrollView not scrolling at all when added programmatically in Swift? 【发布时间】:2017-02-17 06:41:35 【问题描述】:

所以,我浏览了 *** 对这个特定问题的几乎所有答案,甚至浏览了据称教你如何使用滚动视图但它似乎不适用于我的项目的教程。..

这是我目前所知道的,为了让滚动视图正常工作,您首先需要给它一个内容大小。这决定了可滚动的高度等。

我提供了一些代码,让大家更好地了解我如何将所述项目添加到我的滚动视图中。如果我做错了什么,或者如果有更好的方法来做这件事,请告诉我,我对 Swift 和 ios 开发还很陌生,在我看来,我觉得我做得对。

我正在采取的步骤

    创建我想要显示的项目(输入字段、图像视图等) 将所述项目添加到视图控制器的视图中。 (view.addsubview(etc..)) 创建一个滚动视图并将其约束设置为与屏幕/视图相同 将包含所有项目的视图添加到所述滚动视图中 放松,一切都应该完美无瑕?????

这是我的代码,我知道它可能很长,但我认为可能需要它以便理解我的问题的范围

class JobRegistrationController: UIViewController 

// ... Omitted for clarity
lazy var scrollView: UIScrollView = 
    let view = UIScrollView(frame: UIScreen.main.bounds)
    view.backgroundColor = .red
    view.contentSize = CGSize(width: self.view.bounds.width, height: self.view.bounds.height * 2)
    view.translatesAutoresizingMaskIntoConstraints = false
    return view
()

//... Omitted for clarity

    let scrollContentView: UIView = 
    let view = UIView()
    view.translatesAutoresizingMaskIntoConstraints = false
    return view
()

override func viewDidLoad() 
    super.viewDidLoad()

    // Need so that view controller is not behind nav controller
    self.edgesForExtendedLayout = []

    view.addSubview(scrollView)
    scrollView.addSubview(scrollContentView)
    scrollContentView.addSubview(jobTypeField)
    scrollContentView.addSubview(jobTypeDividerLine)

    // x, y, width and height constraints
    scrollView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
    scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    scrollView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
    scrollView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true

    // x, y, width and height constraints
    scrollContentView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
    scrollContentView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    scrollContentView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
    scrollContentView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true

    // x, y, width and height constraints
    jobTypeField.leftAnchor.constraint(equalTo: scrollContentView.leftAnchor, constant: 20).isActive = true
    jobTypeField.topAnchor.constraint(equalTo: scrollContentView.topAnchor).isActive = true
    jobTypeField.rightAnchor.constraint(equalTo: scrollContentView.rightAnchor, constant: -8).isActive = true
    jobTypeField.heightAnchor.constraint(equalToConstant: 30).isActive = true

    // x, y, width and height constraints
    jobTypeDividerLine.leftAnchor.constraint(equalTo: scrollContentView.leftAnchor, constant: 20).isActive = true
    jobTypeDividerLine.topAnchor.constraint(equalTo: jobTypeField.bottomAnchor).isActive = true
    jobTypeDividerLine.rightAnchor.constraint(equalTo: scrollContentView.rightAnchor).isActive = true
    jobTypeDividerLine.heightAnchor.constraint(equalToConstant: 0.5).isActive = true

【问题讨论】:

【参考方案1】:

在你的课堂上使用这个方法

  override func viewDidLayoutSubviews()
  
   scrollView.delegate = self
   scrollView.contentSize = CGSize(width:self.view.frame.size.width, height: 1000) // set height according you
  

【讨论】:

您好,感谢您的建议。当我在视图中滚动时,我可以看到滚动条上下移动,但视图的内容没有移动 我认为您的视图未正确添加到滚动视图中。在滚动视图中添加内容视图。 您好,您对如何执行此操作有任何建议吗?我在我的代码中进行了编辑,添加了滚动内容视图,但它做同样的事情【参考方案2】:
view.contentSize = CGSize(width: self.view.bounds.width, height: self.view.bounds.height * 2)

在尝试访问contentSize 后,您应该尝试在控制台中记录它。我不确定您是否在此处设置了正确的contentSize,如果此时调用 self.view.bounds 时计算正确。因为 self.view 框架和边界的计算需要时间。

尝试设置您的contentSize根据实际总内容大小向其中添加实际内容之后。

编辑:

scrollView 中添加一个UIView,并将约束设置为top-bottom-leading-trailing,并将您的子视图添加到其中。另外,将 scrollView 上的相同约束设置为 superView top-bottom-leading-trailing。

【讨论】:

您好,感谢您的建议。当我在视图中滚动时,我可以看到滚动条上下移动,但视图的内容没有移动 @EdwardLim 这是另一个问题。解决方案是将所有子视图放在单个 UIView 中,然后将单个 UIView 作为子视图添加到 scrollView 中。避免所有子视图都包含在滚动视图中,而没有一个 UIView“scrollContentView”。否则,您将遇到例如您所描述的大量错误。 嗨,您能建议如何正确执行此操作吗?我已经尝试在滚动视图中添加一个视图,但它似乎在做同样的事情。 @EdwardLim 我真的从不通过代码添加任何约束,我发现在 AutoLayout 中很容易做到这一点真的很乱,所以我可能无法通过代码帮助你。但是你需要的基本上是一个 UIView 作为你的滚动视图中的子视图。 UIView 的滚动视图的底部顶部尾随前导应为 0。在这个 UIView 中,你添加了所有的子视图。就是这样。要查看错误所在,请记录 contentSize 和子视图大小并查看子视图是否小于 contentsize。也 @EdwardLim remember 在您的子视图上调用 layoutIfNeeded,如果您这样做,则在更改约束常量时更改约束。【参考方案3】:

我相信下面这行代码是问题所在

scrollContentView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true

您正在将内容视图设置到视图的顶部,而您应该将其设置到滚动视图的顶部。

我刚刚克服了一个类似的问题,我将第一个视图的 topAnchor 设置为滚动视图的 safeAreaLayoutGuide.topAnchor。一切都正确布局,但约束不会显示,因此 scrollView 的全部内容没有移动。

【讨论】:

【参考方案4】:

问题在于您不知道内容的底部在哪里。换句话说,您需要一些底部约束。

如果你使用...

scrollContentView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true

...您还需要添加一个约束以将至少一个视图绑定到 UIScrollView 的底部,例如:

scrollContentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true

...并将scrollContentView中的最后一个视图绑定到它的bottomAnchor。

jobTypeDividerLine.bottomAnchor.constraint(equalTo: scrollContentView.bottomAnchor).isActive = true

这肯定会解决您的问题。因为这样整个约束序列是从上到下链接的。

底线,UIScrollView 并不聪明,它以各种可能的方式确定自己的底部。这是一种懒惰。如果你没有告诉他足够多,它就不会简单地滚动,而很明显你的内容会消失在 UIScrollView 容器的底部。

【讨论】:

以上是关于在 Swift 中以编程方式添加时,UIScrollView 根本不滚动?的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 中以编程方式将视图添加到 stackview

在 iOS Swift 3 中以编程方式添加 Web 视图时如何在 UIWebView 中获取响应状态代码?

当 iAd 横幅出现时,如何将视图的内容上移? (在 Swift 中以编程方式)

如何在 Swift 5 中以编程方式从右上角添加垂直按钮列表

在 Swift 中以编程方式在 UITableViewCell 中创建一个 UICollectionView

在 Swift 中以编程方式添加约束不起作用