ios alertview在ios7后的操做

hello,你们好,在老项目上都用的是UIalertview,最近项目上有个bug,是长时间不操做的话要登出处理,但画面上若有alertview的话,不会消失,会留在画面上。这个问题之前好处理,获取画面上alertview的引用,dismiss就ok了。可是呢,ios7后就获取不到了。详情看这个https://blog.csdn.net/xundh/article/details/46546739ios

项目里alertview不少不少。一个一个改能改到猴年马月去。后找到一个很方便的办法。spa

#import <UIKit/UIKit.h>

@interface UIAlertView (Dismiss)

+ (void)dismissAllVisibleAlertViews;

@end

#import "UIAlertView+Dismiss.h"
#import <objc/runtime.h>

// see http://nshipster.com/method-swizzling/
static inline void swizzle(Class class, SEL originalSelector, SEL swizzledSelector)
{
    Method originalMethod = class_getInstanceMethod(class, originalSelector);
    Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
    
    BOOL didAddMethod =
    class_addMethod(class,
                    originalSelector,
                    method_getImplementation(swizzledMethod),
                    method_getTypeEncoding(swizzledMethod));
    
    if (didAddMethod) {
        class_replaceMethod(class,
                            swizzledSelector,
                            method_getImplementation(originalMethod),
                            method_getTypeEncoding(originalMethod));
    } else {
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
}
@implementation UIAlertView (Dismiss)

+ (void)load
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        swizzle([self class], @selector(show), @selector(replace_show));
        swizzle([self class], @selector(dismissWithClickedButtonIndex:animated:), @selector(replace_dismissWithClickedButtonIndex:animated:));
    });
}

+ (void)dismissAllVisibleAlertViews
{
     NSMutableSet *tempset = [[NSMutableSet alloc] initWithSet:[[self visibleAlertViews] copy]];
    //[[self visibleAlertViews] copy];
    for (NSValue *value in tempset)
    {
        id val = value.nonretainedObjectValue;
        
        if ([val isKindOfClass: [UIAlertView class]])
        {
            [val dismissWithClickedButtonIndex: 0 animated: NO];
        }
    }
    [tempset removeAllObjects];
    tempset = nil;
}

#pragma mark - Method Swizzling

- (void)replace_show
{
    [self replace_show];
    
    [[self.class visibleAlertViews] addObject: [NSValue valueWithNonretainedObject: self]];
}
- (void)replace_dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated
{   //[[self.class visibleAlertViews] removeObject: [NSValue valueWithNonretainedObject: self]];
    [self replace_dismissWithClickedButtonIndex: buttonIndex animated: animated];
    NSLog(@">>>>>>>xxx_dismissWithClickedButtonIndex");
    [[self.class visibleAlertViews] removeObject: [NSValue valueWithNonretainedObject: self]];
}

#pragma mark - Cache

+ (NSMutableSet *)visibleAlertViews
{
    static NSMutableSet *views = nil;
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        views = [NSMutableSet new];
    });
    
    return views;
}

@end

就是这个了。运行时替换的alertview的show和dismiss方法。作了一些处理。.net

在个人项目里就用+ (void)dismissAllVisibleAlertViews;这个静态方法dismiss画面上的alertview。各位有维护老项目的可参考参考,很实用。code

至于swizzling的原理,百度上有不少。https://blog.csdn.net/yiyaaixuexi/article/details/9374411blog

相关文章
相关标签/搜索