如何以编程方式调整 UIStackView 的成员视图的大小?
How can I programmatically adjust the size of member views of a UIStackView?
场景:
我创建了一个包含多行元素的垂直 UIStackView。
一行包含重复的正方形 UIViews (Address1 & Address2),我想调整其大小。
注意:我没有使用 Interface Builder。仅通过代码。
问题:
这两个正方形似乎是固定的矩形,我无法 'square' 调整到合适的大小。
补救措施?
代码如下:
class MainView: UIView {
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// ------------------------------------------------
@objc func onLeftAddressTap() {
print("Left Address Selected")
leftLabel.isHidden = false
rightLabel.isHidden = !leftLabel.isHidden
leftContainerView.layer.borderColor = UIColor.green.cgColor
rightContainerView.layer.borderColor = UIColor.lightGray.cgColor
}
@objc func onRightAddressTap() {
print("Right Address Selected")
leftLabel.isHidden = true
rightLabel.isHidden = !leftLabel.isHidden
rightContainerView.layer.borderColor = UIColor.green.cgColor
leftContainerView.layer.borderColor = UIColor.lightGray.cgColor
}
// ------------------------------------------------
let leftLabel = UILabel()
let rightLabel = UILabel()
let leftContainerView: UIView = {
let view = UIView(frame: CGRect())
view.layer.borderWidth = 1.0
view.layer.borderColor = UIColor.green.cgColor
return view
}()
let rightContainerView: UIView = {
let view = UIView(frame: CGRect())
view.layer.borderWidth = 1.0
view.layer.borderColor = UIColor.lightGray.cgColor
return view
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = .white
setupViews()
}
// ------------------------------------------------
fileprivate func setupAddressStack() -> UIStackView {
setupLeftAddress()
setupRightAddress()
// ------------------------------------------------
// Address StackView:
let addressStackView = UIStackView(arrangedSubviews: [leftContainerView, rightContainerView])
addressStackView.axis = .horizontal
addressStackView.spacing = 10
addressStackView.distribution = .fillEqually
addressStackView.alignment = .fill
return addressStackView
}
// ------------------------------------------------
fileprivate func setupViews() {
// Image Logol
let ratImageview = UIImageView(image: UIImage(named: "Rat"))
ratImageview.frame = CGRect(x: 0, y: 0, width: 68, height: 68)
// TitleLabel
let titleLabel = UILabel(frame: CGRect())
let titleString = "Where should we send your card? We'll cancel it and send you a new one."
titleLabel.text = titleString
titleLabel.textAlignment = .center
titleLabel.font = .systemFont(ofSize: 12)
titleLabel.lineBreakMode = .byWordWrapping
titleLabel.numberOfLines = 0
// Status Label:
let statusLabel = UILabel(frame: CGRect())
let statusString = "Your existing card ending in 0492 will be cancelled and yournew card shoud arrive withi 6 business days via USPS."
statusLabel.text = statusString
statusLabel.textAlignment = .center
statusLabel.font = .systemFont(ofSize: 12)
statusLabel.lineBreakMode = .byWordWrapping
statusLabel.numberOfLines = 0
// ------------------------------------------------
// Container SackView:
let ContainerStackView = UIStackView(arrangedSubviews: [titleLabel, setupAddressStack(), statusLabel])
ContainerStackView.axis = .vertical
ContainerStackView.distribution = .fillEqually
ContainerStackView.spacing = 20
// Logo:
addSubview(ratImageview)
ratImageview.translatesAutoresizingMaskIntoConstraints = false
ratImageview.centerXAnchor.constraint(equalTo: centerXAnchor, constant: 0).isActive = true
ratImageview.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor, constant: 10).isActive = true
// StackView:
addSubview(ContainerStackView)
ContainerStackView.translatesAutoresizingMaskIntoConstraints = false
ContainerStackView.leftAnchor.constraint(equalTo: leftAnchor, constant: 10).isActive = true
ContainerStackView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor, constant: 75).isActive = true
ContainerStackView.rightAnchor.constraint(equalTo: rightAnchor, constant: -10).isActive = true
ContainerStackView.bottomAnchor.constraint(equalTo: centerYAnchor, constant: 0).isActive = true
}
}
// ==============================================================================================
private extension MainView {
func setupLeftAddress() {
// LeftLabel:
leftLabel.numberOfLines = 0
leftLabel.text = "Mother had a feeling, I might be too appealing."
leftLabel.font = UIFont.systemFont(ofSize: 9)
leftLabel.adjustsFontSizeToFitWidth = true
leftLabel.isHidden = false
leftContainerView.addSubview(leftLabel)
leftLabel.translatesAutoresizingMaskIntoConstraints = false
leftLabel.leftAnchor.constraint(equalTo: leftContainerView.leftAnchor, constant: 10).isActive = true
leftLabel.rightAnchor.constraint(equalTo: leftContainerView.rightAnchor, constant: -10).isActive = true
leftLabel.centerYAnchor.constraint(equalTo: leftContainerView.centerYAnchor).isActive = true
let leftButton = UIButton()
leftButton.addTarget(self, action: #selector(onLeftAddressTap), for: .touchUpInside)
leftContainerView.addSubview(leftButton)
leftButton.translatesAutoresizingMaskIntoConstraints = false
leftButton.leftAnchor.constraint(equalTo: leftContainerView.leftAnchor).isActive = true
leftButton.rightAnchor.constraint(equalTo: leftContainerView.rightAnchor).isActive = true
leftButton.topAnchor.constraint(equalTo: leftContainerView.topAnchor).isActive = true
leftButton.bottomAnchor.constraint(equalTo: leftContainerView.bottomAnchor).isActive = true
}
func setupRightAddress() {
rightLabel.numberOfLines = 0
rightLabel.text = "This is the right label."
rightLabel.font = UIFont.systemFont(ofSize: 9)
rightLabel.adjustsFontSizeToFitWidth = true
rightLabel.isHidden = true
rightContainerView.addSubview(rightLabel)
rightLabel.translatesAutoresizingMaskIntoConstraints = false
rightLabel.leftAnchor.constraint(equalTo: rightContainerView.leftAnchor, constant: 10).isActive = true
rightLabel.rightAnchor.constraint(equalTo: rightContainerView.rightAnchor, constant: -10).isActive = true
rightLabel.centerYAnchor.constraint(equalTo: rightContainerView.centerYAnchor).isActive = true
let rightButton = UIButton()
rightButton.addTarget(self, action: #selector(onRightAddressTap), for: .touchUpInside)
rightContainerView.addSubview(rightButton)
rightButton.translatesAutoresizingMaskIntoConstraints = false
rightButton.leftAnchor.constraint(equalTo: rightContainerView.leftAnchor).isActive = true
rightButton.rightAnchor.constraint(equalTo: rightContainerView.rightAnchor).isActive = true
rightButton.topAnchor.constraint(equalTo: rightContainerView.topAnchor).isActive = true
rightButton.bottomAnchor.constraint(equalTo: rightContainerView.bottomAnchor).isActive = true
}
}
如果您希望“地址容器”为正方形 - 1:1 比例...
在setupLeftAddress()
中添加这一行:
leftContainerView.heightAnchor.constraint(equalTo: leftContainerView.widthAnchor).isActive = true
在setupRightAddress()
中添加这一行:
rightContainerView.heightAnchor.constraint(equalTo: rightContainerView.widthAnchor).isActive = true
并在 setupViews()
中更改堆栈视图分布:
//ContainerStackView.distribution = .fillEqually
ContainerStackView.distribution = .fill
这改变了这个:
对此:
场景:
我创建了一个包含多行元素的垂直 UIStackView。
一行包含重复的正方形 UIViews (Address1 & Address2),我想调整其大小。
注意:我没有使用 Interface Builder。仅通过代码。
问题: 这两个正方形似乎是固定的矩形,我无法 'square' 调整到合适的大小。
补救措施?
代码如下:
class MainView: UIView {
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// ------------------------------------------------
@objc func onLeftAddressTap() {
print("Left Address Selected")
leftLabel.isHidden = false
rightLabel.isHidden = !leftLabel.isHidden
leftContainerView.layer.borderColor = UIColor.green.cgColor
rightContainerView.layer.borderColor = UIColor.lightGray.cgColor
}
@objc func onRightAddressTap() {
print("Right Address Selected")
leftLabel.isHidden = true
rightLabel.isHidden = !leftLabel.isHidden
rightContainerView.layer.borderColor = UIColor.green.cgColor
leftContainerView.layer.borderColor = UIColor.lightGray.cgColor
}
// ------------------------------------------------
let leftLabel = UILabel()
let rightLabel = UILabel()
let leftContainerView: UIView = {
let view = UIView(frame: CGRect())
view.layer.borderWidth = 1.0
view.layer.borderColor = UIColor.green.cgColor
return view
}()
let rightContainerView: UIView = {
let view = UIView(frame: CGRect())
view.layer.borderWidth = 1.0
view.layer.borderColor = UIColor.lightGray.cgColor
return view
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = .white
setupViews()
}
// ------------------------------------------------
fileprivate func setupAddressStack() -> UIStackView {
setupLeftAddress()
setupRightAddress()
// ------------------------------------------------
// Address StackView:
let addressStackView = UIStackView(arrangedSubviews: [leftContainerView, rightContainerView])
addressStackView.axis = .horizontal
addressStackView.spacing = 10
addressStackView.distribution = .fillEqually
addressStackView.alignment = .fill
return addressStackView
}
// ------------------------------------------------
fileprivate func setupViews() {
// Image Logol
let ratImageview = UIImageView(image: UIImage(named: "Rat"))
ratImageview.frame = CGRect(x: 0, y: 0, width: 68, height: 68)
// TitleLabel
let titleLabel = UILabel(frame: CGRect())
let titleString = "Where should we send your card? We'll cancel it and send you a new one."
titleLabel.text = titleString
titleLabel.textAlignment = .center
titleLabel.font = .systemFont(ofSize: 12)
titleLabel.lineBreakMode = .byWordWrapping
titleLabel.numberOfLines = 0
// Status Label:
let statusLabel = UILabel(frame: CGRect())
let statusString = "Your existing card ending in 0492 will be cancelled and yournew card shoud arrive withi 6 business days via USPS."
statusLabel.text = statusString
statusLabel.textAlignment = .center
statusLabel.font = .systemFont(ofSize: 12)
statusLabel.lineBreakMode = .byWordWrapping
statusLabel.numberOfLines = 0
// ------------------------------------------------
// Container SackView:
let ContainerStackView = UIStackView(arrangedSubviews: [titleLabel, setupAddressStack(), statusLabel])
ContainerStackView.axis = .vertical
ContainerStackView.distribution = .fillEqually
ContainerStackView.spacing = 20
// Logo:
addSubview(ratImageview)
ratImageview.translatesAutoresizingMaskIntoConstraints = false
ratImageview.centerXAnchor.constraint(equalTo: centerXAnchor, constant: 0).isActive = true
ratImageview.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor, constant: 10).isActive = true
// StackView:
addSubview(ContainerStackView)
ContainerStackView.translatesAutoresizingMaskIntoConstraints = false
ContainerStackView.leftAnchor.constraint(equalTo: leftAnchor, constant: 10).isActive = true
ContainerStackView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor, constant: 75).isActive = true
ContainerStackView.rightAnchor.constraint(equalTo: rightAnchor, constant: -10).isActive = true
ContainerStackView.bottomAnchor.constraint(equalTo: centerYAnchor, constant: 0).isActive = true
}
}
// ==============================================================================================
private extension MainView {
func setupLeftAddress() {
// LeftLabel:
leftLabel.numberOfLines = 0
leftLabel.text = "Mother had a feeling, I might be too appealing."
leftLabel.font = UIFont.systemFont(ofSize: 9)
leftLabel.adjustsFontSizeToFitWidth = true
leftLabel.isHidden = false
leftContainerView.addSubview(leftLabel)
leftLabel.translatesAutoresizingMaskIntoConstraints = false
leftLabel.leftAnchor.constraint(equalTo: leftContainerView.leftAnchor, constant: 10).isActive = true
leftLabel.rightAnchor.constraint(equalTo: leftContainerView.rightAnchor, constant: -10).isActive = true
leftLabel.centerYAnchor.constraint(equalTo: leftContainerView.centerYAnchor).isActive = true
let leftButton = UIButton()
leftButton.addTarget(self, action: #selector(onLeftAddressTap), for: .touchUpInside)
leftContainerView.addSubview(leftButton)
leftButton.translatesAutoresizingMaskIntoConstraints = false
leftButton.leftAnchor.constraint(equalTo: leftContainerView.leftAnchor).isActive = true
leftButton.rightAnchor.constraint(equalTo: leftContainerView.rightAnchor).isActive = true
leftButton.topAnchor.constraint(equalTo: leftContainerView.topAnchor).isActive = true
leftButton.bottomAnchor.constraint(equalTo: leftContainerView.bottomAnchor).isActive = true
}
func setupRightAddress() {
rightLabel.numberOfLines = 0
rightLabel.text = "This is the right label."
rightLabel.font = UIFont.systemFont(ofSize: 9)
rightLabel.adjustsFontSizeToFitWidth = true
rightLabel.isHidden = true
rightContainerView.addSubview(rightLabel)
rightLabel.translatesAutoresizingMaskIntoConstraints = false
rightLabel.leftAnchor.constraint(equalTo: rightContainerView.leftAnchor, constant: 10).isActive = true
rightLabel.rightAnchor.constraint(equalTo: rightContainerView.rightAnchor, constant: -10).isActive = true
rightLabel.centerYAnchor.constraint(equalTo: rightContainerView.centerYAnchor).isActive = true
let rightButton = UIButton()
rightButton.addTarget(self, action: #selector(onRightAddressTap), for: .touchUpInside)
rightContainerView.addSubview(rightButton)
rightButton.translatesAutoresizingMaskIntoConstraints = false
rightButton.leftAnchor.constraint(equalTo: rightContainerView.leftAnchor).isActive = true
rightButton.rightAnchor.constraint(equalTo: rightContainerView.rightAnchor).isActive = true
rightButton.topAnchor.constraint(equalTo: rightContainerView.topAnchor).isActive = true
rightButton.bottomAnchor.constraint(equalTo: rightContainerView.bottomAnchor).isActive = true
}
}
如果您希望“地址容器”为正方形 - 1:1 比例...
在setupLeftAddress()
中添加这一行:
leftContainerView.heightAnchor.constraint(equalTo: leftContainerView.widthAnchor).isActive = true
在setupRightAddress()
中添加这一行:
rightContainerView.heightAnchor.constraint(equalTo: rightContainerView.widthAnchor).isActive = true
并在 setupViews()
中更改堆栈视图分布:
//ContainerStackView.distribution = .fillEqually
ContainerStackView.distribution = .fill
这改变了这个:
对此: