通过响应者链去获取当前控制器

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_18683985/article/details/84953183

响应者链大家应该都知道是什么玩意.

苹果文档中对响应者链有如下一段介绍

Altering the Responder Chain
You can alter the responder chain by overriding the nextResponder property of your responder objects. When you do this, the next responder is the object that you return.

Many UIKit classes already override this property and return specific objects, including:

UIView objects. If the view is the root view of a view controller, the next responder is the view controller; otherwise, the next responder is the view’s superview.

UIViewController objects.

If the view controller’s view is the root view of a window, the next responder is the window object.

If the view controller was presented by another view controller, the next responder is the presenting view controller.

UIWindow objects. The window's next responder is the UIApplication object.

UIApplication object. The next responder is the app delegate, but only if the app delegate is an instance of UIResponder and is not a view, view controller, or the app object itself.

翻译一下就是你可以通过调用nextResponder这个方法获取当前继承于UIResponder类对象的下一个响应者.有以下几种情况

1.如果当前View是Window的rootView.那么.该View的nextResponder是Window.
2.如果一个AViewController被另外一个BViewController用presented的方式展示出来的,那么下一个响应者就是BViewController.
3.UIWindow对象的下一个响应者是UIApplication对象.
如果是UIApplication对象,并且当app delegate是UIResponder的一个对象而不是UIView,UIViewControler,或app对象本身时那么他的下一个响应者是app delegate.

有了以上的知识我们就可以通过无限循环调用nextResponder的方式来获取当前控制器了.

.h
- (UIViewController *)getViewControllerWithUIView:(UIView *)currentView;

.m
- (UIViewController *)getViewControllerWithUIView:(UIView *)currentView {
    for (UIView *view = currentView; view; view = view.superview) {
        UIResponder *nextResponder = [view nextResponder];
        if ([nextResponder isKindOfClass:[UIViewController class]]) {//参考上面的第二条,需要直接return.
            return (UIViewController *)nextResponder;
        }
    }
    return nil;
}

或者咱们写一个UIView的分类后实现一个viewController方法

.h
- (UIViewController *)viewController;

.m
- (UIViewController *)viewController {
    for (UIView *view = self; view; view = view.superview) {
        UIResponder *nextResponder = [view nextResponder];
        if ([nextResponder isKindOfClass:[UIViewController class]]) {
            return (UIViewController *)nextResponder;
        }
    }
    return nil;
}

猜你喜欢

转载自blog.csdn.net/qq_18683985/article/details/84953183