我想在一个网站中为一些元素添加layoutMargins UIStackView
我在代码中创建.我试过在IB中做同样的事情,它工作得很完美,但当我添加了 layoutMargins
我设置 isLayoutMarginsRelativeArrangement = true
那么我的堆栈视图的对齐方式就会中断。
我的堆栈视图的代码如下。
@objc lazy var buttonsStackView: UIStackView = {
let stack = UIStackView(arrangedSubviews: [doneButton, separatorView, giftButton])
stack.layoutMargins = UIEdgeInsets(top: 0, left: 4, bottom: 0, right: 4)
stack.isLayoutMarginsRelativeArrangement = true
stack.axis = .horizontal
stack.frame = CGRect(x: 0, y: 0, width: 150, height: 44)
stack.spacing = 4
stack.distribution = .equalCentering
stack.alignment = .center
let bgView = UIView(frame: stack.bounds)
stackViewBackground = bgView
bgView.backgroundColor = ColorManager.shared.grayColor
bgView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
stack.insertSubview(bgView, at: 0)
separatorView.heightAnchor.constraint(equalTo: stack.heightAnchor, multiplier: 0.8).isActive = true
return stack
}()
SeparatorView只有一个1pt宽度的约束, 而两个按钮则没有约束,以保持它们的宽度。intrinsicContentSize
.
以下是我的stackView在以下情况下的样子 isLayoutMarginsRelativeArrangement
是 false
:
但很明显,左右边距是需要的,所以当设置 isLayoutMarginsRelativeArrangement
到 true
我的stackview的对齐方式发生了变化。
不幸的是,我不能为这个特殊的视图使用IB,我需要从代码中初始化它。如果有任何关于如何解决这个问题的想法,我们将非常感激。谢谢你!我正在尝试添加layoutMargin。
下面是一个将该视图变成自定义视图的例子,使用的是 separator
水平居中,按钮在每个 "边 "上居中。
protocol DoneGiftDelegate: class {
func doneButtonTapped()
func giftButtonTapped()
}
class DoneGiftView: UIView {
weak var delegate: DoneGiftDelegate?
let doneButton: UIButton = {
let v = UIButton(type: .system)
v.setTitle("Done", for: [])
v.tintColor = .white
return v
}()
let giftButton: UIButton = {
let v = UIButton(type: .system)
v.setImage(UIImage(systemName: "gift.fill"), for: [])
v.tintColor = .white
return v
}()
let separatorView: UIView = {
let v = UIView()
v.backgroundColor = .white
return v
}()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() -> Void {
backgroundColor = .lightGray // ColorManager.shared.grayColor
[doneButton, separatorView, giftButton].forEach {
$0.translatesAutoresizingMaskIntoConstraints = false
addSubview($0)
}
// width and height constraints: 150 x 44
// set Priority to 999 so it can be overriden by controller if desired
let widthConstraint = widthAnchor.constraint(equalToConstant: 150.0)
widthConstraint.priority = UILayoutPriority(rawValue: 999)
let heightConstraint = heightAnchor.constraint(equalToConstant: 44.0)
heightConstraint.priority = UILayoutPriority(rawValue: 999)
NSLayoutConstraint.activate([
// doneButton Leading to Leading
doneButton.leadingAnchor.constraint(equalTo: leadingAnchor),
// separator Leading to doneButton Trailing
separatorView.leadingAnchor.constraint(equalTo: doneButton.trailingAnchor),
// giftButton Leading to separator Trailing
giftButton.leadingAnchor.constraint(equalTo: separatorView.trailingAnchor),
// giftButton Trailing to Trailing
giftButton.trailingAnchor.constraint(equalTo: trailingAnchor),
// all centered vertically
doneButton.centerYAnchor.constraint(equalTo: centerYAnchor),
separatorView.centerYAnchor.constraint(equalTo: centerYAnchor),
giftButton.centerYAnchor.constraint(equalTo: centerYAnchor),
// doneButton Height = Height
doneButton.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 1.0),
// separator Height = 80% of Height
separatorView.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 0.8),
// giftButton Height = Height
giftButton.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 1.0),
// separator Width = 1
separatorView.widthAnchor.constraint(equalToConstant: 1.0),
// doneButton Width = giftButton Width
doneButton.widthAnchor.constraint(equalTo: giftButton.widthAnchor, multiplier: 1.0),
// self Width and Height
widthConstraint,
heightConstraint,
])
// add target actions for buttons
doneButton.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside)
giftButton.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside)
}
@objc func buttonTapped(_ sender: UIButton) -> Void {
if sender == doneButton {
delegate?.doneButtonTapped()
} else {
delegate?.giftButtonTapped()
}
}
}
class DemoViewController: UIViewController, DoneGiftDelegate {
let doneGiftView: DoneGiftView = DoneGiftView()
let testView: UIView = UIView()
override func viewDidLoad() {
super.viewDidLoad()
doneGiftView.translatesAutoresizingMaskIntoConstraints = false
testView.translatesAutoresizingMaskIntoConstraints = false
testView.addSubview(doneGiftView)
view.addSubview(testView)
// so we can see the view frame
testView.backgroundColor = .cyan
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
// testView Top: 100
// Leading / Trailing with 20-pts "padding"
// Height: 80
testView.topAnchor.constraint(equalTo: g.topAnchor, constant: 100.0),
testView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
testView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
testView.heightAnchor.constraint(equalToConstant: 80.0),
// doneGiftView Trailing to testView Trailing
doneGiftView.trailingAnchor.constraint(equalTo: testView.trailingAnchor),
// doneGiftView centered vertically in testView
doneGiftView.centerYAnchor.constraint(equalTo: testView.centerYAnchor),
])
doneGiftView.delegate = self
}
func doneButtonTapped() {
print("Done button tapped!")
// do what we want when Done button tapped
}
func giftButtonTapped() {
print("Gift button tapped")
// do what we want when Gift button tapped
}
}
结果示例: