UIStackView равное расстояние, включая края - PullRequest
0 голосов
/ 13 февраля 2019

У меня горизонтальный вид стека с 3 кнопками: Назад, Воспроизведение, Вперед для музыкального приложения.Вот мой текущий код:

self.controlStackView.axis = .horizontal
self.controlStackView.distribution = .equalSpacing
self.controlStackView.alignment = .center
self.controlStackView.spacing = 10.0
self.controlStackView.translatesAutoresizingMaskIntoConstraints = false
self.contentView.addSubview(self.controlStackView)

self.controlStackView.topAnchor.constraint(equalTo: self.artworkImageView.bottomAnchor, constant: 10.0).isActive = true
self.controlStackView.centerXAnchor.constraint(equalTo: self.contentView.centerXAnchor).isActive = true

Что это такое, он распределяет кнопку следующим образом (из центра из-за выравнивания):

[backward] - 10 spacing - [play] - 10 spacing - [forward]

Iможет увеличить расстояние, но оно все равно будет исправлено.Поэтому я устанавливаю ведущий и конечный якорь, чтобы определить максимальную ширину стека:

self.controlStackView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
self.controlStackView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true

Что это делает с макетом:

[left edge backward] - lots of spaaaaaaace - [centered play] - lots of spaaaaaaace - [right edge forward]

Распределяется по всей ширине (и между центром слева и справа есть .equalSpacing).Но это тоже не полезно.По сути, моя цель состоит в том, чтобы иметь по-настоящему равный интервал, включая края.

Допустим, у меня есть доступная ширина 100, а мои 3 кнопки - 10, 20, 10 - это означает, что есть 60 оставшихся пустых мест.

Я бы хотел, чтобы это распределялось так:

space - [backward] - space - [play] - space [forward] - space

Таким образом, между моими кнопками по 4 пробела, каждый из которых равен 15, поэтому мы заполняем оставшиеся 60пространство.Конечно, я мог бы реализовать заполнение для представления стека, чтобы получить внешнее пространство, но это было бы довольно статично и не было бы равномерно распределено.

Кто-нибудь знает, могу ли я реализовать его таким образом, чтобы ребра были включены враспределение пространства?

спасибо

1 Ответ

0 голосов
/ 13 февраля 2019

Это действительно довольно просто, с использованием «проставочных» представлений.

Добавьте еще одну проставку, чем количество кнопок, так что вы получите:

spacer - button - spacer - button - spacer

Затем ограничьтеширина распорок 2-к-n равна ширине первой распорки.StackView будет обрабатывать все остальное!

Вот пример (просто нужен viewController в раскадровке, остальное делается с помощью кода):

class DistributeViewController: UIViewController {

    let stackView: UIStackView = {
        let v = UIStackView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.axis = .horizontal
        v.alignment = .fill
        v.distribution = .fill
        v.spacing = 0
        return v
    }()

    var buttonTitles = [
        "Backward",
        "Play",
        "Forward",
//      "Next",
        ]

    var numButtons = 0

    override func viewDidLoad() {
        super.viewDidLoad()

        // stackView will hold the buttons and spacers
        view.addSubview(stackView)

        // constrain it to Top + 20, Leading and Trailing == 0, height will be controlled by button height
        NSLayoutConstraint.activate([
            stackView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20.0),
            stackView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 0.0),
            stackView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: 0.0),
            ])

        // arrays to hold our buttons and spacers
        var buttons: [UIView] = [UIView]()
        var spacers: [UIView] = [UIView]()

        numButtons = buttonTitles.count

        // create the buttons and append them to our buttons array
        for i in 0..<numButtons {
            let b = UIButton()
            b.translatesAutoresizingMaskIntoConstraints = false
            b.backgroundColor = .blue
            b.setTitle(buttonTitles[i], for: .normal)
            buttons.append(b)
        }

        // create the spacer views and append them to our spacers array
        //      we need 1 more spacer than buttons
        for _ in 1...numButtons+1 {
            let v = UIView()
            v.translatesAutoresizingMaskIntoConstraints = false
            v.backgroundColor = .red        // just so we can see them... use .clear for production
            spacers.append(v)
        }

        // addd spacers and buttons to stackView
        for i in 0..<spacers.count {

            stackView.addArrangedSubview(spacers[i])

            // one fewer buttons than spacers, so don't go out-of-range
            if i < buttons.count {
                stackView.addArrangedSubview(buttons[i])
            }

            if i > 0 {
                // constrain spacer widths to first spacer's width (this will make them all equal)
                spacers[i].widthAnchor.constraint(equalTo: spacers[0].widthAnchor, multiplier: 1.0).isActive = true

                // if you want the buttons to be equal widths, uncomment this block
                /*
                if i < buttons.count {
                    buttons[i].widthAnchor.constraint(equalTo: buttons[0].widthAnchor, multiplier: 1.0).isActive = true
                }
                */

            }

        }

    }

}

Результаты с 3 кнопками:

enter image description here enter image description here

и с 4 кнопками:

enter image description here enter image description here

и пара с кнопками равной ширины:

enter image description here enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...