Перекрывающиеся представления в UIStackView
У меня есть представление горизонтального стека, которое я добавил к нему (7 ячеек).
Каждая из ячеек в стеке имеет круговой значок, который превышает границы вида (отрицательное ограничение).
При работе, как показано ниже, каждая ячейка находится поверх значка предыдущей ячейки. Я хотел бы изменить порядок, чтобы значки были полностью видимыми.
![введите описание изображения здесь]()
Пробовал играть с индексом Z, но это не помогло, поскольку слои как-то не плоские, как вы можете видеть в следующей иерархии представлений:
![введите описание изображения здесь]()
Любая идея или предложение, как это сделать?
Спасибо.
Ответы
Ответ 1
Документация для класса UIStackView сообщает, что:
Порядок массива subviews определяет Z-порядок подсмотров. Если представления перекрываются, подзоны с более высоким индексом появляются подзоны с более низким индексом.
что и есть то, что я испытал в вопросе. Чтобы закончить мой конкретный случай, я сделал трюк, чтобы изменить семантику представления как RTL, как можно видеть здесь:
![введите описание изображения здесь]()
Это не распространяется на общий случай, поскольку на устройстве, возможно, был установлен язык RTL в его глобальных настройках. Для общего случая я предполагаю, что мне нужно будет проверить семантический интерфейс и заставить противоположное направление в моем представлении стека.
P.S. Это как-то взломать, поэтому любые идеи о том, как изменить порядок Z-порядка подсмотров по-другому, будут наиболее желанными!
Ответ 2
Это решение Swift изменяет порядок подпредставлений стекового представления с помощью метода sendSubviewToBack(_:)
(документы здесь):
@IBOutlet weak var stackView: UIStackView!
for view in stackView.arrangedSubviews {
stackView.sendSubviewToBack(view)
}
По мере продвижения через упорядоченные представления стековых представлений (снизу вверх) более поздние (то есть более высокие) представления сдвигаются к низу, меняя порядок в обратном порядке :-)
Ответ 3
Так как iOS 9.0 позволяет установить z-порядок и расположение представлений представления стека независимо. Используйте новое свойство arrangedSubviews
, чтобы указать расположение подпроектов вдоль оси представления стека. И используйте свойство subviews
, чтобы указать subviews z-order на основе их индекса в массиве.
Представление стека гарантирует, что его свойство arrangedSubviews
всегда является подмножеством его свойства subviews
.
Документация для builtSubviews
Ответ 4
Другая идея может заключаться в том, чтобы установить фоновый цвет субвью (7 ячеек) по умолчанию (полностью прозрачный). И установите только фон самого представления стека в белый.
У меня есть аналогичная проблема, но там, где у каждого подзаголовка должен быть определенный фон. И в моем случае ваш взлом может помочь... 😉 Спасибо за это!
Ответ 5
Ниже приведено простое расширение на UIStackView
, чтобы отменить z-индекс подкадров UIStackView
и, возможно, потребовать компоновку:
extension UIStackView {
func reverseSubviewsZIndex(setNeedsLayout: Bool = true) {
let stackedViews = self.arrangedSubviews
stackedViews.forEach {
self.removeArrangedSubview($0)
$0.removeFromSuperview()
}
stackedViews.reversed().forEach(addSubview(_:))
stackedViews.forEach(addArrangedSubview(_:))
if setNeedsLayout {
stackedViews.forEach { $0.setNeedsLayout() }
}
}
}
Ответ 6
Программно, когда вы добавляете подпредставление, добавляйте ограничения на высоту и ширину. В конце вызова StackView setNeedsLayout. Он рассчитает и попытается отрегулировать виды с интервалом
После различных попыток я могу сделать это горизонтально
stackView.leadingAnchor.constraint(equalTo: stackScrollView.leadingAnchor).isActive = true
stackView.trailingAnchor.constraint(equalTo: stackScrollView.trailingAnchor).isActive = true
stackView.bottomAnchor.constraint(equalTo: stackScrollView.bottomAnchor).isActive = true
stackView.heightAnchor.constraint(equalTo: stackScrollView.heightAnchor).isActive = true
stackView.distribution = .equalSpacing
stackView.spacing = 5
stackView.axis = .horizontal
stackView.alignment = .fill
for i in 0 ..< images.count {
let photoView = UIButton.init(frame: CGRect(x: 0, y: 0, width: 85, height: 85))
// set button image
photoView.translatesAutoresizingMaskIntoConstraints = false
photoView.heightAnchor.constraint(equalToConstant: photoView.frame.height).isActive = true
photoView.widthAnchor.constraint(equalToConstant: photoView.frame.width).isActive = true
stackView.addArrangedSubview(photoView)
}
stackView.setNeedsLayout()