简体   繁体   English

将 UIView 添加到 UIScrollView 不会改变内容大小?

[英]Adding UIView to UIScrollView does not change content size?

I'm adding a very large UIView to a UIScrollView, however the scroll view does not scroll to show the whole subview.我正在向 UIScrollView 添加一个非常大的 UIView,但是滚动视图不会滚动以显示整个子视图。

When I add a label to the UIScrollView, it does scroll to show that label.当我将 label 添加到 UIScrollView 时,它会滚动显示 label。

On the actual project I'm working on, I added many views within the scrollView and it is not scrolling at all.在我正在处理的实际项目中,我在 scrollView 中添加了许多视图,但它根本没有滚动。 This is a simplified example to show my problem:这是显示我的问题的简化示例:

import UIKit

class ViewController: UIViewController {
    
    let scrollView: UIScrollView = {
        let scroll = UIScrollView()
        scroll.backgroundColor = .blue
        scroll.translatesAutoresizingMaskIntoConstraints = false
        return scroll
    }()
    
    let viewDoesntWork: UIView = {
        let view = UIView()
        view.backgroundColor = .purple
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()
    
    let labelWorks: UILabel = {
         let label = UILabel()
         label.text = "Why this work?"
         label.backgroundColor = .green
         label.translatesAutoresizingMaskIntoConstraints = false
         return label
     }()
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .red
        
        // Add scrollView to view, 20 from edges of view on all sides
        view.addSubview(scrollView)
        scrollView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20).isActive = true
        scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 20).isActive = true
        scrollView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -20).isActive = true
        scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -20).isActive = true
        
        
        // OPTION 1 (does not work):
        // Add viewDoesntWork to view, make it much bigger than the scrollView fits
        scrollView.addSubview(viewDoesntWork)
        viewDoesntWork.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 20).isActive = true
        viewDoesntWork.leftAnchor.constraint(equalTo: scrollView.leftAnchor, constant: 20).isActive = true
        viewDoesntWork.widthAnchor.constraint(equalToConstant: 1000).isActive = true
        viewDoesntWork.heightAnchor.constraint(equalToConstant: 1000).isActive = true
        
        
        // OPTION 2 (works):
        // Add labelWorks to scrollView, and it does scroll to it. 
        // Uncomment this to see that work.
        // scrollView.addSubview(labelWorks)
        // labelWorks.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 1000).isActive = true
        // labelWorks.leftAnchor.constraint(equalTo: scrollView.leftAnchor, constant: 1000).isActive = true
        // labelWorks.rightAnchor.constraint(equalTo: scrollView.rightAnchor, constant: -20).isActive = true
        // labelWorks.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: -20).isActive = true

    }
}

As is, this does not scroll.照原样,这不会滚动。 But, if you comment out the specified section, it does.但是,如果您注释掉指定的部分,它会这样做。

Why is this?为什么是这样? How can it make it such that adding subViews to the scrollView makes it scroll?怎样才能使向 scrollView 添加子视图使其滚动?

Thanks!谢谢!

The two things are not at all parallel.这两件事根本不是平行的。 You have an example of what works, but in your other example you are not doing that, and that is why it doesn't work.您有一个有效的示例,但在您的另一个示例中,您没有这样做,这就是它不起作用的原因。 Change:改变:

viewDoesntWork.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 20).isActive = true
viewDoesntWork.leftAnchor.constraint(equalTo: scrollView.leftAnchor, constant: 20).isActive = true
viewDoesntWork.widthAnchor.constraint(equalToConstant: 1000).isActive = true
viewDoesntWork.heightAnchor.constraint(equalToConstant: 1000).isActive = true

To:至:

viewDoesntWork.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 0).isActive = true
viewDoesntWork.leftAnchor.constraint(equalTo: scrollView.leftAnchor, constant: 0).isActive = true
viewDoesntWork.widthAnchor.constraint(equalToConstant: 1000).isActive = true
viewDoesntWork.heightAnchor.constraint(equalToConstant: 1000).isActive = true
viewDoesntWork.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 0).isActive = true
viewDoesntWork.rightAnchor.constraint(equalTo: scrollView.rightAnchor, constant: 0).isActive = true

The answer of matt causes a [LayoutConstraints] problem in the console here is my simplified Answer matt 的答案在控制台中导致 [LayoutConstraints] 问题这里是我的简化答案

/* 
 I  shortened and  simplified your code, I also added some 
 explanations such that you could understand that's why the code will 
 seem long
*/
// let's call the viewDoesntWork view1

// first of all you didn't give a frame to the view1
/* 
secondly you didn't set the content size(the content size is the 
size of the scrollable area) of the scrollView!!
if the scrollView doesn't have a contentSize , it won't scroll
 */


/* 
 you don't need to set translatesAutoresizingMaskIntoConstraints = 
false for labelWorks

 Adding UIView to UIScrollView does not change the content size, you 
 have to set it manually
*/
import UIKit


class ViewController: UIViewController {

   let scrollView: UIScrollView = {
   let scroll = UIScrollView()
   scroll.backgroundColor = .blue
   scroll.translatesAutoresizingMaskIntoConstraints = false
   return scroll
       }()
   
       let viewDoesntWork: UIView = {
       let view = UIView()
       view.backgroundColor = .purple
       view.translatesAutoresizingMaskIntoConstraints = false
       return view
   }()
   
       let labelWorks: UILabel = {
        let label = UILabel()
        label.text = "Why this work?"
        label.backgroundColor = .green
        return label
        }()
   
      
   //In this function we set up the frame and other stuffs of the 
   //subviews
    
       override func viewDidLayoutSubviews() {
           super.viewDidLayoutSubviews()

           // let's give it a content size
          scrollView.contentSize  = CGSize(width:view.frame.size.width , height: 1000)
     
        viewDoesntWork.frame = CGRect(x: 20, y: 20, 
          width:view.frame.size.width , height: 800)
   /*
    viewDoesntWork.topAnchor.constraint(equalTo: 
    scrollView.topAnchor, constant: 20).isActive = true isn't 
    necessary anymore 
    since we set the y = 20 , the same goes for letfAnchor and x = 20
   */
        /*
        In my opinion , you don't need to set constraints for the size 
        of the viewDoesntWork
        */
    
        labelWorks.frame = CGRect(x:view.center.x , y: 
        viewDoesntWork.frame.size.height + 20 + 40 , width:120, 
          height: 20)
        // I added your label below the viewDoesntWork
        /* 
   you don't need to set constraints, these are just some 
   calculations since you know the content size
     */
       }

       override func viewDidLoad() {
       super.viewDidLoad()
       view.backgroundColor = .red
       
       // Add scrollView to view, 20 from edges of view on all sides
       view.addSubview(scrollView)
       scrollView.addSubview(viewDoesntWork)
        scrollView.addSubview(labelWorks)
    scrollView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 
 20).isActive = true
    scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 
20).isActive = true
     scrollView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: 
-20).isActive = true
    scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 
-20).isActive = true
       
       }
   }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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