自定义警报通知 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;
然后当您设置视图时(例如在 viewDidLoad
或 loadView
中)您可以创建通知:
- (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) 警报可以解决您的问题。使用单例模式避免出现多个警报视图实例。
对于我的 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;
然后当您设置视图时(例如在 viewDidLoad
或 loadView
中)您可以创建通知:
- (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) 警报可以解决您的问题。使用单例模式避免出现多个警报视图实例。