Dans mon ViewController
, j'ai 12 UIViews
personnalisés (nommés CardView).
J'essaie de parcourir les sous-vues du ViewController
par programmation pour trouver la vue personnalisée (CardView) et effectuer une configuration. Voici mon code pour compter le nombre de CardViews.
private func cardCount()->Int{ var count = 0 for subview in self.view.subviews{ if subview is CardView{ count = count + 1 } } return count }
Cependant, il me renvoie «0» et la raison étant que mes vues sont intégrées dans UIStackViews code>. J'ai 3 vues de pile alignées horizontalement dans une vue alignée verticalement comme-
Comment puis-je obtenir mes CardViews par programmation. Toute aide serait appréciée.
5 Réponses :
Vous créez des IBOutlets dans chacune des vues de pile horizontale. Ensuite, parcourez les sous-vues dans les vues de pile.
@IBOutlet weak var StackView1: UIStackView! @IBOutlet weak var StackView2: UIStackView! @IBOutlet weak var StackView3: UIStackView! for customView in StackView1.arrangedSubviews { // Do task }
Essayez ceci
private func cardCount() -> Int { var count = 0 for subview in self.view.subviews { if let stackView: UIStackView = subview as? UIStackView { let arrangedViews = stackView.arrangedSubviews for cardView in arrangedViews { if cardView is CardView { count = count + 1 } } } } return count }
D'après le diagramme illustré que vous avez partagé, il semble que StackView soit le premier enfant. Chaque fois que vous obtenez les sous-vues, seules les premières vues enfants sont renvoyées. Ainsi, self.view.subviews
ne donnerait qu'un seul UIStackView
. Donnez une balise à chaque vue de pile. Ensuite, dans le code:
private func cardCount()->Int{ var count = 0 for subview in self.view.subviews{ if subview.tag == 10 { // parent stack view for subviewStack in subview { // Get subviews of parent stackview if subviewStack.tag == 11 { // First stack view child for subViewSubStack in subviewStack.subviews { // Get card views in this stack view // Apply your count logic } } } } } return count }
Je n'ai écrit que la première condition. Vous pourriez en ajouter d'autres.
Cela dit, je ne dirai pas que c'est la solution la plus optimale. Cela peut et doit être remanié.
La solution de @ Sweeper est la version refactorisée de ce que j'ai écrit.
Vous pouvez faire quelques plans plats pour aplatir d'abord votre structure de vue, puis les compter:
private func cardCount()->Int{ var count = 0 for subview in self.view.subviews.flatMap { $0.subviews }.flatMap { $0.subviews }{ if subview is CardView{ count = count + 1 } } return count }
Mais j'ai l'impression que vous faites les choses dans le mauvais sens. Le nombre de cartes ressemble à quelque chose dans votre modèle. Vous devriez avoir une variable appelée cardCount
et les cartes à l'écran sont censées changer en fonction de cette variable, et non l'inverse.
Créez une méthode d'extension comme celle-ci. Il comptera toutes les instances CardView dans le contrôleur de vue.
class ViewControllerd: UIViewController { override func viewDidLoad() { super.viewDidLoad() print(self.view.cardCount()) } }
et appellera cette méthode dans viewDidLoad
extension UIView { func cardCount() -> Int { switch self { case let self as CardView: return 1 case let self as UIStackView: return self.arrangedSubviews.reduce(0, { $0 + $1.cardCount() }) default: return self.subviews.reduce(0, { $0 + $1.cardCount() }) } } }
p >
utiliser la propriété arrangéeSubviews au lieu de sous-vues
Vous pouvez utiliser collectionView pour ce type d'interface utilisateur. C'est la meilleure approche
Cher, je pense que vous pouvez faire une boucle encore et encore pour accéder aux vues de carte
première boucle pour la vue verticale de la pile, deuxième pour la vue horizontale de la pile et dernière pour accéder à la carte
Je pense que vous devriez changer la logique de rendu de l'interface utilisateur ici en utilisant soit la vue de la pile à l'intérieur de l'élément de vue de la collection, soit la cellule de la vue du tableau. Mais pour répondre à votre requête ici, vous pouvez créer une instance de la
vue de la pile
du conteneur et effectuer une itération pour les sousvues de la pile
. De cette façon, vous obtiendrez desvues de pile
individuelles et une deuxième itération serait pour lesvues de pile
individuelles pour en obtenir lessous-vues
.Pouvez-vous expliquer pourquoi vous comptez le nombre de cartes? Je sens une question XY.
Merci pour toutes les suggestions. Je sais qu'il existe quelques meilleures alternatives dans cette situation, mais je le fais à des fins d'apprentissage. Je pense que j'ai besoin de boucler jusqu'à ce qu'il n'y ait plus de stackviews.