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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 07:21:35  来源:igfitidea点击:

Swift: Get all subviews of a specific type and add to an array

iosarraysswiftclasssubview

提问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 filterfunction using the isoperator 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}

MyButtonClassis 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.wheresyntax, 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 subViewscollection 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

##代码##