【问题标题】:Resize superview according to label's font size and image's aspect ratio根据标签的字体大小和图像的纵横比调整超级视图的大小
【发布时间】:2020-05-10 12:06:19
【问题描述】:

这是一个与自动布局相关的问题。我有containerView,它有两个子视图:imageViewlabel。我想让label的fontsize根据imageView的纵横比决定containerView的大小。

当字体大小增加时,containerViewimageView 应该会变大,同时保持纵横比并保持label 居中并带有一些填充,如下图所示。

我想以编程方式实现它。

任何帮助将不胜感激

【问题讨论】:

    标签: swift uiview autolayout uilabel dynamic-type-feature


    【解决方案1】:

    您可以通过以下方式完成此操作:

    • 将图像视图约束到容器的所有 4 个侧面
    • 将标签限制在容器的中心
    • 将图像视图限制为 16:9 的比例
    • 将图像视图的高度限制为标签的高度 + 所需的“填充”

    这是一个示例,包括增加/减小字体大小的按钮:

    class WalterViewController: UIViewController {
    
        let theContainerView: UIView = {
            let v = UIView()
            v.backgroundColor = .blue
            return v
        }()
    
        let theImageView: UIImageView = {
            let v = UIImageView()
            v.backgroundColor = .red
            v.contentMode = .scaleToFill
            return v
        }()
    
        let theLabel: UILabel = {
            let v = UILabel()
            v.backgroundColor = .yellow
            v.textAlignment = .center
            v.text = "TEST"
            // content vertical hugging REQUIRED !!!
            v.setContentHuggingPriority(.required, for: .vertical)
            return v
        }()
    
        let btnUp: UIButton = {
            let b = UIButton(type: .system)
            b.backgroundColor = UIColor(white: 0.9, alpha: 1.0)
            b.setTitle("Increase", for: .normal)
            return b
        }()
    
        let btnDn: UIButton = {
            let b = UIButton(type: .system)
            b.backgroundColor = UIColor(white: 0.9, alpha: 1.0)
            b.setTitle("Decrease", for: .normal)
            return b
        }()
    
        let btnStack: UIStackView = {
            let v = UIStackView()
            v.axis = .horizontal
            v.spacing = 12
            v.distribution = .fillEqually
            return v
        }()
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // we'll be using constraints
            [theContainerView, theImageView, theLabel, btnUp, btnDn, btnStack].forEach {
                $0.translatesAutoresizingMaskIntoConstraints = false
            }
    
            // add buttons to the stack
            btnStack.addArrangedSubview(btnUp)
            btnStack.addArrangedSubview(btnDn)
    
            // add imageView and label to container
            theContainerView.addSubview(theImageView)
            theContainerView.addSubview(theLabel)
    
            // add button stack and container view to view
            view.addSubview(btnStack)
            view.addSubview(theContainerView)
    
            // respect safe area
            let g = view.safeAreaLayoutGuide
    
            NSLayoutConstraint.activate([
    
                // horizontal button stack 20-points from top, 40-points on each side
                btnStack.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),
                btnStack.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 40.0),
                btnStack.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -40.0),
    
                // container view centered in view safeArea
                theContainerView.centerXAnchor.constraint(equalTo: g.centerXAnchor),
                theContainerView.centerYAnchor.constraint(equalTo: g.centerYAnchor),
    
                // constrain image view to its superView (container view)
                // 8-pts on all 4 sides
                theImageView.topAnchor.constraint(equalTo: theContainerView.topAnchor, constant: 8.0),
                theImageView.leadingAnchor.constraint(equalTo: theContainerView.leadingAnchor, constant: 8.0),
                theImageView.trailingAnchor.constraint(equalTo: theContainerView.trailingAnchor, constant: -8.0),
                theImageView.bottomAnchor.constraint(equalTo: theContainerView.bottomAnchor, constant: -8.0),
    
                // label is centered in its superView (container view)
                theLabel.centerXAnchor.constraint(equalTo: theContainerView.centerXAnchor),
                theLabel.centerYAnchor.constraint(equalTo: theContainerView.centerYAnchor),
    
                // constrain imageView to 16:9 ratio
                theImageView.widthAnchor.constraint(equalTo: theImageView.heightAnchor, multiplier: 16.0 / 9.0),
    
                // constrain imageView's height to label's height +40
                // will result in 20-pts on top and bottom
                theImageView.heightAnchor.constraint(equalTo: theLabel.heightAnchor, constant: 40.0),
    
            ])
    
            // load an image
            if let img = UIImage(named: "bkg640x360") {
                theImageView.image = img
            }
    
            // add targets to buttons to increase / decrease the label's font size
            btnUp.addTarget(self, action: #selector(increaseTapped(_:)), for: .touchUpInside)
            btnDn.addTarget(self, action: #selector(decreaseTapped(_:)), for: .touchUpInside)
    
        }
    
        @objc func increaseTapped(_ sender: Any?) -> Void {
            theLabel.font = theLabel.font.withSize(theLabel.font.pointSize + 1.0)
        }
    
        @objc func decreaseTapped(_ sender: Any?) -> Void {
            theLabel.font = theLabel.font.withSize(theLabel.font.pointSize - 1.0)
        }
    
    }
    

    它在启动时的样子(容器视图以根视图为中心):

    并且,在点击增加一堆之后:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-10
      • 1970-01-01
      • 2013-06-26
      • 2012-04-15
      相关资源
      最近更新 更多