【问题标题】:How to resize content view in UIScrollView programmatically?如何以编程方式调整 UIScrollView 中内容视图的大小?
【发布时间】:2020-09-14 14:05:53
【问题描述】:

问题是:我需要以编程方式将包含其他子视图的视图添加到滚动视图中。另外,我还需要让这样一个视图的框架坚持主超级视图的边界。下面的代码显示了我试图实现的方法,但正如您从下面的图片中看到的那样,当屏幕旋转时,“contentView”没有更新其帧大小。初始代码取自here,用于演示目的。任何帮助将不胜感激。

import UIKit

class TestViewController : UIViewController {
    
    var contentViewSize = CGSize()
    
    let contentView: UIView = {
        let view = UIView()
        view.backgroundColor = .magenta
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()
    
    let labelOne: UILabel = {
        let label = UILabel()
        label.text = "Scroll Top"
        label.backgroundColor = .red
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    let labelTwo: UILabel = {
        let label = UILabel()
        label.text = "Scroll Bottom"
        label.backgroundColor = .green
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    let scrollView: UIScrollView = {
        let v = UIScrollView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .cyan
        return v
    }()
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        contentViewSize = view.bounds.size
        labelTwo.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: (contentViewSize.width - labelTwo.frame.size.width - 16.0)).isActive = true
        
        labelTwo.topAnchor.constraint(equalTo: contentView.topAnchor, constant: (contentViewSize.height - labelTwo.frame.size.height - 16.0)).isActive = true
    }
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        contentViewSize = view.bounds.size
        
        view.backgroundColor = .yellow
        
        self.view.addSubview(scrollView)
        
        scrollView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 8.0).isActive = true
        scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 8.0).isActive = true
        scrollView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -8.0).isActive = true
        scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -8.0).isActive = true
        
        scrollView.addSubview(contentView)
        
        contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 16).isActive = true
        contentView.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 16).isActive = true
        contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 16).isActive = true
        contentView.rightAnchor.constraint(equalTo: scrollView.rightAnchor, constant: 16).isActive = true
        
        contentView.addSubview(labelOne)
        
        labelOne.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16.0).isActive = true
        labelOne.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 16.0).isActive = true
        
        contentView.addSubview(labelTwo)
        
        labelTwo.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: (contentViewSize.width - labelTwo.frame.size.width - 16.0)).isActive = true
        
        labelTwo.topAnchor.constraint(equalTo: contentView.topAnchor, constant: (contentViewSize.height - labelTwo.frame.size.height - 16.0)).isActive = true
        
        labelTwo.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -16.0).isActive = true
        labelTwo.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -16.0).isActive = true
        
    }
    
}

【问题讨论】:

    标签: swift uiscrollview uikit resize programmatically


    【解决方案1】:

    您对链接到的答案中的代码进行了一些奇怪的更改。另外,这个答案有点过时了。

    这是一个更好的例子。假设您想要仅垂直滚动,这将:

    • 添加青色滚动视图,在安全区域的每一侧插入 8 点
    • 将洋红色“内容视图”添加到滚动视图,每侧 16 磅限制在滚动视图的 contentLayoutGuide,宽度比滚动视图的框架小 32 磅(每边 16 分)
    • 在内容视图的左上角添加标签
    • 在内容视图的右下角添加标签
    • 将底部标签限制在顶部标签下方 1500 点处(因此它会垂直滚动)

    代码:

    class ScrollTestViewController : UIViewController {
        
        let contentView: UIView = {
            let view = UIView()
            view.backgroundColor = .magenta
            view.translatesAutoresizingMaskIntoConstraints = false
            return view
        }()
        
        let labelOne: UILabel = {
            let label = UILabel()
            label.text = "Scroll Top"
            label.backgroundColor = .red
            label.translatesAutoresizingMaskIntoConstraints = false
            return label
        }()
        
        let labelTwo: UILabel = {
            let label = UILabel()
            label.text = "Scroll Bottom"
            label.backgroundColor = .green
            label.translatesAutoresizingMaskIntoConstraints = false
            return label
        }()
        
        let scrollView: UIScrollView = {
            let v = UIScrollView()
            v.translatesAutoresizingMaskIntoConstraints = false
            v.backgroundColor = .cyan
            return v
        }()
        
        override func viewDidLoad() {
            super.viewDidLoad()
            
            view.backgroundColor = .yellow
            
            // add the scroll view
            self.view.addSubview(scrollView)
            
            // add contentView to scroll view
            scrollView.addSubview(contentView)
            
            // add two labels to contentView
            contentView.addSubview(labelOne)
            contentView.addSubview(labelTwo)
                    
            // respect safe-area
            let g = view.safeAreaLayoutGuide
            
            // if you want to ignore the safe-area (bad idea),
            //  use this instead
            //let g = view!
            //scrollView.contentInsetAdjustmentBehavior = .never
            
            // we're going to constrain the contentView to the scroll view's content layout guide
            let scg = scrollView.contentLayoutGuide
            
            NSLayoutConstraint.activate([
                
                // constrain scrollView Top / Leading / Trailing / Bottom to view (safe-area)
                //  with 8-pts on each side
                scrollView.topAnchor.constraint(equalTo: g.topAnchor, constant: 8.0),
                scrollView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 8.0),
                scrollView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -8.0),
                scrollView.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: -8.0),
                
                // constrain contentView Top / Leading / Trailing / Bottom to scroll view's Content Layout Guide
                //  with 16-pts on each side
                contentView.topAnchor.constraint(equalTo: scg.topAnchor, constant: 16.0),
                contentView.leadingAnchor.constraint(equalTo: scg.leadingAnchor, constant: 16.0),
                contentView.trailingAnchor.constraint(equalTo: scg.trailingAnchor, constant: -16.0),
                contentView.bottomAnchor.constraint(equalTo: scg.bottomAnchor, constant: -16.0),
    
                // if we only want vertical scrolling, constrain contentView Width
                // to scrollView's Frame Layout Guide minus 32-pts (because we have 16-pts on each side)
                contentView.widthAnchor.constraint(equalTo: scrollView.frameLayoutGuide.widthAnchor, constant: -32.0),
                
                // constrain labelOne Top / Leading 16-pts to contentView Top / Leading
                //  (so it shows up at top-left corner)
                labelOne.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 16.0),
                labelOne.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16.0),
                
                // constrain labelTwo Bottom / Trailing 16-pts to contentView Bottom / Trailing
                //  (so it shows up at bottom-right corner)
                labelTwo.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16.0),
                labelTwo.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -16.0),
                
                // constrain labelTwo Top to labelOne Bottom + 1500-pts
                //  so we'll have some vertical scrolling to get to it
                labelTwo.topAnchor.constraint(equalTo: labelOne.bottomAnchor, constant: 1500.0),
                
            ])
                    
        }
        
    }
    

    【讨论】:

    • @Andrey - 如果这解决了问题,请务必“接受”答案(为了其他可能看到您帖子的人的利益)。
    猜你喜欢
    • 1970-01-01
    • 2017-03-23
    • 2018-04-22
    • 1970-01-01
    • 2011-02-27
    • 1970-01-01
    • 2016-01-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多