本文將講述在iOS開發中如何根據某個UIView(前提是該UIView已經被加入到Controller中)來獲取所屬的UIViewController。javascript
作過事件響應處理的童鞋應該都或多或少聽過這個類吧,UIResponder的子類有不少好比UIView、UIViewController、UIWindow甚至是UIApplication。java
再引入一個概念叫Responder Chain,即響應用戶觸摸的一條事件處理、響應的鏈,用戶一旦接觸屏幕,這個事件就會按照這條Responder Chain傳遞下去。大概的傳遞規則就是從視圖頂層的UIView向下到UIViewController再到RootViewController再到Window最後到Application。具體如何傳遞我這裏再也不詳述,能夠參閱UIResponderui
當咱們知道UIResponder是UIView和UIViewController的父類,並且他們會經過UIResponder造成一條鏈,那麼咱們不就能夠從UIView開始順着這條鏈找到UIViewController了。this
啥也不說了直接看代碼code
extension UIView{ /** Get the controller that this view belongs to. it will return nil if there is no controller. It won't return a object of the class in arguments, just return a object of UIViewController. If you want use your class, you should use '... as? YourViewControllerClass' to convert it to the class you need. */ func viewController(aClass: AnyClass) -> UIViewController?{ for(var next=self.superview;(next != nil);next=next?.superview){ let nextResponder = next?.nextResponder() if((nextResponder?.isKindOfClass(aClass)) != nil){ return nextResponder as? UIViewController } } return nil } }
extension
這裏是Swift的提供的用於擴展某個類的寫法,這裏我擴展了UIView,爲他加上了一個viewController方法。用一個循環先找到最底層的UIView,而後經過這個最底層的UIView順着Responder chain去找該UIView的下一個nextResponder()
。因爲Responder是UIViewController的父類,咱們經過as轉換成UIViewController便可。事件
直接把上面這段代碼加入你的Swift文件中,UIView就能夠調用viewController()
來獲取他的controller了。ip