Swift: Recursively cycle through all subviews to find a specific class and append to an array

前端 未结 6 676
故里飘歌
故里飘歌 2020-12-06 04:46

Having a devil of a time trying to figure this out. I asked a similar question here: Swift: Get all subviews of a specific type and add to an array

While this works,

6条回答
  •  孤街浪徒
    2020-12-06 04:55

    Based on Aaron Brager and ullstrm answers

    Details

    • Xcode 9.1, Swift 4,
    • Xcode Version 10.3 (10G8), Swift 5

    Solution

    extension UIView {
    
        class func getAllSubviews(from parenView: UIView) -> [T] {
            return parenView.subviews.flatMap { subView -> [T] in
                var result = getAllSubviews(from: subView) as [T]
                if let view = subView as? T { result.append(view) }
                return result
            }
        }
    
        class func getAllSubviews(from parenView: UIView, types: [UIView.Type]) -> [UIView] {
            return parenView.subviews.flatMap { subView -> [UIView] in
                var result = getAllSubviews(from: subView) as [UIView]
                for type in types {
                    if subView.classForCoder == type {
                        result.append(subView)
                        return result
                    }
                }
                return result
            }
        }
    
        func getAllSubviews() -> [T] { return UIView.getAllSubviews(from: self) as [T] }
        func get(all type: T.Type) -> [T] { return UIView.getAllSubviews(from: self) as [T] }
        func get(all types: [UIView.Type]) -> [UIView] { return UIView.getAllSubviews(from: self, types: types) }
    }
    

    Usage sample

    var allViews = UIView.getAllSubviews(from: simpleView)
    func printResult(with text: String) {
        print("\n==============================================")
        print("\(text):\n\(allViews.map { $0.classForCoder } )")
    }
    printResult(with: "UIView.getAllSubviews(from: simpleView)")
    
    allViews = UIView.getAllSubviews(from: simpleView) as [UILabel]
    printResult(with: "UIView.getAllSubviews(from: simpleView) as [UILabel]")
    
    allViews = UIView.getAllSubviews(from: simpleView, types: [UIStackView.self, UILabel.self])
    printResult(with: "UIView.getAllSubviews(from: simpleView, types: [UIStackView.self, UILabel.self])")
    
    allViews = simpleView.getAllSubviews()
    printResult(with: "simpleView.getAllSubviews()")
    
    allViews = simpleView.getAllSubviews() as [UILabel]
    printResult(with: "simpleView.getAllSubviews() as [UILabel]")
    
    allViews = simpleView.get(all: UILabel.self)
    printResult(with: "simpleView.get(all: UILabel.self)")
    
    allViews = simpleView.get(all: [UIStackView.self, UILabel.self])
    printResult(with: "simpleView.get(all: [UIStackView.self, UILabel.self])")
    

    Output of the sample

    ==============================================
    UIView.getAllSubviews(from: simpleView):
    [UILabel, UIButton, UILabel, UILabel, UILabel, UIStackView]
    
    ==============================================
    UIView.getAllSubviews(from: simpleView) as [UILabel]:
    [UILabel, UILabel, UILabel, UILabel]
    
    ==============================================
    UIView.getAllSubviews(from: simpleView, types: [UIStackView.self, UILabel.self]):
    [UILabel, UILabel, UILabel, UILabel, UIStackView]
    
    ==============================================
    simpleView.getAllSubviews():
    [UILabel, UIButton, UILabel, UILabel, UILabel, UIStackView]
    
    ==============================================
    simpleView.getAllSubviews() as [UILabel]:
    [UILabel, UILabel, UILabel, UILabel]
    
    ==============================================
    simpleView.get(all: UILabel.self):
    [UILabel, UILabel, UILabel, UILabel]
    
    ==============================================
    simpleView.get(all: [UIStackView.self, UILabel.self]):
    [UILabel, UILabel, UILabel, UILabel, UIStackView]
    

    Storyboard of the sample

    Other info

    Also, I suggest to work with weak references. Array with weak references to objects

提交回复
热议问题