Cra*_*rds 4 accessibility uibutton uikit ios dynamic-type-feature
有谁有动态类型的工作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)
Run Code Online (Sandbox Code Playgroud)
如果我使用辅助功能检查器上下缩放字体大小,按钮的大小和标签文本不能正确缩放。
但是,如果我只是调用button.setTitle()传递一个普通字符串,动态类型缩放工作正常。
直接在 a 上对属性文本使用相同的模式UILabel效果很好......似乎只是当我将属性文本用于 aUIButton的标题时。
任何想法或建议都会很棒。谢谢
编辑:再戳一下后,看起来正在发生的事情是文本正在尝试缩放,但按钮的宽度/高度并没有随之增长。如果我将动态类型拨号到最大文本大小,然后创建屏幕并继续缩小字体大小,则它可以正常工作,因为按钮的宽度/高度约束设置为初始大值。但是如果我从一个小的动态类型设置开始并变大,按钮就不能适应文本大小的变化
如果我使用辅助功能检查器上下缩放字体大小,按钮的大小和标签文本不能正确缩放。
要缩放的的归属字符串标签UIButton与Dynamic Type,首先设置标题标签作为归因串,然后把这个元件在setAttributedTitle按钮方法。
关于按钮大小,在协议sizeToFit的traitCollectionDidChange实例方法中指定按钮的方法(使用约束也可以是另一种解决方案)。UITraitEnvironment
复制粘贴下面的代码片段(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()
}
}
Run Code Online (Sandbox Code Playgroud)
......你会得到以下结果:
如果您需要进一步解释,我建议您查看包含{代码片段 + 插图} 的这种动态类型教程,以及有关使用动态类型构建应用程序的WWDC 详细摘要。
?? 编辑 2021/02/15 ??
感谢@Anthony 的评论,我将这个旧的解决方案改进为新的上下文,如下所示:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
myButton.layer.borderColor = UIColor.black.cgColor
myButton.layer.borderWidth = 4.0
let font = UIFont(name: "Helvetica", size: 20)!
let scaledFont = UIFontMetrics.default.scaledFont(for: font)
let attributes = [NSAttributedString.Key.font: scaledFont]
let attributedText = NSAttributedString(string: "Press Me Huge Button",
attributes: attributes)
myButton.titleLabel?.attributedText = attributedText
myButton.titleLabel?.numberOfLines = 0
myButton.titleLabel?.textAlignment = .center
myButton.setAttributedTitle(attributedText,
for: .normal)
myButton.titleLabel?.adjustsFontForContentSizeCategory = true
createConstraints()
}
Run Code Online (Sandbox Code Playgroud)
...并在按钮及其内容之间添加约束:
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
DispatchQueue.main.async() {
self.myButton.setNeedsUpdateConstraints() // For updating constraints.
}
}
private func createConstraints() {
myButton.translatesAutoresizingMaskIntoConstraints = false
myButton.titleLabel?.translatesAutoresizingMaskIntoConstraints = false
let spacing = 10.0
myButton.titleLabel?.trailingAnchor.constraint(equalTo: myButton.trailingAnchor,
constant: -CGFloat(spacing)).isActive = true
myButton.titleLabel?.leadingAnchor.constraint(equalTo: myButton.leadingAnchor,
constant: CGFloat(spacing)).isActive = true
myButton.titleLabel?.topAnchor.constraint(equalTo: myButton.topAnchor,
constant: CGFloat(spacing)).isActive = true
myButton.titleLabel?.bottomAnchor.constraint(equalTo: myButton.bottomAnchor,
constant: -CGFloat(spacing)).isActive = true
}
Run Code Online (Sandbox Code Playgroud)
通过对内部按钮的一些新约束Interface Builder,我终于使用Xcode 环境覆盖窗格获得了这些屏幕截图:
