J'ai une vue de pile horizontale que j'ai ajoutée à des sous-vues arrangées (7 cellules). Chacune des cellules de la pile a un badge circulaire qui dépasse les limites de la vue (contrainte négative). Lors de l'exécution, comme vous pouvez le voir ci-dessous, chaque cellule se trouve au-dessus du badge de la cellule précédente. Je voudrais changer l'ordre pour que les badges soient entièrement visibles.
J'ai essayé de jouer avec l'index Z mais cela n'a pas aidé, car les couches ne sont pas plates comme vous pouvez le voir dans la hiérarchie suivante:
Une idée ou une suggestion comment le faire?
Merci.
La documentation de la classe UIStackView indique que:
L'ordre du tableau des sous-vues définit l'ordre Z des sous-vues. Si les vues se chevauchent, les sous-vues d'indice inférieur apparaissent derrière les sous-vues d'index supérieur.
ce qui est exactement ce que j'ai expérimenté dans la question. Pour résoudre mon cas spécifique, j'ai eu l’astuce de changer la sémantique de la vue en RTL comme on peut le voir ici:
Cela ne couvre pas le cas générique, car un périphérique a peut-être été défini comme langage RTL dans ses paramètres globaux. Pour le cas générique, je devrais vérifier la sémantique de l'interface et forcer une direction opposée à celle de la pile.
P.S. C'est un peu un bidouillage, toute idée sur la façon de réordonner l'ordre Z des sous-vues d'une manière différente sera la bienvenue!
Cette solution Swift inverse l'ordre de la sous-vue de la pile à l'aide de la méthode UIView sendSubviewToBack(_:)
( docs here ):
@IBOutlet weak var stackView: UIStackView!
for view in stackView.arrangedSubviews {
stackView.sendSubviewToBack(view)
}
Au fur et à mesure que nous avançons dans les vues organisées de la vue de pile (de bas en haut), les vues les plus récentes (c'est-à-dire les plus hautes) sont poussées vers le bas, inversant ainsi l'ordre :-)
Depuis iOS 9.0, il est possible de définir indépendamment l'ordre z et la disposition des sous-vues de la vue de pile. Utilisez la nouvelle propriété arrangedSubviews
pour spécifier la disposition des sous-vues le long de l’axe de la vue de pile. Et utilisez la propriété subviews
pour spécifier l'ordre z des sous-vues en fonction de leur index dans le tableau.
La vue de pile garantit que sa propriété arrangedSubviews
est toujours un sous-ensemble de sa propriété subviews
.
Vous trouverez ci-dessous une simple extension sur UIStackView
pour inverser l'index z des sous-vues de UIStackView
et nécessiter éventuellement une présentation:
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() }
}
}
}
Une autre idée pourrait être de définir la couleur de fond des sous-vues (7 cellules) sur la valeur par défaut ( entièrement transparent ). Et définissez uniquement l'arrière-plan de la vue stack sur white .
J'ai un problème similaire mais où chaque sous-vue doit avoir un arrière-plan spécifique. Et dans mon cas, votre bidouille pourrait aider… ???? Merci pour cela!
Par programme, lorsque vous ajoutez la sous-vue, ajoutez des contraintes de hauteur et de largeur constantes. À la fin, appelez setNeedsLayout de StackView. Il va calculer et essayer d'ajuster les vues avec l'espacement
Après diverses tentatives, je suis capable de le faire horizontalement
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()
}