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

Ios 将UIView添加到UIScrollView不会更改内容大小?,ios,swift,uiscrollview,Ios,Swift,Uiscrollview,我正在向UIScrollView添加一个非常大的UIView,但是滚动视图不会滚动显示整个子视图 当我向UIScrollView添加标签时,它会滚动显示该标签 在我正在处理的实际项目中,我在scrollView中添加了许多视图,它根本不滚动。这是一个简单的示例来说明我的问题: import UIKit class ViewController: UIViewController { let scrollView: UIScrollView = { let sc

我正在向UIScrollView添加一个非常大的UIView,但是滚动视图不会滚动显示整个子视图

当我向UIScrollView添加标签时,它会滚动显示该标签

在我正在处理的实际项目中,我在scrollView中添加了许多视图,它根本不滚动。这是一个简单的示例来说明我的问题:

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

    }
}
按原样,这不会滚动。但是,如果您注释掉指定的部分,它就会注释掉

为什么会这样?它如何使添加子视图到scrollView使其滚动


谢谢

这两件事根本不是平行的。你有一个例子说明什么是有效的,但在你的另一个例子中你没有这样做,这就是为什么它不起作用。更改:

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
致:


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
       
       }
   }
/* 
 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
       
       }
   }