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

相關文章
相關標籤/搜索