Swift: obtén todas las subvistas de un tipo específico y agregalas a una matriz

Tengo una class personalizada de botones en una UIView que me gustaría agregar a una matriz para que sean fácilmente accesibles, hay una manera de hacerlo. ¿Obtiene todas las subvistas de una class específica y la agrega a una matriz en Swift?

La function de filter que usa el operador is puede filtrar elementos de una class específica.

 let myViews = view.subviews.filter{$0 is MyButtonClass} 

MyButtonClass es la class personalizada a filtrar.

No puedo probarlo ahora, pero esto debería funcionar en Swift 2:

 view.subviews.flatMap{ $0 as? YourView } 

Que devuelve una matriz de YourView

Aquí hay un ejemplo probado y típico para get un recuento:

 countDots = allDots!.view.subviews.flatMap{$0 as? Dot}.count 

Aqui tienes

  extension UIView { /** This is the function to get subViews of a view of a particular type */ func subViews<T : UIView>(type : T.Type) -> [T]{ var all = [T]() for view in self.subviews { if let aView = view as? T{ all.append(aView) } } return all } /** This is a function to get subViews of a particular type from view recursively. It would look recursively in all subviews and return back the subviews of the type T */ func allSubViewsOf<T : UIView>(type : T.Type) -> [T]{ var all = [T]() func getSubview(view: UIView) { if let aView = view as? T{ all.append(aView) } guard view.subviews.count>0 else { return } view.subviews.forEach{ getSubview(view: $0) } } getSubview(view: self) return all } } 

Puedes llamarlo como

 let allSubviews = view.allSubViewsOf(type: UIView.self) let allLabels = view.allSubViewsOf(type: UILabel.self) 

Si desea actualizar / acceder a esas subvenciones específicas, entonces use esto,

 for (index,button) in (view.subviews.filter{$0 is UIButton}).enumerated(){ button.isHidden = false } 

Para hacer esto de forma recursiva (es decir, get todas las vistas de la subvista también), puede usar esta function genérica:

 private func getSubviewsOf<T : UIView>(view:UIView) -> [T] { var subviews = [T]() for subview in view.subviews { subviews += getSubviewsOf(view: subview) as [T] if let subview = subview as? T { subviews.append(subview) } } return subviews } 

Para search todos los UILabel en una jerarquía de vistas, simplemente haz esto:

 let allLabels : [UILabel] = getSubviewsOf(view: theView) 

UIView tiene una propiedad llamada subViews , puede ver la API.

Para este caso, creo que podríamos usar la first.where syntax de Swift, que es más eficiente que filter.count , filter.isEmpty .

Porque cuando usamos el filter , creará una matriz subyacente, por lo tanto no es efectiva, imaginemos que tenemos una gran colección.

Por lo tanto, compruebe si la colección de subViews una vista contiene un tipo específico de class, podemos usar esto

 let containsBannerViewKind = view.subviews.first(where: { $0 is BannerView }) != nil 

que es equivalente a: encontrarme la primera coincidencia con la class BannerView en la colección subViews de esta vista. Entonces, si esto es cierto, podemos llevar a cabo nuestra lógica adicional.

Referencia: https://github.com/realm/SwiftLint/blob/master/Rules.md#first-where