Skip to content

Instantly share code, notes, and snippets.

@isoiphone
Last active April 26, 2016 07:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save isoiphone/c729437bfaa10e4450ea to your computer and use it in GitHub Desktop.
Save isoiphone/c729437bfaa10e4450ea to your computer and use it in GitHub Desktop.
extension UIView {
func forEachSubviewOfType<V: UIView>(type: V.Type, @noescape apply block: V -> Void) {
for view in subviews {
if let view = view as? V {
block(view)
} else {
view.forEachSubviewOfType(V.self, apply: block)
}
}
}
}
searchController.searchBar.forEachSubviewOfType(UITextField.self) { textField in
textField.textColor = .whiteColor()
}
@JessyCatterwaul
Copy link

Edit: Hah! iosdevzone chimed in while I was away and said something very similar.

I think you should split up the mapping logic and the forEach logic. Then you can recur over anything you like.

extension SequenceType  {
   /// Recursively map, and stop recurring at the first non-nil element in a branch
   ///
   ///- Parameter recursed: the next level of children
   ///- Parameter map: transform the non-nil elements
   func flatMapped<Mapped>(
      @noescape recursed recursed: Generator.Element -> Self,
      @noescape _ map: Generator.Element -> Mapped?
   ) -> [Mapped] {
      return reduce([]){
         if let mapped = map($1) {return $0 + [mapped]}
         return $0 + recursed($1).flatMapped(recursed: recursed, map)
      }
   }
}


UISearchBar().subviews.flatMapped(recursed: {$0.subviews}){$0 as? UITextField}
.forEach{$0.textColor = .whiteColor()}


struct Branch {
   let datum: Int
   let branches: [Branch]
}

let branch1 = Branch(datum: 1, branches: [])
let branch2 = Branch(datum: 2, branches: [branch1])
let branch3 = Branch(datum: 3, branches: [branch2])

let branches = [branch1, branch2, branch3].flatMapped(recursed: {$0.branches})
{$0.datum < 2 ? $0 : nil}

// branch1, thrice
branches

Here's iosdevzone's code as an extension:

extension SequenceType  {
   func recursed(recursed: Generator.Element -> Self) -> [Generator.Element] {
      return flatMap{[$0] + recursed($0).recursed(recursed)}
   }
}

UISearchBar().subviews.recursed{$0.subviews}.flatMap{$0 as? UITextField}
.forEach{$0.textColor = .whiteColor()}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment