自定义警报通知 iOS

Custom Alert Notify iOS

对于我的 iOS 应用程序,我创建了一个具有 "Custom Notifications" 功能的自定义 UIView。

一切正常,但我有一个问题,我希望通知只出现一次。简而言之,我的案例研究是,如果我多次单击弹出通知的按钮,后者将无限期重叠,相反,如果按钮,我(可能通过使用布尔值)也能够弹出一次性通知被按了几次...

您能建议实现此目标的最佳方法吗?

自定义视图是这样呈现在外部视图控制器中的

-(IBAction)loginUser:(id)sender {
    UTAlertView *alert = [[UTAlertView alloc] initWithTitle:@"Attenzione" message:@"Tutti i campi sono obbligatori" ];
        alert.alertViewType = UTAlertViewTypeWarning;
        [alert presentAlert];
        [self.view addSubview:alert];
}

用于通知的自定义 UIView Class - 实现文件

 @interface UTAlertView ()
@property (nonatomic, assign) BOOL alertActive;

@end

@implementation UTAlertView
@synthesize alertIcon;
@synthesize titleLabel, messageLabel;
@synthesize alertView;
@synthesize alertActive;



-(id)initWithTitle:(NSString*)title message:(NSString *)message {
    [self initializeStringElementAlertView:title message:message];
    return self;
}

-(void)initializeStringElementAlertView:(NSString *)title message:(NSString *)message {
    alertView = [self initWithFrame:CGRectMake(0, [UIScreen mainScreen].bounds.size.height +100, kViewSize_W, kViewSize_H)];
    [UTAlertElement alertTitle:titleLabel withString:title andAddSubview:self];
    [UTAlertElement alertMessage:messageLabel withString:message andAddSubview:self];
    alertIcon = [UTAlertElement iconAlertViewInView:self];
}



-(void)presentAlert {

    if (!alertActive) {
        alertActive =YES;

        [UIView animateWithDuration:.3
                         animations:^{
                             [self bounce:1] ;

                             self.frame = CGRectMake(0, [UIScreen mainScreen].bounds.size.height -60, [UIScreen mainScreen].bounds.size.width, kViewSize_H);

                         } completion:^(BOOL finished) {
                             UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(setHideAnimation)];
                             tapGesture.cancelsTouchesInView = NO;
                             [self setUserInteractionEnabled:YES];
                             [self addGestureRecognizer:tapGesture];
                             [self performSelector:@selector(setHideAnimation) withObject:self afterDelay:3];

                         }];


    }

}


-(void)setHideAnimation {

        [UIView animateWithDuration:.3
                         animations:^{
                             self.frame = CGRectMake(0, [UIScreen mainScreen].bounds.size.height +100, [UIScreen mainScreen].bounds.size.width, kViewSize_H);

                         } completion:^(BOOL finished) {
                            alertActive =NO;
                         }];




}

您可以使用 GCD dispatch_once

例如,在您的视图的初始化方法中创建 dispatch_once_t dispatch_flag 然后:

  dispatch_once( & dispatch_flag, ^{
    // your presentation code goes here
  } );

如果你只是想让你的代码只执行,那么看看 dispatch_once here.

基本上你可以这样做:

static dispatch_once_t once;
dispatch_once(&once, ^ { 
    // Your code to be executed only once.
});

如果您希望能够多次打开通知,但不是同时打开,您有多种选择,包括:

  • 单例模式:在这种情况下我不会使用它,因为这意味着您将无法拥有通知类型的多个实例。
  • 块或委托:拥有完成块或使用委托模式也是一种选择。但是,我认为这种方法会让通知的使用者 class 来处理何时应该可以显示通知的逻辑。这可能是你想要的(如果你对不同的观点有不同的逻辑),但我不这么认为。

这些可能是很好的方法,但在您的情况下,我会按照您自己的建议简单地进行一些基本的状态处理。所以,我可能会做这样的事情:

第 1 步:将 BOOL 属性 添加到您的通知中 class

@property (nonatomic, assign) BOOL isVisible

第 2 步:向显示和隐藏方法添加状态处理

-(void)presentAlert {
    //PRESENT THE ALERT
    if (!self.isVisible) {
        self.isVisible = YES;
        [UIView animateWithDuration:.3
                         animations:^{
                             [self bounce:1];
                             self.frame = CGRectMake(0, [UIScreen mainScreen].bounds.size.height - 60, [UIScreen mainScreen].bounds.size.width, kViewSize_H);
                         }
                         completion:^(BOOL finished) {
                             UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(setHideAnimation)];
                             tapGesture.cancelsTouchesInView = NO;
                             [self setUserInteractionEnabled:YES];
                             [self addGestureRecognizer:tapGesture];
                             [self performSelector:@selector(setHideAnimation) withObject:self afterDelay:3];
                         }];
    }
}

-(void)setHideAnimation {
    //REMOVE THE ALERT
    [UIView animateWithDuration:.3
                     animations:^{
                         self.frame = CGRectMake(0, [UIScreen mainScreen].bounds.size.height +100, [UIScreen mainScreen].bounds.size.width, kViewSize_H);
                     }
                     completion:^(BOOL finished) {
                         self.isVisible = NO;
                    }];
}

我还没有真正测试过它,但它应该能让你入门。此外,您可能想研究避免保留循环。

请记住,使用此方法时,不应在用户每次触发通知时都创建通知。你可能想做这样的事情:

@property (nonatomic, strong) UTAlertView *loginAlert;

然后当您设置视图时(例如在 viewDidLoadloadView 中)您可以创建通知:

- (void)viewDidLoad {
    [super viewDidLoad];
    self.loginAlert = [[UTAlertView alloc] initWithTitle:@"Attenzione" message:@"Tutti i campi sono obbligatori" ];
    self.loginAlert.alertViewType = UTAlertViewTypeWarning;
}

当然,然后在您负责显示警报的方法中执行如下操作:

-(IBAction)loginUser:(id)sender {
    [self.loginAlert presentAlert];
    [self.view addSubview:self.loginAlert];
}

我认为单实例 (Singleton) 警报可以解决您的问题。使用单例模式避免出现多个警报视图实例。