簡體   English   中英

使用函數遞歸循環遍歷數組數組

[英]Recursively loop through array of arrays using functional

我想遍歷我的視圖子視圖,並為每個子視圖循環遍歷其子視圖等。

所以說我有以下代碼:

let view = myVC.view
view.backgroundColor = UIColor.clearColor()

然后對每個子視圖重復相同的操作。 我想在功能上做到這一點。

任何見解都非常感激。

編輯:

說清楚

我在尋找這樣的東西:

view.subviews.chanageColor() { (aView, aColor) in
aView.backgroundColor = aColor
}

但它應該是遞歸的,它會轉到每個視圖子視圖。

像這樣的東西?

func makeAllSubviewsClear(view: UIView!)
{
    view.backgroundColor = UIColor.clearColor()
    for eachSubview in view.subviews
    {
        makeAllSubviewsClear(eachSubview)
    }
}

通過:

let view = myVC.view
makeAllSubviewsClear(view)

使用隊列而不是遞歸。

我想你可以這樣做......

extension UIView {    
    func changeColor(color: UIColor) {
        var queue = [self]

        while let view = queue.first() {
            queue += view.subviews

            view.backgroundColor = color

            queue.remove(view)
        }
    }
}

我是用隊列來做的,而不是遞歸地做。 但該方法不起作用。

做你想要的問題

你可以這樣做,這就是你在問題中提出的想法。

extension UIView {
    // this name isn't very good but you get the idea
    func applyChangeToAllSubviews(block: (UIView) -> ()) {
        var queue = [self]

        // I don't have my dev computer dos not sure of the syntax
        while let view = queue.first() {
            queue += view.subviews

            block(view)

            queue.remove(view)
        }
    }
}

然后像......一樣運行它

someView.applyChangeToAllSubviews {
    view in
    view.backgroundColor = UIColor.whiteColor()
}

我想這有點功能......是的。

怎么樣:

let _ = myVC.view.subviews.map{ $0.backgroundColor = UIColor.clearColor() }

雖然地圖應該以不同的方式使用imho。

編輯:我只是看起來OP想要遞歸循環,這是不同的事情。 您應該將此代碼移動到函數中,並為每個$ 0遞歸調用它。

也許這樣的東西:

extension Array where Element: UIView {
    func changeColor(color: UIColor) {
        for view in self {
            view.subviews.changeColor(color)
            view.backgroundColor = color
        }
    }
}

看起來很實用,可以像這樣調用:

myVC.view.subviews.changeColor(color)

受@fogmaister啟發的另一個解決方案:

extension Array where Element: UIView {
    func applyChange(closure: (UIView)->()) {
        for view in self {
            view.subviews.applyChange(closure)
            closure(view)
        }
    }
}

這是一個可能的通用解決方案,它允許遍歷任何“嵌套序列”。 它不僅限於UIViewsubviews ,而是采用將每個序列元素映射到其直接子元素的參數。

它還通過返回一個可以與現有方法(如forEach()一起使用的Generator來分離遍歷序列的任務和元素上的操作 (如設置背景顏色forEach()

(這是受到Swift中為簡單樹結構實現遞歸生成器的一些答案的啟發。)

extension SequenceType {

    public func generate<S : SequenceType where S.Generator.Element == Generator.Element>
        (children children: Generator.Element -> S) -> AnyGenerator<Generator.Element> {

            var selfGenerator = self.generate()
            var childGenerator : AnyGenerator<Generator.Element>?

            return anyGenerator {
                // Enumerate all children of the current element:
                if childGenerator != nil {
                    if let next = childGenerator!.next() {
                        return next
                    }
                }

                // Get next element of self, and prepare subGenerator to enumerate its children:
                if let next = selfGenerator.next() {
                    childGenerator = children(next).generate(children: children)
                    return next
                }

                return nil
            }
    }
}

舉個例子,如果viewUIView那么

view.subviews.generate(children: { $0.subviews })

返回所有(嵌套)子視圖的(懶惰)生成器。 通過在此生成器上調用forEach() ,我們可以修改每個子視圖:

view.subviews.generate(children: { $0.subviews }).forEach {
    $0.backgroundColor = UIColor.clearColor()
}

但它也可以用於獲取包含所有嵌套子視圖的數組:

let allViews = Array(view.subviews.generate(children: { $0.subviews }))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM