UIstackview 如何确保两个子视图具有不同的比例大小
UIstackview how to make sure two child view have different propotional size
我有一个有两个视图的 UIStackview。当轴为垂直时,我希望 view1 占父级的 70%,而当轴为水平时,我希望 view2 占父级的 70%。
我尝试通过玩横向拥抱和对抗两种观点来实现这一点。但是没有任何效果。
仅供参考:
视图 1 内部有一个图像,水平和垂直居中于视图,而宽度和高度均为 50
视图 2 实际上是一个标签。这不是视图。
更新:
如果我激活和停用相等的 width/height 约束,它就会起作用。但是我遇到了以下错误
2021-02-04 20:07:15.262465+0530 test[10094:159481] [LayoutConstraints] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(
"<NSLayoutConstraint:0x600003ccedf0 UILabel:0x7fc42ae0b1d0.width == 0.8*UIStackView:0x7fc42ae0d290.width (active)>",
"<NSLayoutConstraint:0x600003cce8a0 UILayoutGuide:0x6000026cc540'UIViewSafeAreaLayoutGuide'.trailing == UIStackView:0x7fc42ac0cca0.trailing (active)>",
"<NSLayoutConstraint:0x600003cce800 UIStackView:0x7fc42ac0cca0.leading == UILayoutGuide:0x6000026cc540'UIViewSafeAreaLayoutGuide'.leading (active)>",
"<NSLayoutConstraint:0x600003cc91d0 'UISV-alignment' UIView:0x7fc42ae05790.leading == UILabel:0x7fc42ae0b1d0.leading (active)>",
"<NSLayoutConstraint:0x600003cc9270 'UISV-alignment' UIView:0x7fc42ae05790.trailing == UILabel:0x7fc42ae0b1d0.trailing (active)>",
"<NSLayoutConstraint:0x600003cc9130 'UISV-canvas-connection' UIStackView:0x7fc42ae0d290.leading == UIView:0x7fc42ae05790.leading (active)>",
"<NSLayoutConstraint:0x600003cc9180 'UISV-canvas-connection' H:[UIView:0x7fc42ae05790]-(0)-| (active, names: '|':UIStackView:0x7fc42ae0d290 )>",
"<NSLayoutConstraint:0x600003cc92c0 'UISV-canvas-connection' UIStackView:0x7fc42ac0cca0.leading == UIStackView:0x7fc42ac0a850.leading (active)>",
"<NSLayoutConstraint:0x600003cc9310 'UISV-canvas-connection' H:[UIStackView:0x7fc42ae0d290]-(0)-| (active, names: '|':UIStackView:0x7fc42ac0cca0 )>",
"<NSLayoutConstraint:0x600003cc93b0 'UISV-fill-equally' UIStackView:0x7fc42ae0d290.width == UIStackView:0x7fc42ac0a850.width (active)>",
"<NSLayoutConstraint:0x600003cc9360 'UISV-spacing' H:[UIStackView:0x7fc42ac0a850]-(0)-[UIStackView:0x7fc42ae0d290] (active)>",
"<NSLayoutConstraint:0x600003cc96d0 'UIView-Encapsulated-Layout-Width' UIView:0x7fc42ac0d030.width == 414 (active)>",
"<NSLayoutConstraint:0x600003cce990 'UIViewSafeAreaLayoutGuide-left' H:|-(0)-[UILayoutGuide:0x6000026cc540'UIViewSafeAreaLayoutGuide'](LTR) (active, names: '|':UIView:0x7fc42ac0d030 )>",
"<NSLayoutConstraint:0x600003cce8f0 'UIViewSafeAreaLayoutGuide-right' H:[UILayoutGuide:0x6000026cc540'UIViewSafeAreaLayoutGuide']-(0)-|(LTR) (active, names: '|':UIView:0x7fc42ac0d030 )>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x600003cc9270 'UISV-alignment' UIView:0x7fc42ae05790.trailing == UILabel:0x7fc42ae0b1d0.trailing (active)>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
没有一组约束可以满足您的需求,因此您需要为两个状态设置约束并设置这些约束 isActive
状态 true
或 false
取决于关于你的堆栈是处于水平还是垂直状态。
通过故事板
你需要:
- 垂直情况下的一个比例高度约束。请注意
Installed
即 isActive
属性 框是如何为所选约束选中的。另一个约束变暗,因为 Installed
/isActive
设置为 false。
- 水平情况下的一个比例宽度约束。
当你想翻转时,在这些约束上切换 isActive
标志。
class ViewController: UIViewController {
@IBOutlet weak var stack: UIStackView!
@IBOutlet weak var viewOne: UIView!
@IBOutlet weak var viewTwo: UIView!
@IBOutlet weak var vModeHeightConstraint: NSLayoutConstraint!
@IBOutlet weak var hModeWidthContraint: NSLayoutConstraint!
var isVertical = true {
didSet {
UIView.animate(withDuration: 1.0) {
self.toggle()
}
}
}
func toggle() {
vModeHeightConstraint.isActive = false
hModeWidthContraint.isActive = false
stack.axis = isVertical ? .vertical:.horizontal
stack.layoutIfNeeded()
vModeHeightConstraint.isActive = isVertical
hModeWidthContraint.isActive = !isVertical
stack.layoutIfNeeded()
}
@IBAction func toggleModeAction(_ sender: Any) {
isVertical.toggle()
}
}
您可以通过编程方式设置约束。如何做到这一点很容易在 SO 上找到。
您将在更改过程中看到一堆自动布局错误。这些错误可以在“UIKit 不完美”下提交。
通常这种更改是由 func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?)
中的设备轮换触发的,但您没有说明希望更改发生的时间。
我有一个有两个视图的 UIStackview。当轴为垂直时,我希望 view1 占父级的 70%,而当轴为水平时,我希望 view2 占父级的 70%。
我尝试通过玩横向拥抱和对抗两种观点来实现这一点。但是没有任何效果。
仅供参考: 视图 1 内部有一个图像,水平和垂直居中于视图,而宽度和高度均为 50 视图 2 实际上是一个标签。这不是视图。
更新:
如果我激活和停用相等的 width/height 约束,它就会起作用。但是我遇到了以下错误
2021-02-04 20:07:15.262465+0530 test[10094:159481] [LayoutConstraints] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(
"<NSLayoutConstraint:0x600003ccedf0 UILabel:0x7fc42ae0b1d0.width == 0.8*UIStackView:0x7fc42ae0d290.width (active)>",
"<NSLayoutConstraint:0x600003cce8a0 UILayoutGuide:0x6000026cc540'UIViewSafeAreaLayoutGuide'.trailing == UIStackView:0x7fc42ac0cca0.trailing (active)>",
"<NSLayoutConstraint:0x600003cce800 UIStackView:0x7fc42ac0cca0.leading == UILayoutGuide:0x6000026cc540'UIViewSafeAreaLayoutGuide'.leading (active)>",
"<NSLayoutConstraint:0x600003cc91d0 'UISV-alignment' UIView:0x7fc42ae05790.leading == UILabel:0x7fc42ae0b1d0.leading (active)>",
"<NSLayoutConstraint:0x600003cc9270 'UISV-alignment' UIView:0x7fc42ae05790.trailing == UILabel:0x7fc42ae0b1d0.trailing (active)>",
"<NSLayoutConstraint:0x600003cc9130 'UISV-canvas-connection' UIStackView:0x7fc42ae0d290.leading == UIView:0x7fc42ae05790.leading (active)>",
"<NSLayoutConstraint:0x600003cc9180 'UISV-canvas-connection' H:[UIView:0x7fc42ae05790]-(0)-| (active, names: '|':UIStackView:0x7fc42ae0d290 )>",
"<NSLayoutConstraint:0x600003cc92c0 'UISV-canvas-connection' UIStackView:0x7fc42ac0cca0.leading == UIStackView:0x7fc42ac0a850.leading (active)>",
"<NSLayoutConstraint:0x600003cc9310 'UISV-canvas-connection' H:[UIStackView:0x7fc42ae0d290]-(0)-| (active, names: '|':UIStackView:0x7fc42ac0cca0 )>",
"<NSLayoutConstraint:0x600003cc93b0 'UISV-fill-equally' UIStackView:0x7fc42ae0d290.width == UIStackView:0x7fc42ac0a850.width (active)>",
"<NSLayoutConstraint:0x600003cc9360 'UISV-spacing' H:[UIStackView:0x7fc42ac0a850]-(0)-[UIStackView:0x7fc42ae0d290] (active)>",
"<NSLayoutConstraint:0x600003cc96d0 'UIView-Encapsulated-Layout-Width' UIView:0x7fc42ac0d030.width == 414 (active)>",
"<NSLayoutConstraint:0x600003cce990 'UIViewSafeAreaLayoutGuide-left' H:|-(0)-[UILayoutGuide:0x6000026cc540'UIViewSafeAreaLayoutGuide'](LTR) (active, names: '|':UIView:0x7fc42ac0d030 )>",
"<NSLayoutConstraint:0x600003cce8f0 'UIViewSafeAreaLayoutGuide-right' H:[UILayoutGuide:0x6000026cc540'UIViewSafeAreaLayoutGuide']-(0)-|(LTR) (active, names: '|':UIView:0x7fc42ac0d030 )>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x600003cc9270 'UISV-alignment' UIView:0x7fc42ae05790.trailing == UILabel:0x7fc42ae0b1d0.trailing (active)>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
没有一组约束可以满足您的需求,因此您需要为两个状态设置约束并设置这些约束 isActive
状态 true
或 false
取决于关于你的堆栈是处于水平还是垂直状态。
通过故事板
你需要:
- 垂直情况下的一个比例高度约束。请注意
Installed
即isActive
属性 框是如何为所选约束选中的。另一个约束变暗,因为Installed
/isActive
设置为 false。
- 水平情况下的一个比例宽度约束。
当你想翻转时,在这些约束上切换 isActive
标志。
class ViewController: UIViewController {
@IBOutlet weak var stack: UIStackView!
@IBOutlet weak var viewOne: UIView!
@IBOutlet weak var viewTwo: UIView!
@IBOutlet weak var vModeHeightConstraint: NSLayoutConstraint!
@IBOutlet weak var hModeWidthContraint: NSLayoutConstraint!
var isVertical = true {
didSet {
UIView.animate(withDuration: 1.0) {
self.toggle()
}
}
}
func toggle() {
vModeHeightConstraint.isActive = false
hModeWidthContraint.isActive = false
stack.axis = isVertical ? .vertical:.horizontal
stack.layoutIfNeeded()
vModeHeightConstraint.isActive = isVertical
hModeWidthContraint.isActive = !isVertical
stack.layoutIfNeeded()
}
@IBAction func toggleModeAction(_ sender: Any) {
isVertical.toggle()
}
}
您可以通过编程方式设置约束。如何做到这一点很容易在 SO 上找到。
您将在更改过程中看到一堆自动布局错误。这些错误可以在“UIKit 不完美”下提交。
通常这种更改是由 func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?)
中的设备轮换触发的,但您没有说明希望更改发生的时间。