ios - UIStackView 灵活宽度和等宽项
问题描述
TL;博士
UIStackView
我想用灵活宽度的项目替换自定义(不同于其他项目)宽度项目并将所有UIStackView
项目居中。
更多信息:
我有一个UIStackView
很少的习惯UIView's
:
self.handleButtonStack.axis = .horizontal
self.handleButtonStack.alignment = .center
self.handleButtonStack.distribution = .fillProportionally
self.handleButtonStack.spacing = 10.0
let hbVideo = HandleButton(image: "icon", title: "", type: .video, delegate: self)
hbVideo.widthAnchor.constraint(equalToConstant: 50).isActive = true
let hbInstagram = HandleButton(image: "icon", title: "", type: .instagram, delegate: self)
hbInstagram.widthAnchor.constraint(equalToConstant: 50).isActive = true
let hbWhatsApp = HandleButton(image: "icon", title: "", type: .whatsapp, delegate: self)
hbWhatsApp.widthAnchor.constraint(equalToConstant: 50).isActive = true
let hbHints = HandleButton(image: "icon", title: "title", type: .hint, delegate: self)
hbHints.widthAnchor.constraint(greaterThanOrEqualToConstant: 100).isActive = true
self.handleButtonStack.addArrangedSubview(hbVideo)
self.handleButtonStack.addArrangedSubview(hbInstagram)
self.handleButtonStack.addArrangedSubview(hbWhatsApp)
self.handleButtonStack.addArrangedSubview(hbHints)
在用户执行某些操作后,我想更改UIStackView
并删除hbHints
按钮并使项目居中。
我这样做是这样的:
if let subviews = self.handleButtonStack.arrangedSubviews as? [HandleButton] {
if let hintsButton = subviews.last {
self.handleButtonStack.removeFully(view: hintsButton)
let leadingSpacer = self.createSpacer(width: 50)
let trailingSpacer = self.createSpacer(width: 50)
self.handleButtonStack.insertArrangedSubview(leadingSpacer, at: 0)
self.handleButtonStack.insertArrangedSubview(trailingSpacer, at: subviews.count)
}
}
并添加这样的垫片:
func createSpacer(width: CGFloat) -> UIView {
let space = UIView(frame: .zero)
space.backgroundColor = .red
space.translatesAutoresizingMaskIntoConstraints = false
if width != 0 {
space.widthAnchor.constraint(equalToConstant: width).isActive = true
}
return space
}
我的问题是约束因错误而中断,我不知道为什么。是否可以添加一个灵活的宽度作为我将其放置到位时伸展的垫片?
我已经尝试过的:
- 为项目设置 contentHuggingPriority
- 为项目设置 contentCompressionResistancePriority
- 向间隔项添加约束
- 删除间隔项的宽度约束
没有成功。
这是限制破坏日志:
[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:0x283414050 H:[UIStackView:0x124599e30]-(0)-| (active, names: '|':UIView:0x1245e9f20 )>",
"<NSLayoutConstraint:0x2834142d0 H:|-(0)-[UIStackView:0x124599e30] (active, names: '|':UIView:0x1245e9f20 )>",
"<NSLayoutConstraint:0x283416e90 UILayoutGuide:0x282e94460'UIViewSafeAreaLayoutGuide'.trailing == UIView:0x1245e9f20.trailing + 40 (active)>",
"<NSLayoutConstraint:0x283416620 UIView:0x1245e9f20.leading == UILayoutGuide:0x282e94460'UIViewSafeAreaLayoutGuide'.leading + 40 (active)>",
"<NSLayoutConstraint:0x283428b90 MyApp.HandleButton:0x124589460.width == 50 (active)>",
"<NSLayoutConstraint:0x283428af0 MyApp.HandleButton:0x124589e40.width == 50 (active)>",
"<NSLayoutConstraint:0x283428a50 MyApp.HandleButton:0x124589610.width == 50 (active)>",
"<NSLayoutConstraint:0x2834281e0 'UISV-canvas-connection' UIStackView:0x124599e30.leading == UIView:0x124576f20.leading (active)>",
"<NSLayoutConstraint:0x283428230 'UISV-canvas-connection' H:[UIView:0x1245897c0]-(0)-| (active, names: '|':UIStackView:0x124599e30 )>",
"<NSLayoutConstraint:0x2834282d0 'UISV-fill-proportionally' UIView:0x124576f20.width == 0 (active)>",
"<NSLayoutConstraint:0x28342bc50 'UISV-fill-proportionally' UIView:0x1245897c0.width == 0 (active)>",
"<NSLayoutConstraint:0x283428280 'UISV-spacing' H:[UIView:0x124576f20]-(10)-[MyApp.HandleButton:0x124589460] (active)>",
"<NSLayoutConstraint:0x28342acb0 'UISV-spacing' H:[MyApp.HandleButton:0x124589460]-(10)-[MyApp.HandleButton:0x124589e40] (active)>",
"<NSLayoutConstraint:0x28342af80 'UISV-spacing' H:[MyApp.HandleButton:0x124589e40]-(10)-[MyApp.HandleButton:0x124589610] (active)>",
"<NSLayoutConstraint:0x28342b2a0 'UISV-spacing' H:[MyApp.HandleButton:0x124589610]-(10)-[UIView:0x1245897c0] (active)>",
"<NSLayoutConstraint:0x283429810 'UIView-Encapsulated-Layout-Width' MyApp.AngleColorsView:0x124599fc0.width == 414 (active)>",
"<NSLayoutConstraint:0x283415f90 'UIViewSafeAreaLayoutGuide-left' H:|-(0)-[UILayoutGuide:0x282e94460'UIViewSafeAreaLayoutGuide'](LTR) (active, names: '|':MyApp.AngleColorsView:0x124599fc0 )>",
"<NSLayoutConstraint:0x283416440 'UIViewSafeAreaLayoutGuide-right' H:[UILayoutGuide:0x282e94460'UIViewSafeAreaLayoutGuide']-(0)-|(LTR) (active, names: '|':MyApp.AngleColorsView:0x124599fc0 )>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x283428a50 MyApp.HandleButton:0x124589610.width == 50 (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.
解决方案
在这里你不需要给出任何中心对齐。根据您的要求,您不需要我认为因为您为所有视图和最后一个视图提供约束,您还提供了更大的ThanOrEqual 约束,它会自动拉伸您的视图以填补空白。
因此,请尝试将对齐方式从 .center 更改为 .fill。
然后,在您删除最后一个视图后,您不必添加任何空格来填充缺失的字段。相反,您可以为堆栈视图本身提供约束。
对于堆栈视图的前导和尾随锚点,请给出更大的ThanOrEqualTo 约束而不是相等,并且还向堆栈视图添加中心对齐约束。
因此,当您现在删除视图时,堆栈视图会自动将视图安排在您需要的中心对齐位置。
希望这是您预期的最终结果。
推荐阅读
- laravel - Laravel Websockets 广播但未显示在仪表板中
- docker - 我们如何在 Docker 上提高 TensorFlow API 模型的性能
- javascript - Vue.js 字段未设置
- database - Mongodb 节点在失败后不与 ReplicaSet 同步
- sql - 消息 8114,级别 16,状态 5,第 3 行:将数据类型 nvarchar 转换为浮点数时出错
- sql-server - 从 FreeTDS 驱动程序迁移到 MSODBC17 驱动程序
- vue.js - 尝试通过按下按钮(使用 axios)在 Vue.js 中获得简单的 GET 响应,但不起作用
- javascript - 数据不会与 getjson 一起出现(未定义)
- vue.js - 在 vuetify 中为 v-dialog 激活器使用自定义事件
- javascript - 是否有有效的数组单子变压器?