Динамический тип для UIButton's attributeTitle - PullRequest
0 голосов
/ 30 июня 2019

Кто-нибудь когда-нибудь работал с динамическим типом для attributedTitle на UIButton? Рассмотрим супер простой код ниже:

let font = UIFont(name: "Helvetica", size: 14)!
let scaledFont = UIFontMetrics.default.scaledFont(for: font)

let button = UIButton(type: .custom)
button.titleLabel?.font = scaledFont
button.titleLabel?.adjustsFontForContentSizeCategory = true

let attributes: [NSAttributedString.Key: Any] = [ .font: scaledFont ]
let attributedText = NSAttributedString(string: "Press me", attributes: attributes)
button.setAttributedTitle(attributedText, for: .normal)

Если я масштабирую размер шрифта вверх и вниз с помощью Accessibility Inspector, размер кнопки и текст метки не масштабируются должным образом.

Если я просто вызываю button.setTitle(), передавая обычную строку, динамическое масштабирование типов работает нормально.

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

Любые мысли или предложения будут потрясающими. Спасибо

Редактировать: После еще нескольких нажатий, похоже, что происходит то, что текст пытается масштабироваться, но ширина / высота кнопки при этом не растут. Если я набираю динамический шрифт с наибольшим размером текста, а затем создаю экран и продолжаю уменьшать размер шрифта, он работает нормально, потому что ограничения ширины / высоты кнопок имеют изначально большое значение. Но если я начну с небольшой настройки динамического типа и увеличу ее размер, кнопка не будет соответствовать изменению размера текста

Ответы [ 2 ]

1 голос
/ 04 июля 2019

На всякий случай, если кто-то последует за вами, ключ к решению этой проблемы содержится в первом абзаце поста @ XLE_22, но довольно тонок.

При вызове setAttributedTitle() на кнопке необходимо передать приписанную строку из метки .то есть.myButton.titleLabel?.attributedText ... передача локальной переменной attributedText не работает.Я не могу объяснить, почему это так.Рассмотрим следующий код:

myButton.titleLabel?.attributedText = attributedText
let labelAttributedText = myButton.titleLabel?.attributedText

myButton.setAttributedTitle(labelAttributedText, for: .normal)  // works
myButton.setAttributedTitle(attributedText, for: .normal)       // doesn't work

Если я сравню attributedText с labelAttributedText, я могу видеть, что первый - NSConcreteAttributedString, тогда как последний - NSConcreteMutableAttributedString.Если спросить их, равны ли они, верните true и быстрое сравнение их атрибутов, по-видимому, говорит о том, что они действительно одинаковы, но должно быть что-то немного отличающееся.

Сначала я попытался создать attributedText как изменяемую атрибутивную строку, но это тоже не помогло.Очень удивительно, но огромное спасибо @ XLE_22 за подсказку ... Я сомневаюсь, что когда-нибудь попробовал бы этот конкретный трюк самостоятельно.

1 голос
/ 30 июня 2019

Если я масштабирую размер шрифта вверх и вниз с помощью Accessibility Inspector, размер кнопки и текст метки не масштабируются должным образом.

Чтобы масштабировать метку приписанной строки UIButton с помощью Dynamic Type, , сначала установите метку заголовка как приписанную строку , а затем поместите этот элемент в метод кнопки setAttributedTitle.

Что касается размера кнопки, укажите метод sizeToFit кнопки в traitCollectionDidChange метод экземпляра протокола UITraitEnvironment (использование ограничений может быть другим решением а также) .

Я создал пустой проект в Xcode следующим образом: enter image description here

Скопируйте и вставьте фрагмент кода ниже (Swift 5.0, iOS 12) :

class ViewController: UIViewController {

    @IBOutlet weak var myButton: UIButton!

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        myButton.layer.borderColor = UIColor.black.cgColor
        myButton.layer.borderWidth = 4.0

        myButton.contentEdgeInsets = UIEdgeInsets(top: 10,
                                                  left: 20,
                                                  bottom: 10,
                                                  right: 20)

        let font = UIFont(name: "Helvetica", size: 19)!
        let scaledFont = UIFontMetrics.default.scaledFont(for: font)

        let attributes = [NSAttributedString.Key.font: scaledFont]
        let attributedText = NSAttributedString(string: "Press me",
                                                attributes: attributes)

        myButton.titleLabel?.attributedText = attributedText
        myButton.setAttributedTitle(myButton.titleLabel?.attributedText,
                                    for: .normal)

        myButton.titleLabel?.adjustsFontForContentSizeCategory = true
    }


    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {

        myButton.sizeToFit()
    }
}

... и вы получите результат в дальнейшем: enter image description here Если вам нужно дальнейшее объяснение, я предлагаю взглянуть на этот учебник по динамическому типу , который содержит {фрагменты кода + иллюстрации}, и на это WWDC подробное резюме , которое касается создания приложений с динамическим типом.

...