我正在练习自动布局编程。我想把一个UIView在控制器的宽度将是4/5在纵向模式,但当它将进入横向模式,我需要的高度是4/5的超级视图的高度,而不是宽度的控制器中心。
就像-
因此,我根据方向停用然后激活所需的约束,但当我更改旋转时,它会给我冲突,就好像它没有停用我指定要停用的约束一样。这是我的完整代码。因为它是独立于故事板的,你可以把视图控制器类分配给一个视图控制器,然后看到效果。
class MyViewController: UIViewController {
var widthSizeClass = UIUserInterfaceSizeClass.unspecified
var centeredView : UIView = {
let view = UIView()
view.backgroundColor = UIColor.systemGreen
return view
}()
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.view.addSubview(centeredView)
centeredView.translatesAutoresizingMaskIntoConstraints = false
}
override func viewWillLayoutSubviews(){
super.viewWillLayoutSubviews()
widthSizeClass = self.traitCollection.horizontalSizeClass
addConstrainsToCenterView()
}
func addConstrainsToCenterView() {
centeredView.centerXAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.centerXAnchor).isActive = true
centeredView.centerYAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.centerYAnchor).isActive = true
let compactWidthAnchor = centeredView.widthAnchor.constraint(equalTo: self.view.widthAnchor, multiplier: 4/5)
let compactHeightAnchor = centeredView.heightAnchor.constraint(equalTo: centeredView.widthAnchor)
let regularHeightAnchor = centeredView.heightAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.heightAnchor, multiplier: 4/5)
let regularWidthAnchor = centeredView.widthAnchor.constraint(equalTo: centeredView.heightAnchor)
if widthSizeClass == .compact{
NSLayoutConstraint.deactivate([regularWidthAnchor, regularHeightAnchor])
NSLayoutConstraint.activate([compactWidthAnchor, compactHeightAnchor])
}
else{
NSLayoutConstraint.deactivate([compactWidthAnchor, compactHeightAnchor])
NSLayoutConstraint.activate([regularWidthAnchor, regularHeightAnchor])
}
}
}
谁能帮我找出我的缺点。
3条答案
按热度按时间jobtbby31#
有几个问题...
1 -许多iPhone型号 * 只有 * 有
wC hR
(纵向)和wC hC
(横向)尺寸类别。因此,如果您在这些设备上检查.horizontalSizeClass
,它将始终是.compact
。您可能需要检查.verticalSizeClass
2 -你有你的代码的方式,你正在创建***新***约束每次你调用
addConstrainsToCenterView()
。您没有 * 激活/停用 * 现有约束。看看这个:
通过这种方法,我们为我们想要激活/停用的约束创建了两个变量:
然后,在
viewDidLoad()
中,我们将centeredView
添加到视图中,设置其“不变”约束- centerX、centerY、aspect-ratio -并创建两个激活/停用约束。当我们改变size类时,我们只需要处理两个
var
约束。5jdjgkvh2#
可能不是答案,但为了沿着我的评论,下面是我成功使用的代码:
注意,
p
和l
是数组,分别代表纵向和横向。这里没什么特别的,只是说明了在加载视图时可以设置约束。
再一次,这里没有什么-看起来你正在做这件事。下面是我在你的视图控制器覆盖中看到的区别:
其中一些可能是矫枉过正为您使用。但是,我实际上不是检查类的大小,而是检查边界,沿着检测初始方向。给我用?我实际上设置了一个侧边栏或底部栏。适用于所有iPhone和iPad。
同样,我没有看到任何主要的-激活/停用一个名为(?)约束的数组而不是创建数组,这样做的顺序,你正在使用的覆盖...对我来说,最突出的一点就是看班级的大小。(可能会发现初始大小类是什么?))
我目前正在记录
UISplitViewController
如何决定显示Secondary或Compact VC。事实证明,它在至少 * 五个 * 组中的表现不同- iPad(始终是次要的),iPad分屏(除了iPad Pro 12.9外,所有iPad都是紧凑的),iPhone纵向(始终是紧凑的),最后,iPhone横向(大多数是紧凑的,但次要的是(iPhone 8 Plus,iPhone 11,iPhone 11 Pro Max和iPhone 12 Pro Max)。注意:它是iPhone 11 Pro,iPhone 12和iPhone 12 Pro的紧凑型!我对此感到惊讶。(接下来我将直接测试大小类。)
我的观点?也许你需要去屏幕边界,以确定你想要什么布局,而不是大小类。这比班级规模更受你的控制。不管怎样,祝你好运!
ac1kyiln3#
很简单每次布局发生,每次你说例如:
您没有取消激活接口中现有的活动约束。您正在创建一个全新的约束,然后将其禁用(这是毫无意义的,因为它从未处于活动状态),然后将其丢弃。
您只需要创建这些约束一次,并保留对它们的引用。