Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Looping through UIButtons in UIView

Tags:

loops

ios

swift

I have my setup as followed:

UIView(1) -> UIScrollview -> UIStackview -> UIViews(2) -> UIButton

How to loop through every UIButton in all the UIViews(2) in the UIStackview? I got more buttons in my UIView(1) so I can not loop through every button in the whole Viewcontroller. I tried:

for view in self.stackview.subviews as [UIView] {
    if let btn = view as? UIButton {
        print("Worked")
    }
}
for view in self.scrollview.subviews as [UIView] {
    if let btn = view as? UIButton {
        print("Worked")
    }
}
for case let button as UIButton in self.scrollview.subviews {
    print("worked")
}
for case let button as UIButton in self.stackview.subviews {
    print("worked")
}

It just don't prints anything when trying to add this in my viewDidLoad function. What am I doing wrong here?

like image 373
Petravd1994 Avatar asked Dec 23 '22 20:12

Petravd1994


2 Answers

The first solution that comes in mind:

let buttons = self.stackview.subviews // direct subviews of stack view
    .map { subview in subview.subviews } // second level subviews
    .joined() // join the second level subviews into one flat array
    .compactMap { $0 as? UIButton } // filter buttons

Basically you are only forgetting to jump to the second level. You are iterating only the first level subviews.

If you want a more stable solution, you can iterate recursively over the subviews in any depth, e.g. using a category:

extension UIView {
    var allSubviews: [UIView] {
        return self.subviews + self.subviews.map { $0.allSubviews }.joined()
    }
}

and then

let buttons = self.stackview.allSubviews.compactMap { $0 as? UIButton }
like image 78
Sulthan Avatar answered Jan 11 '23 18:01

Sulthan


How about…

for view in stackView.subviews {
    for case let button as UIButton in view.subviews {
        print(button.title(for: .normal)) // Do something with button
    }
}

or

for case let button as UIButton in stackView.subviews.flatMap({ $0.subviews }) {
    print(button.title(for: .normal))  // Do something with button
}

or

for button in stackView.subviews.flatMap({ $0.subviews }).flatMap({ $0 as? UIButton }) {
    print(button.title(for: .normal))  // Do something with button
}
like image 35
Ashley Mills Avatar answered Jan 11 '23 18:01

Ashley Mills