简体   繁体   中英

Center views horizontally in iOS stack view

I'm trying to achieve the following layout (views centered horizontally):

在此处输入图片说明

So I set up a stack view like so:

let quickPromptsView: UIStackView = {
    let sv = UIStackView()
    sv.axis = .horizontal
    sv.alignment = .center
    sv.distribution = .equalSpacing
    sv.spacing = 10
    sv.translatesAutoresizingMaskIntoConstraints = false
    return sv
}()

Adding buttons to stack views:

func addOptions(options: [DialogNodeOutputOptionsElement]) {
    DispatchQueue.main.async {
        // clear all subviews
        self.quickPromptsView.subviews.forEach { (view) in
            view.removeFromSuperview()
        }
        for option in options {
            let button = QuickPromptButton()
            button.setTitle(option.label, for: .normal)
            button.addTarget(self, action: #selector(self.didTapQuickPrompt), for: .touchUpInside)
            self.quickPromptsView.addArrangedSubview(button)
        }
    }
}

Button class:

class QuickPromptButton: UIButton {

    var userFacingValue: String?
    var answerValue: String?

    override init(frame: CGRect) {
        super.init(frame: frame)
        layer.borderColor = UIColor.primaryColor.cgColor
        layer.borderWidth = 1
        layer.cornerRadius = 15
        setTitleColor(.primaryColor, for: .normal)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

This is how I add the stack view, I add it inside another stack part of the MessageKit

func configureQuickPromptsView() {
    view.addSubview(quickPromptsView)
    quickPromptsView.heightAnchor.constraint(equalToConstant: 40).isActive = true

    // this stack view belongs to the MessageKit library
    messageInputBar.topStackView.axis = .horizontal
    messageInputBar.topStackView.distribution = .fill
    messageInputBar.topStackView.addArrangedSubview(quickPromptsView)
}

However, this is what I get:

在此处输入图片说明

The stack view has 100% the width of the screen. I've tried every single type of distribution but that didn't work. I've also tried to insert transparent UIView s at the extremes to force the centering but that seems like a hack. Any ideas?

Just center your stack view horizontally in its superview.

Examples below are using UIKitPlus library (it is pure UIKit but declarative and support LivePreview, iOS9+)

UView {
    UHStack {
        UView {
            UText("Yes")
                .color(.green)
                .edgesToSuperview(h: 8, v: 4)
        }
        .border(1, .green)
        .circle()
        UView {
            UText("No")
                .color(.red)
                .edgesToSuperview(h: 8, v: 4)
        }
        .border(1, .red)
        .circle()
        UView {
            UText("I don't know")
                .color(.darkGray)
                .edgesToSuperview(h: 8, v: 4)
        }
        .border(1, .darkGray)
        .circle()
    }
    .alignment(.center)
    .distribution(.equalSpacing)
    .spacing(10)
    .edgesToSuperview(v: 0)
    .centerXInSuperview() // this will center your stack view
}
.edgesToSuperview(h: 0)
.centerYInSuperview()

第一个解决方案

Or use a little hack by adding two views with equal width, one in the beginning of stack and one as the last view in stack.

let v1 = UView()
UHStack {
    v1
    UView {
        UText("Yes")
            .color(.green)
            .edgesToSuperview(h: 8, v: 4)
    }
    .border(1, .green)
    .circle()
    UView {
        UText("No")
            .color(.red)
            .edgesToSuperview(h: 8, v: 4)
    }
    .border(1, .red)
    .circle()
    UView {
        UText("I don't know")
            .color(.darkGray)
            .edgesToSuperview(h: 8, v: 4)
    }
    .border(1, .darkGray)
    .circle()
    UView().width(to: v1)
}
.alignment(.center)
.spacing(10)
.edgesToSuperview(h: 0)
.centerYInSuperview()

第二种解决方案

The stack view itself can't center inner views automatically unfortunately, so you have to help it to do that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM