在我的应用中,我必须创建一个自定义警报视图,如下所示:
因此,我按照本教程创建了一个自定义警报视图。我完成了,但是在以下方法中遇到了问题:
- (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中插入nil对象,但是我不明白出了什么问题,希望您能帮助我解决此问题。
更新这里是我开发的所有类代码:
#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
我使用CustomAlertView的UPDATE 2代码:
#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
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个特性hasOkButton
和hasCancelButton
与一个新的构造,以类似这样的自定义类:
- (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
我在一个真实的项目中尝试了您的解决方案,并通过在调用方中使用以下几行使它起作用:
- (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可见的属性hasOK
和hasCancel
in.h。并通过添加方法来修改.m:
-(void)viewWillAppear:(BOOL)animated
{
[self removeOkayButton:self.hasOK];
[self removeCancelButton:self.hasCancel];
}
确保修改情节提要(如果符合条件)以通过以下方式定义“ customAlertView”:
也不要忘记将UIButton绑定到控制器,这在您的实现中也可能是一个错误:
希望这能够帮到你 :)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句