問題:接手了一個項目沒多久,今天測試提交了一個bug,算是邏輯上的bug吧。前臺收到了mqtt發送過來的一個消息,然後用UIAlertView顯示了一個彈框,上面有“加入”和“拒絕”兩個按鈕可以選擇。也就是說,用戶在某一個頁面進行着某一項操作突然彈出了一個提示框,並且我必須選其一。但是如果用戶不想現在決定,就需要隱藏這個彈窗,此時並沒有取消按鈕,所以就產生了一個需求:點擊UIAlertView的黑色背景隱藏彈窗。
之前的代碼這樣的:
UIAlertView *organizationAlert = [[UIAlertView alloc]initWithTitle:nil
message:[NSString stringWithFormat:@"尊敬的用戶,您的平臺賬號被%@邀請加入,請確認。",notifica.object]
delegate:self
cancelButtonTitle:@"拒接"
otherButtonTitles:@"加入", nil];
[kUserDefaults setObject:[NSString stringWithFormat:@"尊敬的用戶,您的平臺賬號被%@邀請加入,請確認。",notifica.object] forKey:@"NotificaObject"];
[self.organizationAlert show];
現在我想添加一個點擊事件,然後在事件裏面去dismiss彈窗。這個時候需要把organizationAlert寫成屬性。問題來了:這一切都是寫在類目裏面的!
#import "AppDelegate.h"
@interface AppDelegate (Notifies)
@end
明白了吧,在這裏添加屬性,就需要用到runtime了,這也是runtime需要用的爲數不多的應用場景:添加屬性。
下面直接放完整代碼:
①把彈窗寫成屬性
#import "AppDelegate.h"@interface AppDelegate (Notifies)
@property (nonatomic, strong) UIAlertView *organizationAlert;
@end
②添加getter setter方法
//strKey 唯一標識
static void *strKey = &strKey;
- (void)setOrganizationAlert:(UIAlertView *)organizationAlert{
objc_setAssociatedObject(self, &strKey, organizationAlert, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIAlertView *)organizationAlert{
return objc_getAssociatedObject(self, &strKey);
}
③使用
#pragma mark -- 組織邀請
-(void)organizationInvite:(NSNotification *)notifica{
self.organizationAlert = [[UIAlertView alloc]initWithTitle:nil
message:[NSString stringWithFormat:@"尊敬的用戶,您的平臺賬號被%@邀請加入,請確認。",notifica.object]
delegate:self
cancelButtonTitle:@"拒接"
otherButtonTitles:@"加入", nil];
[kUserDefaults setObject:[NSString stringWithFormat:@"尊敬的用戶,您的平臺賬號被%@邀請加入,請確認。",notifica.object] forKey:@"NotificaObject"];
[self.organizationAlert show];
//點擊背景隱藏
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tap:)];
tap.numberOfTapsRequired = 1;
tap.cancelsTouchesInView = NO;
[[UIApplication sharedApplication].keyWindow addGestureRecognizer:tap];
}
//點擊事件處理
- (void)tap:(UITapGestureRecognizer *)tap
{
if (tap.state == UIGestureRecognizerStateEnded){//下面代碼自己去理解
CGPoint location = [tap locationInView:nil];
if (![self.organizationAlert pointInside:[self.organizationAlert convertPoint:location fromView:self.organizationAlert.window] withEvent:nil]){
[self.organizationAlert.window removeGestureRecognizer:tap];
[self.organizationAlert dismissWithClickedButtonIndex:0 animated:YES];
}
}
}