UITrait与UITraitDefinition
- iOS17 新增了一个协议
UITraitDefinition
,表示特征集合中特征的类型。通过遵守该协议可以实现自定义特征。 - UITrait 则是
UITraitDefinition.Type
的别名。
@available(iOS 17.0, tvOS 17.0, *)
public protocol UITraitDefinition {
associatedtype Value
static var defaultValue: Self.Value { get }
static var identifier: String { get }
static var name: String { get }
static var affectsColorAppearance: Bool { get }
}
@available(iOS 17.0, tvOS 17.0, *)
public typealias UITrait = UITraitDefinition.Type
UITraitCollection
- UITraitCollection 包含的所有特征都遵守了
UITraitDefinition
协议。 - 增加了新的构造方法。
- 增加了修改方法。
// 创建
let customTraits = UITraitCollection { mutableTraits in
mutableTraits.horizontalSizeClass = .compact
mutableTraits.verticalSizeClass = .regular
mutableTraits.userInterfaceStyle = .light
}
// 修改
let modifyTraits = customTraits.modifyingTraits { mutableTraits in
mutableTraits.horizontalSizeClass = .regular
mutableTraits.verticalSizeClass = .compact
mutableTraits.userInterfaceStyle = .dark
}
traitCollectionDidChange()
UITraitEnvironment 协议中的traitCollectionDidChange()
方法被废弃,监听特征改变需要使用UITraitChangeObservable
协议中的相应的特征变化注册方法。
import UIKit
extension UIColor {
static var viewBackgroundColor: UIColor {
.init { (trait: UITraitCollection) -> UIColor in
if trait.userInterfaceStyle == .dark {
return .white
}
return .black
}
}
static var viewControllerBackgroundColor: UIColor {
.init { (trait: UITraitCollection) -> UIColor in
if trait.userInterfaceStyle == .dark {
return .red
}
return .green
}
}
}
class CustomView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
// iOS17之后
registerForTraitChanges([UITraitUserInterfaceStyle.self], action: #selector(configureView))
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: iOS17之前,被废弃
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {}
@objc private func configureView() {
backgroundColor = .viewBackgroundColor
}
}
class ViewController: UIViewController {
lazy var customView: CustomView = {
let customView = CustomView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
customView.center = view.center
customView.backgroundColor = .viewBackgroundColor
return customView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .viewControllerBackgroundColor
view.addSubview(customView)
// iOS17之后
registerForTraitChanges([UITraitUserInterfaceStyle.self]) { (self: Self, previousTraitCollection: UITraitCollection) in
self.view.backgroundColor = .viewControllerBackgroundColor
}
}
// MARK: iOS17之前,被废弃
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {}
}
效果.gif