Skip to content

Instantly share code, notes, and snippets.

@Juanpe
Last active December 17, 2018 08:20
Show Gist options
  • Save Juanpe/96b5c7e37d5e57e44fd8270ba3134865 to your computer and use it in GitHub Desktop.
Save Juanpe/96b5c7e37d5e57e44fd8270ba3134865 to your computer and use it in GitHub Desktop.
extension Collection where Element: UIView {
/// Returns an array containing, in order, the views of the sequence that satisfy the given predicate.
///
/// - Parameters:
/// - recursive: Boolean that indicates if filtering recursively
/// - isIncluded: A closure that takes a view of the sequence as its argument and returns a Boolean value indicating whether the view should be included in the returned array.
/// - Returns: An array of the views that isIncluded allowed.
func filter(recursive: Bool = false, _ isIncluded: (UIView) -> Bool) -> [UIView] {
return reduce(into: []) { partialResult, view in
if isIncluded(view) {
partialResult.append(view)
}
if recursive, !view.subviews.isEmpty {
let filteredSubviews = view.findSubviews(recursive: recursive, isIncluded)
partialResult.append(contentsOf: filteredSubviews)
}
}
}
}
extension UIView {
/// Returns an array containing, in order, the subviews that satisfy the given predicate.
///
/// - Parameters:
/// - recursive: Boolean that indicates if filtering the subviews
/// - isIncluded: A closure that takes a subview as its argument and returns a Boolean value indicating whether the view should be included in the returned array.
/// - Returns: An array of the views that isIncluded allowed.
func findSubviews(recursive: Bool = false, _ isIncluded: (UIView) -> Bool) -> [UIView] {
return subviews.filter(recursive: recursive, isIncluded)
}
}
@theblixguy
Copy link

You can simplify it further:

extension UIView {
  func subviews(recursively: Bool = false) -> [UIView] {
    guard recursively else { return subviews }
    return subviews.flatMap { [$0] + $0.subviews(recursively: true) }
  }
  
  func subviews(recursively: Bool = false, satisfy: (UIView) -> Bool) -> [UIView] {
    return subviews(recursively: recursively).filter(satisfy)
  }
}

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