2014-10-03 77 views
0

自定義警報視圖在我的應用我已經創建像下面這樣的自定義警報視圖:在iOS的問題

enter image description here

所以我跟着這個tutorial創建自定義警報視圖。我做完了,但我發現問題如下方法:

- (void)addOrRemoveButtonWithTag:(int)tag andActionToPerform:(BOOL)shouldRemove { 
    NSMutableArray *items = [[NSMutableArray alloc]init]; 

    [items addObject:self.buttonOk]; 
    [items addObject:self.buttonClose]; 

    int buttonIndex = (tag == 1); 

    if (shouldRemove) { 
     [items removeObjectAtIndex:buttonIndex]; 
    } else { 
     if (tag == 1) { 
      [items insertObject:self.buttonOk atIndex:buttonIndex]; 
     } else { 
      [items insertObject:self.buttonClose atIndex:buttonIndex]; 
     } 
    } 
} 

我編輯它比教程,因爲我不需要對按鈕的UIToolBar。當我運行應用程序時,它說我不能在NSMutableArray中插入一個零對象,但我不明白什麼是錯,我希望你能幫我解決這個問題。

UPDATE 這裏就是我開發的類代碼:

#import "CustomAlertViewController.h" 

#define ANIMATION_DURATION 0.25 

@interface CustomAlertViewController() 
- (IBAction)buttonOk:(UIButton *)sender; 
- (IBAction)buttonCancel:(UIButton *)sender; 
@property (weak, nonatomic) IBOutlet UIButton *buttonClose; 
@property (weak, nonatomic) IBOutlet UIButton *buttonOk; 

@property (strong, nonatomic) IBOutlet UIView *viewAlert; 

-(void)addOrRemoveButtonWithTag:(int)tag andActionToPerform:(BOOL)shouldRemove; 

@end 

@implementation CustomAlertViewController 

- (id)init 
{ 
    self = [super init]; 
    if (self) { 
     [self.viewAlert setFrame:CGRectMake(self.labelAlertView.frame.origin.x, 
             self.labelAlertView.frame.origin.y, 
             self.labelAlertView.frame.size.width, 
             self.viewAlert.frame.size.height)]; 
     [self.buttonOk setTag:1]; 
     [self.buttonClose setTag:0]; 
    } 
    return self; 
} 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view from its nib. 
} 

- (void)didReceiveMemoryWarning { 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

- (void)showCustomAlertInView:(UIView *)targetView withMessage:(NSString *)message { 
    CGFloat statusBarOffset; 

    if (![[UIApplication sharedApplication] isStatusBarHidden]) { 
     CGSize statusBarSize = [[UIApplication sharedApplication] statusBarFrame].size; 
     if (statusBarSize.width < statusBarSize.height) { 
      statusBarOffset = statusBarSize.width; 
     } else { 
      statusBarOffset = statusBarSize.height; 
     } 
    } else { 
     statusBarOffset = 0.0; 
    } 
    CGFloat width, height, offsetX, offsetY; 

    if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeLeft || 
     [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeRight) { 
     width = targetView.frame.size.width; 
     height = targetView.frame.size.height; 

     offsetX = 0.0; 
     offsetY = -statusBarOffset; 
    } 

    [self.view setFrame:CGRectMake(targetView.frame.origin.x, targetView.frame.origin.y, width, height)]; 
    [self.view setFrame:CGRectOffset(self.view.frame, offsetX, offsetY)]; 
    [targetView addSubview:self.view]; 

    [self.viewAlert setFrame:CGRectMake(0.0, -self.viewAlert.frame.size.height, self.viewAlert.frame.size.width, self.viewAlert.frame.size.height)]; 

    [UIView beginAnimations:@"" context:nil]; 
    [UIView setAnimationDuration:ANIMATION_DURATION]; 
    [UIView setAnimationCurve:UIViewAnimationCurveEaseOut]; 
    [self.viewAlert setFrame:CGRectMake(0.0, 0.0, self.viewAlert.frame.size.width, self.viewAlert.frame.size.height)]; 
    [UIView commitAnimations]; 

    [self.labelAlertView setText:@"CIAO"]; 
} 

- (void)removeCustomAlertFromView { 
    [UIView beginAnimations:@"" context:nil]; 
    [UIView setAnimationDuration:ANIMATION_DURATION]; 
    [UIView setAnimationCurve:UIViewAnimationCurveEaseOut]; 
    [self.viewAlert setFrame:CGRectMake(0.0, -self.viewAlert.frame.size.height, self.viewAlert.frame.size.width, self.viewAlert.frame.size.height)]; 
    [UIView commitAnimations]; 

    [self.view performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:ANIMATION_DURATION]; 
} 

- (void)removeCustomAlertFromViewInstantly { 
    [self.view removeFromSuperview]; 
} 

- (BOOL)isOkayButtonRemoved { 
    if (self.buttonOk == nil) { 
     return YES; 
    } else { 
     return NO; 
    } 
} 

- (BOOL)isCancelButtonRemoved { 
    if (self.buttonClose == nil) { 
     return YES; 
    } else { 
     return NO; 
    } 
} 

- (void)removeOkayButton:(BOOL)shouldRemove { 
    if ([self isOkayButtonRemoved] != shouldRemove) { 
     [self addOrRemoveButtonWithTag:1 andActionToPerform:shouldRemove]; 
    } 
} 

- (void)removeCancelButton:(BOOL)shouldRemove { 
    if ([self isCancelButtonRemoved] != shouldRemove) { 
     [self addOrRemoveButtonWithTag:0 andActionToPerform:shouldRemove]; 
    } 
} 

- (void)addOrRemoveButtonWithTag:(int)tag andActionToPerform:(BOOL)shouldRemove { 
    NSMutableArray *items = [[NSMutableArray alloc]init]; 

    [items addObject:self.buttonOk]; 
    [items addObject:self.buttonClose]; 

    int buttonIndex = (tag == 1); 

    if (shouldRemove) { 
     [items removeObjectAtIndex:buttonIndex]; 
    } else { 
     if (tag == 1) { 
      [items insertObject:self.buttonOk atIndex:buttonIndex]; 
     } else { 
      [items insertObject:self.buttonClose atIndex:buttonIndex]; 
     } 
    } 
} 

- (IBAction)buttonOk:(UIButton *)sender { 
    [self.delegate customAlertOk]; 
} 

- (IBAction)buttonCancel:(UIButton *)sender { 
    [self.delegate customAlertCancel]; 
} 
@end 

更新2 代碼中,我使用CustomAlertView:

#import "PromotionsViewController.h" 
#import "CustomAlertViewController.h" 

@interface PromotionsViewController() <CustomAlertViewControllerDelegate> { 
    BOOL isDeletingItem; 
} 


@property(nonatomic,strong) CustomAlertViewController *customAlert; 

- (IBAction)buttonBack:(UIButton *)sender; 
@property (weak, nonatomic) IBOutlet UIButton *buttonAlert; 
- (IBAction)buttonAlert:(UIButton *)sender; 

@end 

@implementation PromotionsViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view. 
    [self.buttonAlert setTitle:self.promotionSelected forState:UIControlStateNormal]; 
    [self.customAlert setDelegate:self]; 
    isDeletingItem = NO; 
} 

- (void)didReceiveMemoryWarning { 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

- (IBAction)buttonBack:(UIButton *)sender { 
    [self dismissViewControllerAnimated:YES completion:nil]; 
} 
- (IBAction)buttonAlert:(UIButton *)sender { 
    self.customAlert = [[CustomAlertViewController alloc]init]; 
    [self.customAlert removeOkayButton:NO]; 
    [self.customAlert removeCancelButton:NO]; 
    NSString *message = [NSString stringWithFormat:@"La tua offerta %@ del 20%% è stata convertita in punti IoSi x10", self.promotionSelected]; 
    [self.customAlert showCustomAlertInView:self.view withMessage:message]; 
    isDeletingItem = YES; 
} 

- (void)customAlertOk { 
    if (isDeletingItem) { 
     [self.customAlert removeCustomAlertFromViewInstantly]; 
    } else { 
     [self.customAlert removeCustomAlertFromView]; 
    } 
} 

- (void)customAlertCancel { 
    [self.customAlert removeCustomAlertFromView]; 
    if (isDeletingItem) { 
     isDeletingItem = NO; 
    } 
} 

@end 
+1

你如何初始化你的兩個按鈕? – KIDdAe 2014-10-03 14:53:53

+0

我剛剛按照教程,我通過使用Interface Builder設計了2個按鈕 – lucgian841 2014-10-03 14:57:08

回答

2

也許你在打電話addOrRemoveButtonWithTag:andActionToPerform:因爲UI元素是異步創建的,因此您的UI未完全創建。因此,如果您在自定義警報視圖實例之後調用此方法,則會因爲未創建視圖中的按鈕而導致崩潰。

要解決此問題,只有在您的自定義警報添加到視圖層次結構後,才需要致電addOrRemoveButtonWithTag:andActionToPerform:

編輯:

與您編輯2給的例子代碼,你可以調用這些行:

- (IBAction)buttonAlert:(UIButton *)sender { 
    self.customAlert = [[CustomAlertViewController alloc]init]; 
    [self.customAlert removeOkayButton:NO]; 
    [self.customAlert removeCancelButton:NO]; 
} 

但是當你剛纔實例CustomAlertViewController,它的2個按鈕都沒有創建,所以我建議你添加2個屬性hasOkButtonhasCancelButton和一個新的構造函數到你的自定義類像這樣:

- (instancetype) initWithOk:(BOOL)OkButton AndCancel:(BOOL) CancelButton 
{ 
    if(self = [super init]) 
    { 
     hasOkButton = OkButton; 
     hasCancelButton = CancelButton; 
    } 
} 

-(void)viewWillAppear:(BOOL)animated 
{ 
     [super viewWillAppear:animated]; 
     // At this time, the custom UI buttons will be created in the UI view hierarchy 
     [self removeOkayButton: hasOkButton]; 
     [self removeOkayButton: hasCancelButton]; 
} 

而且在來電者可以使用以下方法來顯示自定義的警報視圖:

- (IBAction)buttonAlert:(UIButton *)sender { 
    self.customAlert = [[CustomAlertViewController alloc] initWithOk:NO AndCancel:NO]; 
    // ... 
} 

編輯#2

我想在一個真正的項目解決方案,我做了它通過使用這些線路工作int來電者:

- (IBAction)buttonAlert:(UIButton *)sender { 
    self.customAlert = [self.storyboard instantiateViewControllerWithIdentifier:@"customAlertView"]; 
    self.customAlert.hasOK = NO; 
    self.customAlert.hasCancel = YES; 
    NSString *message = [NSString stringWithFormat:@"La tua offerta %@ del 20%% è stata convertita in punti IoSi x10", self.promotionSelected]; 
    [self.customAlert showCustomAlertInView:self.view withMessage:message]; 
    isDeletingItem = YES; 
} 

CustomAlertViewController聲明2可見屬性hasOKhasCancel in.h. 並修改你的。米乘加入方法:

-(void)viewWillAppear:(BOOL)animated 
{ 
    [self removeOkayButton:self.hasOK]; 
    [self removeCancelButton:self.hasCancel]; 
} 

一定要修改你的故事板(如符合資格)有「customAlertView」這樣定義的:

Screen capture of storyboard properties

也不要忘了你的UIButton綁定控制器這可能是一個錯誤太的實現:

Bind UIButtons to the controller

希望ŧ他會幫助你:)

+0

我剛剛添加了所有我在我的CustomAlertViewController.m中插入的代碼,我希望你能幫我找出我的錯誤在哪裏 – lucgian841 2014-10-03 15:02:00

+0

@ lucgian841你能添加插入新的CustomAlertViewController的代碼?我認爲你只是調用方法addOrRemoveButtonWithTag:andActionToPerform:太快...導致你的崩潰 – cdescours 2014-10-03 15:08:36

+0

我更新我的問題,通過添加我調用CustomAlertView的代碼 – lucgian841 2014-10-03 15:12:26

0

我在網上找到了一個使用代碼創建自定義警報視圖的教程,如果你有興趣,你可以去tutorial。我用它來解決我的問題,它效果很好!你必須修正一些事情,因爲它使用了不推薦的命令,但很容易修復它。 如果你有興趣看看這個教程。我認爲你可以將它集成到你的應用程序中,然後在需要時可以輕鬆使用其他內容。我希望我的回答能幫助別人。