想象一下包含四个项目的堆栈视图,填充一些内容。 (说,填写屏幕)。
请注意,三个缺口,ABC。
说UISV能够绘制所有内容,比如剩下300个。这三个差距各为100个。
在这个例子中,剩下9个,所以A B和C各为3个。
然而
通常,您希望间隙本身享受比例关系。
因此 - 您的设计师可能会说类似
如果屏幕太高,请展开A,B和C处的空格。总是扩大B,比A和B的间隙快4倍。“
所以,如果留下“12”,那将是2,8,2。而当剩下18时,那将是3,12,3。
这个概念在堆栈视图中是否可用?否则,你会怎么做?
(注意,最近添加到堆栈视图中,您确实可以单独指定间隙。因此,可以“手动”执行此操作,但这将是一个真正的混乱,您将与解算器一起工作很多。)
答案 0 :(得分:4)
您可以通过以下解决方法来实现这一目标。而不是间距,为每个空间添加一个新的UIView()
,它将是一个可伸缩的空间。然后只需在这些"空格"的高度之间添加约束。这会根据你想要的乘数将它们的高度限制在一起,例如:
space1.heightAnchor.constraint(equalTo: space2.heightAnchor, multiplier: 2).isActive = true
为了使其工作,我认为你必须添加一个约束,试图在有空位的情况下拉伸这些空间:
let stretchingConstraint = space1.heightAnchor.constraint(equalToConstant: 1000)
// lowest priority to make sure it wont override any of the rest of constraints and compression resistances
stretchingConstraint.priority = UILayoutPriority(rawValue: 1)
stretchingConstraint.isActive = true
"正常"内容视图必须具有内在大小或显式约束,以便将其高度设置为正常工作。
以下是一个例子:
class MyViewController: UIViewController {
fileprivate let stack = UIStackView()
fileprivate let views = [UIView(), UIView(), UIView(), UIView()]
fileprivate let spaces = [UIView(), UIView(), UIView()]
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .white
self.view.addSubview(stack)
// let stack fill the whole view
stack.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
stack.topAnchor.constraint(equalTo: self.view.topAnchor),
stack.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
stack.leftAnchor.constraint(equalTo: self.view.leftAnchor),
stack.rightAnchor.constraint(equalTo: self.view.rightAnchor),
])
stack.alignment = .fill
// distribution must be .fill
stack.distribution = .fill
stack.spacing = 0
stack.axis = .vertical
for (index, view) in views.enumerated() {
stack.addArrangedSubview(view)
view.translatesAutoresizingMaskIntoConstraints = false
// give it explicit height (or use intrinsic height)
view.heightAnchor.constraint(equalToConstant: 50).isActive = true
view.backgroundColor = .orange
// intertwin it with spaces
if index < spaces.count {
stack.addArrangedSubview(spaces[index])
spaces[index].translatesAutoresizingMaskIntoConstraints = false
}
}
// constraints for 1 4 1 proportions
NSLayoutConstraint.activate([
spaces[1].heightAnchor.constraint(equalTo: spaces[0].heightAnchor, multiplier: 4),
spaces[2].heightAnchor.constraint(equalTo: spaces[0].heightAnchor, multiplier: 1),
])
let stretchConstraint = spaces[0].heightAnchor.constraint(equalToConstant: 1000)
stretchConstraint.priority = UILayoutPriority(rawValue: 1)
stretchConstraint.isActive = true
}
}
答案 1 :(得分:2)
值得注意的是,@MilanNosáľ
的解决方案非常有效。
您无需设置任何优先级/等等 - 它在iOS求解器中“自然地”完美运行!
将四个内容区域简单地设置为50个固定高度。 (使用任何内在内容项。)
根本不要设置“gap1”的高度。
将gap2和gap3设置为gap1的相等高度。
只需 - 为gap2和gap3设置所需的比率!
与间隙1对比。
因此,gap2为gap1的高度为0.512,gap3为gap1的高度为0.398等。
它确实解决了所有情况。
奇!!!!!!!!!!
所以:三个例子中的 (具有三种不同屏幕高度的手机)。 实际上差距的相对高度总是一样的。你的设计部门会高兴! :)
答案 2 :(得分:1)
已创建:a gist with a storyboard example
此处的关键是您排列的视图与参考视图之间的Equal Heights
:
然后将“乘数”更改为所需的大小:
在这个例子中,主视图大小为0.2(深灰色),对中为0.05(黑色),对之间为0.1(浅灰色)
然后只需更改包含视图的大小将导致视图按比例重新调整大小:
这完全在故事板中,但你可以在代码中做同样的事情。
请注意,我只使用StackView
中的比例来避免总大小不正确(并确保它们加起来为1.0),但也应该有一些设定的高度如果正确完成,则在StackView
内。