ios Swift:获取特定类型的所有子视图并添加到数组中
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32151637/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Swift: Get all subviews of a specific type and add to an array
提问by Kenji Crosland
I have a custom class of buttons in a UIView that I'd like to add to an array so that they're easily accessible. Is there a way to get all subviews of a specific class and add it to an array in Swift?
我在 UIView 中有一个自定义按钮类,我想将其添加到数组中,以便可以轻松访问它们。有没有办法获取特定类的所有子视图并将其添加到 Swift 中的数组中?
回答by vadian
The filter
function using the is
operator can filter items of a specific class.
filter
使用is
运算符的函数可以过滤特定类别的项目。
let myViews = view.subviews.filter{let myViews = view.subviews.compactMap{ 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: let allSubviews = view.allSubViewsOf(type: UIView.self)
let allLabels = view.allSubViewsOf(type: UILabel.self)
) }
}
getSubview(view: self)
return all
}
}
as? MyButtonClass}
is MyButtonClass}
MyButtonClass
is the custom class to be filtered for.
MyButtonClass
是要过滤的自定义类。
To filter and castthe view to the custom type use compactMap
过滤和投视图到自定义类型使用compactMap
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
}
回答by Mohammad Sadiq
Here you go
干得好
let allLabels : [UILabel] = getSubviewsOf(view: theView)
You can call it like
你可以称之为
view.subviews.flatMap{ countDots = allDots!.view.subviews.flatMap{extension UIView {
func subviews<T:UIView>(ofType WhatType:T.Type) -> [T] {
var result = self.subviews.compactMap {let arr = myView.subviews(ofType: MyButtonClass.self)
as? T}
for sub in self.subviews {
result.append(contentsOf: sub.subviews(ofType:WhatType))
}
return result
}
}
as? Dot}.count
as? YourView }
回答by ullstrm
To do this recursively (I.e. fetching all subview's views aswell), you can use this generic function:
要递归地执行此操作(即同时获取所有子视图的视图),您可以使用此通用函数:
let buttons:[UIButton] = stackView.subviews.compactMap{ let _ = stackView.subviews.compactMap{ for (index,button) in (view.subviews.filter{func allSubViews(views: [UIView]) {
for view in views {
if let tf = view as? UITextField {
// Do Something
}
self.allSubViews(views: view.subviews)
}
}
self.allSubViews(views: self.view.subviews)
is UIButton}).enumerated(){
button.isHidden = false
}
as? UIButton }.map { let containsBannerViewKind = view.subviews.first(where: { extension UIView {
func firstSubView<T: UIView>(ofType type: T.Type) -> T? {
var resultView: T?
for view in subviews {
if let view = view as? T {
resultView = view
break
}
else {
if let foundView = view.firstSubView(ofType: T.self) {
resultView = foundView
break
}
}
}
return resultView
}
}
is BannerView }) != nil
.isSelected = false }
as? UIButton }
To fetch all UILabel's in a view hierarchy, just do this:
要获取视图层次结构中的所有 UILabel,只需执行以下操作:
##代码##回答by Kametrixom
I can't test it right now but this should work in Swift 2:
我现在无法对其进行测试,但这应该适用于 Swift 2:
##代码##Which returns an array of YourView
它返回一个数组 YourView
Here's a tested, typical example, to get a count:
这是一个经过测试的典型示例,用于获取计数:
##代码##回答by matt
So many of the answers here are unnecessarily verbose or insufficiently general. Here's how to get all subviews of a view, at any depth, that are of anydesired class:
这里的许多答案都是不必要的冗长或不够笼统。以下是如何获取一个视图的所有子视图,在任何深度,属于任何所需的类:
##代码##How to use:
如何使用:
##代码##回答by Diego Carrera
From Swift 4.1, you can use new compactMap (flatMap is now depcrecated): https://developer.apple.com/documentation/swift/sequence/2950916-compactmap(see examples inside)
从 Swift 4.1 开始,您可以使用新的 compactMap(flatMap 现在已弃用):https: //developer.apple.com/documentation/swift/sequence/2950916-compactmap(请参阅里面的示例)
In your case, you can use:
在您的情况下,您可以使用:
##代码##And you can execute actions to all buttons using map:
您可以使用 map 对所有按钮执行操作:
##代码##回答by Zaid Pathan
If you want to update/access those specific subviews then use this,
如果您想更新/访问那些特定的子视图,请使用它,
##代码##回答by Mustafa Alqudah
回答by Vinh Nguyen
For this case, I think we could use Swift's first.where
syntax, which is more efficient than filter.count
, filter.isEmpty
.
对于这种情况,我认为我们可以使用 Swift 的first.where
语法,它比filter.count
,更有效filter.isEmpty
。
Because when we use filter
, it will create a underlying array, thus not effective, imagine we have a large collection.
因为当我们使用时filter
,它会创建一个底层数组,因此无效,假设我们有一个大集合。
So just check if a view's subViews
collection contains a specific kind of class, we can use this
所以只需检查视图的subViews
集合是否包含特定类型的类,我们可以使用它
which equivalent to: find me the first match to BannerView class in this view's subViews collection. So if this is true, we can carry out our further logic.
这相当于:在此视图的子视图集合中找到与 BannerView 类的第一个匹配项。所以如果这是真的,我们可以执行我们进一步的逻辑。
Reference: https://github.com/realm/SwiftLint/blob/master/Rules.md#first-where
参考:https: //github.com/realm/SwiftLint/blob/master/Rules.md#first-where
回答by Mike Glukhov
Let me post my variation of this) but this, finds the first of T
让我发布我对此的变体)但是这个,找到第一个 T
##代码##