Swift:获取特定类型的所有子视图并添加到数组中

Ken*_*and 38 arrays class subview ios swift

我在UIView中有一个自定义类按钮,我想将它添加到一个数组中,以便它们易于访问.有没有办法获取特定类的所有子视图并将其添加到Swift中的数组?

vad*_*ian 68

filter使用is运算符的函数可以过滤特定类的项.

let myViews = view.subviews.filter{$0 is MyButtonClass}
Run Code Online (Sandbox Code Playgroud)

MyButtonClass 是要过滤的自定义类.

  • 语法称为"Trailing Closure"symtax​​:*`如果提供闭包表达式作为函数的唯一参数,并且您将该表达式作为尾随闭包提供,则不需要在函数名称后面写一对括号()你打电话给这个职能.* (4认同)
  • 这有效,但语法有点偏:应该让myViews = view.subViews.filter({$ 0是MyButtonClass}) (2认同)
  • 如果在“for in”循环中出现在“in”之后的对象上调用它,则似乎不能使用尾随闭包:for myButton in view.subViews.filter{$0 is MyButtonClass} { } has error: "Anonymous闭包中不包含闭包参数” (2认同)

Moh*_*diq 29

干得好

    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
        }
    }
Run Code Online (Sandbox Code Playgroud)

你可以这样称呼它

let allSubviews = view.allSubViewsOf(type: UIView.self)
let allLabels = view.allSubViewsOf(type: UILabel.self)
Run Code Online (Sandbox Code Playgroud)


mat*_*att 21

这里的许多答案都是不必要的冗长或不够笼统。以下是如何获取一个视图的所有子视图,在任何深度,属于任何所需的类:

extension UIView {
    func subviews<T:UIView>(ofType WhatType:T.Type) -> [T] {
        var result = self.subviews.compactMap {$0 as? T}
        for sub in self.subviews {
            result.append(contentsOf: sub.subviews(ofType:WhatType))
        }
        return result
    }
}
Run Code Online (Sandbox Code Playgroud)

如何使用:

let arr = myView.subviews(ofType: MyButtonClass.self)
Run Code Online (Sandbox Code Playgroud)

  • 由于某种原因,我收到错误:实例方法“subViews(ofType:)”要求“UITextView.Type”继承“UIView” (2认同)

ull*_*trm 18

要递归地执行此操作(即获取所有子视图的视图),您可以使用此通用函数:

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
}
Run Code Online (Sandbox Code Playgroud)

要获取视图层次结构中的所有UILabel,只需执行以下操作:

let allLabels : [UILabel] = getSubviewsOf(view: theView)
Run Code Online (Sandbox Code Playgroud)


Kam*_*xom 12

我现在无法测试它,但这应该适用于Swift 2:

view.subviews.flatMap{ $0 as? YourView }
Run Code Online (Sandbox Code Playgroud)

返回一个数组 YourView

这是一个经过测试的典型示例,用于计算:

countDots = allDots!.view.subviews.flatMap{$0 as? Dot}.count
Run Code Online (Sandbox Code Playgroud)


Zai*_*han 5

如果您想更新/访问这些特定的子视图,请使用此方法,

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


Die*_*era 5

在Swift 4.1中,您可以使用新的compactMap(现在不再使用flatMap):https : //developer.apple.com/documentation/swift/sequence/2950916-compactmap (请参阅内部示例)

就您而言,您可以使用:

let buttons:[UIButton] = stackView.subviews.compactMap{ $0 as? UIButton }
Run Code Online (Sandbox Code Playgroud)

您可以使用map对所有按钮执行操作:

let _ = stackView.subviews.compactMap{ $0 as? UIButton }.map { $0.isSelected = false }
Run Code Online (Sandbox Code Playgroud)