iOSのは、イベントにし、ビュー階層チェーンに応じて、ベースの流れ

  それがグローバルであるので、その後、彼は合わなかったので、層を横断することはできませんが、通知をするので、プロキシを使用して、プロジェクトチーム、そしてより多くのネストされたUI階層、UIのインタラクション、イベント配信、など。ページには時間が表示されない場合は、そこにトリガーイベントで、かつ使用して完成も削除する必要があるかもしれません。私は期待に沿ったもので、ここではないです。反射に最新の、最も最近いくつかのアイデアで、そしてあなたと共有します。

応答チェーンのトップイベントからのイベントに基づいて、下位層に転写

  無視された場合、プロセスはその後窓層まで下位層に転送、処理することができる場合にメインイベントは、nextResponder介してイベントを処理するかどうかを決定するために同時に送られます。もちろん、イベントへの応答であれば、だけでなく、イベントは、下位層に渡されることができます。

ビュー階層下から上へ、イベントを渡し、UIをベース

  ビューの開始、イベントを送信、イベントはそのすべての子ビュービューの納入範囲に限定されています。対応するサブビューがプロトコルに準拠している場合、イベントの配信が来て、対応する処理ロジックは、もちろん、場合イベントが一つだけのサブビュー処理時間を必要とし、その後処理、結果は、その後の終了イベントのうち戻すことができます転送。
具体的なコードは次のよう:


typedef NS_ENUM(NSInteger, JKUIEventResult)
{
 JKUIEventResultIgnore = 0,       /// 忽略事件,事件会继续传递,直到结束
 JKUIEventResultHandle,           /// 响应事件,阻止事件继续传递
 JKUIEventResultHandleDelivery    /// 响应事件,并让事件继续传递
}; /// 事件处理结果

@protocol JKUIEventProtocol <NSObject>

@optional

/// 接收到链式事件
/// @param eventName 事件名称
/// @param data 数据
- (JKUIEventResult)jk_receiveChainEvent:(nonnull NSString *)eventName
                        data:(nullable id)data;

/// 接收广播事件
/// @param eventName 事件名称
/// @param data 数据
- (JKUIEventResult)jk_receiveBroadcastEvent:(nonnull NSString *)eventName
                            data:(nullable id)data;

@end
@interface JKUIEventHandler : NSObject

/// 发送链式事件,事件根据响应链朝着对应的VC层级传递
/// @param eventName 事件名称
/// @param data 数据
/// @param responder 响应者
+ (void)sendChainEvent:(nonnull NSString *)eventName
                  data:(nullable id)data
             responder:(nonnull __kindof UIResponder *)responder;

/// 广播事件,事件根据视图层级,从responder层朝着顶层传递
/// @param eventName 事件名称
/// @param data 数据
/// @param responder 响应者
+ (void)broadcastEvent:(nonnull NSString *)eventName
                  data:(nullable id)data
             responder:(nonnull __kindof UIResponder *)responder;

@end

#import "JKUIEventHandler.h"
#import "JKUIEventProtocol.h"

@implementation JKUIEventHandler

+ (void)sendChainEvent:(nonnull NSString *)eventName
                  data:(nullable id)data
             responder:(nonnull __kindof UIResponder *)responder
{
#if DEBUG
    NSAssert(eventName, @"eventName can't be nil");
    NSAssert(responder, @"responder can't be nil");
    NSAssert([responder isKindOfClass:[UIResponder class]], @"make sure [responder isKindOfClass:[UIResponder class]] be YES");
#endif
    if (!eventName) {
        return;
    }
    if (!responder) {
        return;
    }
    if (![responder isKindOfClass:[UIResponder class]]) {
        return;
    }
    UIResponder <JKUIEventProtocol>*currentResponder = (UIResponder <JKUIEventProtocol>*)responder.nextResponder;
    while (currentResponder
           && ![currentResponder isKindOfClass:[UIWindow class]]
           && ![currentResponder isKindOfClass:[UIApplication class]]) {
        if ([currentResponder conformsToProtocol:@protocol(JKUIEventProtocol)]) {
            if ([currentResponder respondsToSelector:@selector(jk_receiveChainEvent:data:)]) {
                JKUIEventResult result = [currentResponder jk_receiveChainEvent:eventName data:data];
                if (result == JKUIEventResultHandleDelivery) {// 事件继续传递
                   currentResponder = (UIResponder <JKUIEventProtocol>*)currentResponder.nextResponder;
                } else {
                    break;
                }
            } else {
               currentResponder = (UIResponder <JKUIEventProtocol>*)currentResponder.nextResponder;
            }
        } else {
            currentResponder = (UIResponder <JKUIEventProtocol>*)currentResponder.nextResponder;
        }
    }
}


+ (void)broadcastEvent:(nonnull NSString *)eventName
                  data:(nullable id)data
             responder:(nonnull __kindof UIResponder *)responder
{
    #if DEBUG
        NSAssert(eventName, @"eventName can't be nil");
        NSAssert(responder, @"responder can't be nil");
        NSAssert([responder isKindOfClass:[UIResponder class]], @"make sure [responder isKindOfClass:[UIResponder class]] be YES");
    #endif
        if (!eventName) {
            return;
        }
        if (!responder) {
            return;
        }
        if (![responder isKindOfClass:[UIResponder class]]) {
            return;
        }
        
    if ([responder isKindOfClass:[UIViewController class]]) {
        __kindof UIViewController <JKUIEventProtocol>*responderVC = (__kindof UIViewController <JKUIEventProtocol>*)responder;
        if ([responderVC conformsToProtocol:@protocol(JKUIEventProtocol)]
            && [responderVC respondsToSelector:@selector(jk_receiveBroadcastEvent:data:)]) {
            JKUIEventResult result = [responderVC jk_receiveBroadcastEvent:eventName data:data];
            if (result == JKUIEventResultHandle) { // 事件停止继续广播
                return;
            }
        }
        if (responderVC.childViewControllers.count > 0) {
            for (__kindof UIViewController *childVC in responderVC.childViewControllers) {
               [self broadcastEvent:eventName data:data responder:childVC];
            }
        }
        
        __kindof UIView <JKUIEventProtocol>*view = (__kindof UIView <JKUIEventProtocol>*)responderVC.view;
        if ([view conformsToProtocol:@protocol(JKUIEventProtocol)]
            && [view respondsToSelector:@selector(jk_receiveBroadcastEvent:data:)]) {
            JKUIEventResult result = [view jk_receiveBroadcastEvent:eventName data:data];
            if (result == JKUIEventResultHandle) { // 事件停止继续广播
                return;
            }
        }
        if (responderVC.view.subviews.count > 0) {
            for (__kindof UIView *subview in responderVC.view.subviews) {
                [self broadcastEvent:eventName data:data responder:subview];
            }
        }
    } else if([responder isKindOfClass:[UIView class]]) {
        __kindof UIView <JKUIEventProtocol>*view = (__kindof UIView <JKUIEventProtocol>*)responder;
        if ([view conformsToProtocol:@protocol(JKUIEventProtocol)]
            && [view respondsToSelector:@selector(jk_receiveBroadcastEvent:data:)]) {
            JKUIEventResult result = [view jk_receiveBroadcastEvent:eventName data:data];
            if (result == JKUIEventResultHandle) {// 事件停止继续广播
                return;
            }
        }
        if (view.subviews.count > 0) {
            for (__kindof UIView *subview in view.subviews) {
                [self broadcastEvent:eventName data:data responder:subview];
            }
        }
    }
}
@end

ソースのダウンロード
ポッド統合

pod 'JKUIEventHandler'

批判と共通の進歩の多くにようこそ。

さらに記事は、物品を乾燥国民の関心のコード番号を掃引することを歓迎します

書き込み絵は、ここで説明しました

231元記事公開 ウォンの賞賛110 ビューに60万+を

おすすめ

転載: blog.csdn.net/HHL110120/article/details/104055352