自定义提醒通知iOS

时间:2015-03-20 09:05:58

标签: ios xcode uiview boolean

对于我的iOS应用程序,我创建了一个自定义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类 - 实施文件

 @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;
                         }];




}

3 个答案:

答案 0 :(得分:1)

如果您只想让代码仅执行,请查看dispatch_once here

基本上你可以这样做:

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

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

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

这些可能是很好的方法,但在你的情况下,我会简单地采用一些基本的状态处理,就像你自己建议的那样。所以,我可能会这样做:

第1步:将BOOL属性添加到通知类

@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];
}

答案 1 :(得分:1)

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

答案 2 :(得分:0)

您可以使用GCD dispatch_once

例如,在视图的init方法中创建dispatch_once_t dispatch_flag,然后:

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