Почему установка шрифта uibutton мешает моим слоям

Я пытаюсь создать пользовательский интерфейс регистрации входа в Swift для iOS без использования раскадровки.

С помощью этого кода в моем контроллере:

    loginButton.translatesAutoresizingMaskIntoConstraints = false
    loginButton.layer.borderWidth = 1
    loginButton.clipsToBounds = true
    loginButton.layer.borderColor = UIColor.Palette.boldYellow.cgColor
    loginButton.setTitle("Login", for: .normal)
    loginButton.setTitleColor(UIColor.Palette.boldYellow, for: .normal)
    loginButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 24)
    loginButton.heightAnchor.constraint(equalToConstant: 58).isActive = true
    NSLayoutConstraint(item: loginButton, attribute: .leading, relatedBy: .equal, toItem: footerView, attribute: .leading, multiplier: 1, constant: 30).isActive = true
    NSLayoutConstraint(item: loginButton, attribute: .trailing, relatedBy: .equal, toItem: footerView, attribute: .trailing, multiplier: 1, constant: -30).isActive = true
    NSLayoutConstraint(item: loginButton, attribute: .top, relatedBy: .equal, toItem: footerView, attribute: .top, multiplier: 1, constant: 21).isActive = true

    registerButton.translatesAutoresizingMaskIntoConstraints = false
    registerButton.clipsToBounds = true
    registerButton.setTitle("Register", for: .normal)
    registerButton.setTitleColor(.white, for: .normal)
    registerButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 24)
    registerButton.heightAnchor.constraint(equalToConstant: 58).isActive = true
    NSLayoutConstraint(item: registerButton, attribute: .leading, relatedBy: .equal, toItem: footerView, attribute: .leading, multiplier: 1, constant: 30).isActive = true
    NSLayoutConstraint(item: registerButton, attribute: .trailing, relatedBy: .equal, toItem: footerView, attribute: .trailing, multiplier: 1, constant: -30).isActive = true
    NSLayoutConstraint(item: registerButton, attribute: .bottom, relatedBy: .equal, toItem: footerView, attribute: .bottom, multiplier: 1, constant: -21).isActive = true

Я могу добиться этого:

enter image description here

Но я бы хотел сделать текст «Регистрация» более жирным, поэтому я добавляю эту строку:

registerButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 24)

Незадолго до

registerButton.heightAnchor.constraint(equalToConstant: 58).isActive = true

Но потом весь интерфейс сломан, и я получил вот что:

enter image description here

Похоже, что изменения, которые я внес в слой обеих кнопок, не применяются.

Я делаю эти изменения уровня в переопределении viewDidLayoutSubviews моего контроллера:

  override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    let gradientBackgroundButton = CAGradientLayer()
    gradientBackgroundButton.frame = registerButton.bounds
    gradientBackgroundButton.startPoint = CGPoint.zero
    gradientBackgroundButton.endPoint = CGPoint(x: 1, y: 1)
    gradientBackgroundButton.colors = [UIColor.Palette.lightYellow.cgColor, UIColor.Palette.boldYellow.cgColor]

    registerButton.layer.insertSublayer(gradientBackgroundButton, at: 0)

    registerButton.layer.cornerRadius = registerButton.bounds.height / 2
    loginButton.layer.cornerRadius = loginButton.bounds.height / 2
}

Я предполагаю, что когда я не указываю размер шрифта, мое представление должно вызывать viewDidLayoutSubviews, но не тогда, когда я его указываю. В этом случае, где я должен изменить слой моих кнопок?

Этот код отлично работает на моем симуляторе, я просто указываю, что высота нижнего колонтитула исправлена.

VDPurohit 31.10.2018 12:12

Да, он работает нормально, когда вы предоставляете представлениям фиксированные размеры, устанавливая свойство view.bounds.height, но я хочу работать с ограничениями, чтобы пользовательский интерфейс оставался максимально отзывчивым. @VDPurohit

YoanGJ 31.10.2018 12:23
2
2
107
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю, твоя догадка верна. viewDidLayoutSubviews можно вызывать много-много раз, и в настоящее время каждый раз, когда он вызывается, вы собираетесь создавать и добавлять новый слой градиента. Добавьте точку останова в viewDidLayoutSubviews и посмотрите, как часто он запускается и каковы значения размера кнопки.

Вам нужно либо проверить наличие градиентного слоя, прежде чем вставлять и изменять его размер, либо, в идеале, переместить всю эту логику в подклассы UIButton, которые могут сохранять свои собственные ссылки на слои и обрабатывать их при изменении размера самой кнопки.

Как вы сказали, я перенесу всю логику в подкласс UIButton, поскольку, когда я печатаю значение границ моих кнопок в viewDidLayoutSubviews, я получаю 0,0, 0,0, а метод вызывается только один раз, поэтому мой единственный вариант - выбрать наиболее идеальное решение ( что здорово)

YoanGJ 31.10.2018 12:07

Другие вопросы по теме