2015-10-06 47 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"Optional枚舉flatMap(_:)方法。

+0

就是這樣!我知道如果會更簡潔。我不認爲你能詳細說明這一點嗎?我有一個輕微的概念性問題,理解代碼正在做什麼。 – rustproofFish

+0

更新了答案。 – rintaro

+0

謝謝!當您看到擴展版本時顯而易見。 flatmap()的使用令我感到困惑,但現在我意識到,當您用完超級視圖時,這是一種處理零事件的非常狡猾的方式。 – rustproofFish

2

編輯:這是通過意見不超級意見

你可以嘗試不用而遞歸函數的方式進行搜索。不知道這是你在找什麼。

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 
} 

編輯2 + 3:所做的功能簡單

+0

其實我覺得這是問題,似乎借給自己很好的,但我發現它實際上使我的代碼稍微笨重,難以閱讀。我在想,如果這是有道理的,我可以使用遞歸'管道':get superview - >如果沒有視圖,否則退出nil) - >如果superview返回superview,否則重複。我不確定自己是否清楚,因爲我沒有掌握術語。感謝您的建議,雖然 – rustproofFish

+0

哦,我只是意識到你想搜索「up」而不是「down」 – eyeballz

+0

沒問題:-)無論如何感謝 – rustproofFish

2

Swift find superview of given class with generics

斯威夫特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)