Изменение размера суперпредставления в соответствии с размером шрифта ярлыка и соотношением сторон изображения - PullRequest
0 голосов
/ 24 января 2020

Это вопрос, связанный с автоматическим макетом. У меня есть containerView, у которого есть два подпредставления: imageView и label. Я хочу, чтобы размер шрифта label определял размер containerView в соответствии с соотношением сторон imageView.

Когда размер шрифта увеличивается, containerView и imageView должны увеличиваться, сохраняя соотношение сторон и сохраняя центрирование label с некоторыми отступами, как показано на рисунке ниже.

И я хочу достичь этого программно.

Любая помощь будет высоко ценится

enter image description here

1 Ответ

1 голос
/ 24 января 2020

Вы можете выполнить sh это следующим образом:

  • ограничить вид изображения для всех 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)
    }

}

Как это выглядит при запуске (представление контейнера центрировано в root представлении):

enter image description here

и после нажатия Увеличить связку раз:

enter image description here

...