如何修复偏离中心的堆栈视图?
How to fix an off-centered stack view?
这里我有一个包含三个子视图的水平堆栈视图,但是,它看起来有点偏离中心,如下所示。
我试过:
- 约束堆栈视图的 centerXAnchor 等于父视图的 centerXAnchor
- 将堆栈视图的对齐方式设置为居中
如何正确地将堆栈视图对齐到父视图的中心?
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
view.addSubview(macroStackView)
macroStackView.translatesAutoresizingMaskIntoConstraints = false
constrainView()
}
lazy var carbView: UIView = {
var view = UIView()
var iv = UIImageView(image: Image.planViewBg)
iv.frame = CGRect(x: 0, y: 0, width: 105, height: 118)
iv.contentMode = .scaleAspectFit
var label1 = UILabel()
label1.text = "31%"
label1.textAlignment = .center
var label2 = UILabel()
label2.text = "30g"
label2.textAlignment = .center
var label3 = UILabel()
label3.text = "Carbs"
label3.textAlignment = .center
var labelStack = UIStackView(arrangedSubviews: [label1, label2, label3])
labelStack.axis = .vertical
labelStack.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(iv)
iv.addSubview(labelStack)
NSLayoutConstraint.activate([
labelStack.centerXAnchor.constraint(equalTo: iv.centerXAnchor),
labelStack.centerYAnchor.constraint(equalTo: iv.centerYAnchor),
])
return view
}()
lazy var proteinView: UIView = {
var view = UIView()
var iv = UIImageView(image: Image.planViewBg)
iv.frame = CGRect(x: 0, y: 0, width: 105, height: 118)
iv.contentMode = .scaleAspectFit
var label1 = UILabel()
label1.text = "23%"
label1.textAlignment = .center
var label2 = UILabel()
label2.text = "23g"
label2.textAlignment = .center
var label3 = UILabel()
label3.text = "Protein"
label3.textAlignment = .center
var labelStack = UIStackView(arrangedSubviews: [label1, label2, label3])
labelStack.axis = .vertical
labelStack.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(iv)
iv.addSubview(labelStack)
NSLayoutConstraint.activate([
labelStack.centerXAnchor.constraint(equalTo: iv.centerXAnchor),
labelStack.centerYAnchor.constraint(equalTo: iv.centerYAnchor),
])
return view
}()
lazy var fatView: UIView = {
var view = UIView()
var iv = UIImageView(image: Image.planViewBg)
iv.frame = CGRect(x: 0, y: 0, width: 105, height: 118)
iv.contentMode = .scaleAspectFit
var label1 = UILabel()
label1.text = "46%"
label1.textAlignment = .center
var label2 = UILabel()
label2.text = "20g"
label2.textAlignment = .center
var label3 = UILabel()
label3.text = "Fat"
label3.textAlignment = .center
var labelStack = UIStackView(arrangedSubviews: [label1, label2, label3])
labelStack.axis = .vertical
labelStack.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(iv)
iv.addSubview(labelStack)
NSLayoutConstraint.activate([
labelStack.centerXAnchor.constraint(equalTo: iv.centerXAnchor),
labelStack.centerYAnchor.constraint(equalTo: iv.centerYAnchor),
])
return view
}()
lazy var macroStackView: UIStackView = {
var stack = UIStackView(arrangedSubviews: [carbView, proteinView, fatView])
stack.axis = .horizontal
stack.distribution = .fillEqually
stack.alignment = .center
return stack
}()
func constrainView() {
NSLayoutConstraint.activate([
macroStackView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
macroStackView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 30),
macroStackView.widthAnchor.constraint(equalTo: view.widthAnchor,
multiplier: 0.9)
])
}
}
Tiv
没有将其 translatesAutoresizingMaskIntoConstraints
设置为 false。这使得它的位置固定在 view
s 内的 (0, 0)。然而,view
被堆栈视图适当地拉伸,这就是为什么 (0, 0, 105, 118) 的帧在右边留下很多空白 space。
堆栈视图的对齐描述了事物如何垂直分布到轴。在这种情况下,轴是水平的,因此 alignment
是关于事物如何沿堆栈视图的高度对齐,而不是您可能假设的 width。看起来你想要 .fill
这里 - “框”应该填满堆栈视图的高度。
无论如何,一个简单的解决方案是通过添加约束将 iv
正确定位在 view
中。
你应该先设置
iv.translatesAutoresizingMaskIntoConstraints = false
您将要添加约束。然后添加这些约束:
iv.widthAnchor.constraint(equalToConstant: 105),
iv.heightAnchor.constraint(equalToConstant: 118),
iv.centerXAnchor.constraint(equalTo: view.centerXAnchor),
iv.centerYAnchor.constraint(equalTo: view.centerYAnchor),
我也没有看到任何决定 macroStackView
高度的东西。您应该向 macroStackView
.
添加高度限制
macroStackView.heightAnchor.constraint(equalToConstant: 118)
或者,您可以从 view
un-embed iv
,直接 return iv
。
lazy var carbView: UIView = {
var iv = UIImageView(image: Image.planViewBg)
iv.translatesAutoresizingMaskIntoConstraints = false
iv.contentMode = .scaleAspectFit
var label1 = ...
var label2 = ...
var label3 = ...
var labelStack = UIStackView(arrangedSubviews: [label1, label2, label3])
...
iv.addSubview(labelStack)
...
return iv
}()
在这种情况下,您需要设置堆栈视图的 spacing
以获得您想要的间距。
这里我有一个包含三个子视图的水平堆栈视图,但是,它看起来有点偏离中心,如下所示。
我试过:
- 约束堆栈视图的 centerXAnchor 等于父视图的 centerXAnchor
- 将堆栈视图的对齐方式设置为居中
如何正确地将堆栈视图对齐到父视图的中心?
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
view.addSubview(macroStackView)
macroStackView.translatesAutoresizingMaskIntoConstraints = false
constrainView()
}
lazy var carbView: UIView = {
var view = UIView()
var iv = UIImageView(image: Image.planViewBg)
iv.frame = CGRect(x: 0, y: 0, width: 105, height: 118)
iv.contentMode = .scaleAspectFit
var label1 = UILabel()
label1.text = "31%"
label1.textAlignment = .center
var label2 = UILabel()
label2.text = "30g"
label2.textAlignment = .center
var label3 = UILabel()
label3.text = "Carbs"
label3.textAlignment = .center
var labelStack = UIStackView(arrangedSubviews: [label1, label2, label3])
labelStack.axis = .vertical
labelStack.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(iv)
iv.addSubview(labelStack)
NSLayoutConstraint.activate([
labelStack.centerXAnchor.constraint(equalTo: iv.centerXAnchor),
labelStack.centerYAnchor.constraint(equalTo: iv.centerYAnchor),
])
return view
}()
lazy var proteinView: UIView = {
var view = UIView()
var iv = UIImageView(image: Image.planViewBg)
iv.frame = CGRect(x: 0, y: 0, width: 105, height: 118)
iv.contentMode = .scaleAspectFit
var label1 = UILabel()
label1.text = "23%"
label1.textAlignment = .center
var label2 = UILabel()
label2.text = "23g"
label2.textAlignment = .center
var label3 = UILabel()
label3.text = "Protein"
label3.textAlignment = .center
var labelStack = UIStackView(arrangedSubviews: [label1, label2, label3])
labelStack.axis = .vertical
labelStack.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(iv)
iv.addSubview(labelStack)
NSLayoutConstraint.activate([
labelStack.centerXAnchor.constraint(equalTo: iv.centerXAnchor),
labelStack.centerYAnchor.constraint(equalTo: iv.centerYAnchor),
])
return view
}()
lazy var fatView: UIView = {
var view = UIView()
var iv = UIImageView(image: Image.planViewBg)
iv.frame = CGRect(x: 0, y: 0, width: 105, height: 118)
iv.contentMode = .scaleAspectFit
var label1 = UILabel()
label1.text = "46%"
label1.textAlignment = .center
var label2 = UILabel()
label2.text = "20g"
label2.textAlignment = .center
var label3 = UILabel()
label3.text = "Fat"
label3.textAlignment = .center
var labelStack = UIStackView(arrangedSubviews: [label1, label2, label3])
labelStack.axis = .vertical
labelStack.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(iv)
iv.addSubview(labelStack)
NSLayoutConstraint.activate([
labelStack.centerXAnchor.constraint(equalTo: iv.centerXAnchor),
labelStack.centerYAnchor.constraint(equalTo: iv.centerYAnchor),
])
return view
}()
lazy var macroStackView: UIStackView = {
var stack = UIStackView(arrangedSubviews: [carbView, proteinView, fatView])
stack.axis = .horizontal
stack.distribution = .fillEqually
stack.alignment = .center
return stack
}()
func constrainView() {
NSLayoutConstraint.activate([
macroStackView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
macroStackView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 30),
macroStackView.widthAnchor.constraint(equalTo: view.widthAnchor,
multiplier: 0.9)
])
}
}
Tiv
没有将其 translatesAutoresizingMaskIntoConstraints
设置为 false。这使得它的位置固定在 view
s 内的 (0, 0)。然而,view
被堆栈视图适当地拉伸,这就是为什么 (0, 0, 105, 118) 的帧在右边留下很多空白 space。
堆栈视图的对齐描述了事物如何垂直分布到轴。在这种情况下,轴是水平的,因此 alignment
是关于事物如何沿堆栈视图的高度对齐,而不是您可能假设的 width。看起来你想要 .fill
这里 - “框”应该填满堆栈视图的高度。
无论如何,一个简单的解决方案是通过添加约束将 iv
正确定位在 view
中。
你应该先设置
iv.translatesAutoresizingMaskIntoConstraints = false
您将要添加约束。然后添加这些约束:
iv.widthAnchor.constraint(equalToConstant: 105),
iv.heightAnchor.constraint(equalToConstant: 118),
iv.centerXAnchor.constraint(equalTo: view.centerXAnchor),
iv.centerYAnchor.constraint(equalTo: view.centerYAnchor),
我也没有看到任何决定 macroStackView
高度的东西。您应该向 macroStackView
.
macroStackView.heightAnchor.constraint(equalToConstant: 118)
或者,您可以从 view
un-embed iv
,直接 return iv
。
lazy var carbView: UIView = {
var iv = UIImageView(image: Image.planViewBg)
iv.translatesAutoresizingMaskIntoConstraints = false
iv.contentMode = .scaleAspectFit
var label1 = ...
var label2 = ...
var label3 = ...
var labelStack = UIStackView(arrangedSubviews: [label1, label2, label3])
...
iv.addSubview(labelStack)
...
return iv
}()
在这种情况下,您需要设置堆栈视图的 spacing
以获得您想要的间距。