2015-10-06 3 views
3

Я написал функцию, которая выполняет итерации через супервизоры данного UIView, чтобы получить ссылку на конкретный подкласс UIView, если он присутствует (в данном случае UITableView). Это прекрасно работает с использованием императивного стиля, но, похоже, это проблема, которая хорошо зарекомендовала бы себя в «Железнодорожно-ориентированном программировании». Поскольку я все еще чувствую свою функциональность, может ли кто-нибудь предложить более элегантную функциональную версию этой функции?Поиск иерархии UIView с использованием функционального Swift

func findTableView(var view: UIView) -> UITableView? { 
    var table: UITableView? = nil 
    while table == nil { 
     guard let superView = view.superview else { return nil } 
     view = superView 
     table = view as? UITableView 
    } 
    return table 
} 

ответ

5

Как это?

func findTableView(view: UIView) -> UITableView? { 
    return view as? UITableView ?? view.superview.flatMap(findTableView) 
} 

Этот код просто укороченный из:

func findTableView(view: UIView) -> UITableView? { 
    if let tableView = view as? UITableView { 
     return tableView 
    } 
    else { 
     let superview = view.superview 
     if superview == nil { 
      return nil 
     } 
     else { 
      return findTableView(superview!) 
     } 
    } 
} 

Использование "Nil Coalescing Operator" и flatMap(_:) методом на Optional перечислении.

+0

Вот и все! Я знал, был бы более кратким. Я не думаю, что вы могли бы разобраться в этом? У меня есть небольшая концептуальная проблема, понимающая, что делает код. – rustproofFish

+0

Обновлен ответ. – rintaro

+0

Спасибо! Очевидно, когда вы видите расширенную версию. Использование flatmap() меня сбило с толку, но теперь я понимаю, что это довольно хитрый способ справиться с ноль-событием, когда у вас заканчиваются супервизоры. – rustproofFish

2

Edit: Это для поиска через подразделам взглядов не супер вида

Вы можете попробовать рекурсивный функциональный подход без некоторого времени. Не знаю, это то, что вы ищете.

func findTableView(view: UIView) -> UITableView? { 
    if view is UITableView { 
     return view as? UITableView 
    } else { 
     for subview in view.subviews { 
      if let res = findTableView(subview) { 
       return res 
      } 
     } 
    } 
    return nil 
} 

Edit 2 + 3: Сделано функция проще

+0

я на самом деле думаю о том, что, как проблема, казалось бы, поддается хорошо к нему, но я нашел это на самом деле сделал мой код немного громоздким и труднее читать. Я думал, что могу использовать рекурсивный «конвейер», если это имеет смысл: получить супервизор -> если нет представления, выйти с нулем в противном случае) -> если в противном случае повторить возврат супервизора. Я не уверен, поняла ли я себя, поскольку я не придерживаюсь терминологии. Спасибо за предложение, хотя – rustproofFish

+0

О, я просто понял, что вы хотите найти «вверх», а не «вниз» – eyeballz

+0

Нет проблем :-) Спасибо в любом случае – rustproofFish

2

Swift find superview of given class with generics

Swift 3

extension UIView { 

    func superview<T>(of type: T.Type) -> T? { 
     return superview as? T ?? superview.flatMap { $0.superview(of: type) } 
    } 

    func subview<T>(of type: T.Type) -> T? { 
     return subviews.flatMap { $0 as? T ?? $0.subview(of: type) }.first 
    } 

} 

Использование:

let tableView = someView.superview(of: UITableView.self) 
let tableView = someView.subview(of: UITableView.self) 
Смежные вопросы