Ces*_*are 4 ios autolayout swift
我希望标签的字体大小与屏幕大小成正比。我已经对这个UILabel类进行了子类化来完成这个:
@IBDesignable class MyCustomLabel: UILabel {
override func layoutSubviews() {
super.layoutSubviews()
self.font = UIFont(name: "myFontName", size: (self.font?.pointSize)!)
self.adjustsFontSizeToFitWidth = true
}
}
Run Code Online (Sandbox Code Playgroud)
标签(与附加到它们的超级视图约束成比例的宽度)在应用程序首次启动时正确调整大小,但是当它进入后台状态时layoutSubviews会被重复调用。该应用程序不再响应用户的输入并不断为字体分配字体大小。
为什么会这样?
在您的测试项目中,如果我在 iPhone 上运行,我不会看到layoutSubviews()在后台被调用。它只发生在 iPad 上。
那是因为您的应用程序支持多任务处理:
layoutSubviews()被调用。这是完全正常的。真正的问题是您正在创建一个“布局循环”。您的代码layoutSubviews()导致您自己的视图布局无效,因此系统需要再次运行布局过程。然后布局运行,你再做一次,它会再次发生。
具体来说,原因是:
self.font = UIFont(name: fontName, size: fontSize)
Run Code Online (Sandbox Code Playgroud)
更改标签的字体会导致其内在尺寸发生变化,这意味着其超视图可能需要更新其布局,因此需要再次运行布局过程。这样做是个坏主意,layoutSubviews()因为它会导致布局循环。你真的应该只改变你的子视图的属性,而不是你的视图本身。
为什么你认为你需要这样做layoutSubviews()?在布局过程之外,可能有更好的地方放置它。在您的示例中,我根本看不到这段代码如何做任何有用的事情。
设置adjustsFrameSizeToWidth一次,然后不做任何事情会更有意义layoutSubviews():
override init(frame: CGRect) {
super.init(frame: frame)
self.adjustsFontSizeToFitWidth = true
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.adjustsFontSizeToFitWidth = true
}
Run Code Online (Sandbox Code Playgroud)
如果您尝试根据大小类更改字体大小,则可以通过覆盖在代码中执行此操作traitCollectionDidChange():
override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
var fontSize: CGFloat
if (self.traitCollection.horizontalSizeClass == .Regular) {
fontSize = 70
}
else {
fontSize = 30
}
self.font = UIFont(name: fontName, size:fontSize)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1183 次 |
| 最近记录: |