2014-10-03 93 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。我用它来解决我的问题,它效果很好!你必须修正一些事情,因为它使用了不推荐的命令,但很容易修复它。 如果你有兴趣看看这个教程。我认为你可以将它集成到你的应用程序中,然后在需要时可以轻松使用其他内容。我希望我的回答能帮助别人。