題目:找出兩個 UIView 的最近的公共 View,如果不存在,則輸出 nil 。
分析:這其實是數據結構里面的找最近公共祖先的問題。
一個 UIViewController 中的所有 view 之間的關系其實可以看成一顆樹,UIViewController 的 view 變量是這顆樹的根節點,其它的 view 都是根節點的直接或間接子節點。
所以我們可以通過 view 的 superview 屬性,一直找到根節點。需要注意的是,在代碼中,我們還需要考慮各種非法輸入,如果輸入了 nil,則也需要處理,避免異常。以下是找到指定 view 到根 view 的路徑代碼:
extension UIView{ func superViews() ->[UIView]?{ guard let superV = superview else { return nil } var arr : [UIView]? = [] var teamView:UIView? = superV while teamView != nil { arr?.append(teamView!) teamView = teamView?.superview } return arr } }
對於兩個VIew她們的第一個公共父視圖以后的父視圖就都一樣了,所以view1的從最近的父視圖開始遍歷如果也屬於view2的父視圖數組中那么就是了
func commonView(view1:UIView,view2:UIView) -> UIView? { guard let arr1 = view1.superViews(),let arr2 = view2.superViews() else { return nil } return arr1.first { arr2.contains($0)} }
還可以使用isDescendant利用遞歸思想解決此問題
func commonSuperview(of view: UIView) -> UIView? { if let s = superview { if view.isDescendant(of: s) { return s } else { return s.commonSuperview(of: view) } } return nil }