当设备处于纵向模式时,我尝试将屏幕上的UIView布局在16:9的宽高比位于顶部,并且当设备处于横向模式时,我将尝试全屏显示(如视频播放器屏幕)。我决定使用大小类。这是我如何实现它,但我对实现不满意,并且存在一些错误。这是我的代码:
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
if traitCollection.verticalSizeClass == .compact {
localPlayerView.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
}
}
override func viewWillLayoutSubviews() {
if traitCollection.verticalSizeClass == .compact {
localPlayerView.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
}
if traitCollection.horizontalSizeClass == .compact {
localPlayerView.removeFromSuperview()
view.addSubview(localPlayerView)
let height = view.frame.width * 9 / 16
localPlayerView.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: height)
collectionView.anchor(top: localPlayerView.bottomAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
localPlayerView.layoutIfNeeded()
}
}
我不得不从superview中删除localPlayerView并将其添加回来以获得所需的结果,因为当我切换回肖像时,它仍然限制为完整的超视图宽度。 如何改进此代码以获得相同的结果?
答案 0 :(得分:1)
每当您给出定义其大小和位置的localPlayerView
个新约束时,您必须删除/停用旧约束。在你的代码中,似乎你总是只是添加新的约束,这将导致不可满足的约束,然后布局出现问题 - 更重要的是,如果你从superview中删除播放器然后再添加它,那将删除那些约束 - 只有证实了我的假设。你必须小心,始终有非冲突的约束。
如何做到这一点只是一个广泛的指导方针。在viewController
中定义两个属性:
var portraitConstraints: [NSLayoutConstraint] = []
var landscapeConstraints: [NSLayoutConstraint] = []
然后,一旦加载了视图(例如,在viewDidLoad
中),就相应地填充它们:
portraitConstraints = [
// here create all the constraints that are needed to properly define position and size of the player when in portrait
]
landscapeConstraints = [
// all the constraints for landscape
]
NSLayoutConstraint.activate(portraitConstraints) // activate these as default
然后在traitCollectionDidChange
检测你是在横向还是纵向(我省略了这个代码,你可以找到关于那个的SO问题),并且只是激活适当的约束(并停用旧约束):
let inLandscape = // code to detect current orientation
if inLandscape {
NSLayoutConstraint.deactivate(portraitConstraints)
NSLayoutConstraint.activate(landscapeConstraints)
} else {
NSLayoutConstraint.deactivate(landscapeConstraints)
NSLayoutConstraint.activate(portraitConstraints)
}