0

I use to find specific views within a parent usually like:

let label: UILabel? = view.subviews.filter {$0 is UILabel}.first

I would like to create a function that would take a type or an object of a certain type and return a view within the parent's subviews that corresponds with the type. Something along the lines of:

extension UIView {
    func findView(byType type: <Some Type or UIView object?>() -> UIView? {
        return self.subviews.filter {$0 is <The type>}.first
    }
}

// Usage
if let myLabel = view.findView(byType: <*UILabel.Type* or UILabel()>) { ... }

But I can't figure out how to do it, I tried looking up the topic, but I'm afraid my knowledge of Swift is limiting me on this one.
How can I achieve this?

Eilon
  • 2,698
  • 3
  • 16
  • 32
  • Could be helpful https://stackoverflow.com/a/39603570/2907715 – ielyamani Sep 01 '19 at 22:36
  • @ielyamani No, that's not relevant at all. – rmaddy Sep 01 '19 at 22:42
  • It's good to learn to do this kind of stuff but instead of searching through the subviews of a view you should retain ownership of the views, either by storing them in variables when you create them or by assigning them to IBOutlets. – EmilioPelaez Sep 01 '19 at 23:21

1 Answers1

1

You can create an extension like this :

extension UIView {
    func findView<T>(byType type: T.Type) -> T? {
       return self.subviews.filter {$0 is T}.first as? T
    }
}

Now you can use it like view.findView(byType: UIButton.self)

As @LeoDabus pointed out, a better extension would be :

func findView<T>(byType type: T.Type) -> T? {
    return subviews.first { $0 is T } as? T
}
May Rest in Peace
  • 2,070
  • 2
  • 20
  • 34
  • 2
    This will unnecessarily loop the whole collection of subviews. You can use collection method first where `subviews.first { $0 is T } as? T` – Leo Dabus Sep 01 '19 at 22:44
  • @LeoDabus That's a better solution. Will update the answer. Thanks. – May Rest in Peace Sep 01 '19 at 23:12
  • Works great, thanks. It just didn't quite make sense to me using a parameter that you don't actually use anywhere within the function. I assume you could also define the function as `findView(byType _: T.Type) -> T?`? – Eilon Sep 02 '19 at 06:08