⬆️ ⬇️

Writing an alert for iOS

Good morning / afternoon / evening / night% username%!



Prehistory


In the process of implementing the next project , it became necessary to implement an effective notification of the user about something (for example, the absence of an Internet connection). So how do you do this? The standard UIAlertView class turned out to be too cumbersome and boring for this purpose, and, finding nothing more suitable, it was decided to write my casino with blackjack ... its own alert class.



Implementation


So let's get started. The main criterion for this class was “calling with one line of code,” so I got the method:



+ (void) showMessage:(NSString *)message; 


')

Based on the task of “very simple user notification”, it was decided to use:





For a start, we will take the UILabel and "sharpen" for our needs:



 UILabel *messageLabel = [[UILabel alloc] init]; messageLabel.textAlignment = UITextAlignmentCenter; messageLabel.numberOfLines = 0; messageLabel.lineBreakMode = UILineBreakModeWordWrap; messageLabel.text = message; messageLabel.font = [UIFont fontWithName:@”Helvetica-Bold” size:15.0f]; messageLabel.textColor = [UIColor whiteColor]; messageLabel.backgroundColor = [UIColor clearColor]; 




Next you need to know - "And how much will our message take up space on the screen?"



 CGSize messageSize = [message sizeWithFont:messageLabel.font constrainedToSize:CGSizeMake(160.0f, 9999.0f) lineBreakMode:UILineBreakModeWordWrap]; 




Method for NSString sizeWithFont: (UIFont *) font constrainedToSize (CGSize) size lineBreakMode: (UILineBreakMode) lineBreakMode will return to us in this case the size of the rectangle in which the text will be entered based on the conditions:





Further it is necessary to make a rectangle from the obtained sizes taking into account 2 additional sizes:





 CGRect messageRect = CGRectMake(offsetSize.width + borderWidth, offsetSize.height + borderWidth, messageSize.width, messageSize.height); messageLabel.frame = messageRect; 




Everything, on it meanwhile we finished with UILabel.

Next in line is the container for UILabel - the first of two UIViews. For the container it was necessary to take into account - the background color, border, indents from the border. As an addition to the design of the annotation - rounded corners, shadow and transparency. Below is the code for our container.



 messageSize.width += offsetSize.width*2.0f + borderWidth; messageSize.height += offsetSize.height*2.0f + borderWidth; contentRect = CGRectMake(0.0f, 0.0f, messageSize.width, messageSize.height); UIView *content = [[UIView alloc] init]; content.frame = contentRect; content.backgroundColor = [UIColor colorWithRed:(60.0f/255.0f) green:(60.0f/255.0f) blue:(60.0f/255.0f) alpha:1.0f]; content.alpha = 0.8f; content.layer.cornerRadius = 8.0f; content.layer.shadowRadius = 8.0f; content.layer.masksToBounds = NO; content.layer.shadowOffset = CGSizeMake(0.0f, 4.0f); content.layer.shadowOpacity = 1.0f; content.layer.borderWidth = 1.0f; content.layer.borderColor = [[UIColor colorWithRed:(128.0f/255.0f) green:(128.0f/255.0f) blue:(128.0f/255.0f) alpha:1.0f] CGColor]; content.layer.shadowPath = [UIBezierPath bezierPathWithRect:contentRect].CGPath; 




That's all. Now we can only use the last remaining UIView - rootView. We will use it for animation.



 UIView *rootView = [[UIView alloc] init]; rootView.tag = 2000; rootView.frame = contentRect; rootView.alpha = 0.0f; 




Everything at this stage we have prepared for further use UILabel with the message and 2 UIView containers. It remains only to assemble a matryoshka from them and establish a position in the center of the screen:



 messageLabel.center = CGPointMake(contentRect.size.width/2.0f, contentRect.size.height/2.0f); [content addSubview:messageLabel]; [messageLabel release]; [rootView addSubview:content]; [content release]; rootView.center = [[UIApplication sharedApplication] keyWindow].center; 




Animation


In our case, the animation was divided into 3 components:





The bounce effect was achieved by simply animating the rootView increase from the size with a factor of 0.8 to the size of a factor of 1.1 and an immediate decrease to the natural size - a factor of 1.0. Appearance and Disappearance - change rootView.alpha from 0.0f to 1.0f and vice versa. The disappearance is also accompanied by a change in size to a factor of 1.2. For the appearance and achievement of the “peak” point of the bounce-effect (namely, when the coefficient of 1.2 is reached), it was decided to allocate 2/3 of the total time scheduled for the animation. The remainder of the time was used to go to the normal display. Then the user is given time to be able to read the message and then the message disappears.

Starting with iOS version 4.0, animation is implemented through blocks. Therefore, the required version of iOS is not lower than 4.0 (in the future we plan to add support for iOS 3).



 + (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion 




the UIView class method allows us to set:





The animation implementation code is shown below:



 rootView.transform = CGAffineTransformMakeScale(0.8f, 0.8f); [[[UIApplication sharedApplication] keyWindow] addSubview:rootView]; [UIView animateWithDuration:0.35*0.66 delay:0.0 options:UIViewAnimationCurveEaseOut animations:^ { rootView.alpha = 0.66f; rootView.transform = CGAffineTransformMakeScale(1.1f, 1.1f); } completion:^(BOOL completed) { [UIView animateWithDuration:0.35*0.33 delay:0.0 options:UIViewAnimationCurveLinear animations:^{ rootView.alpha = 1.0f; rootView.transform = CGAffineTransformIdentity; } completion:^(BOOL completed) { [UIView animateWithDuration:0.35 delay:0.9 options:UIViewAnimationCurveEaseIn animations:^{ rootView.alpha = 0.0f; rootView.transform = CGAffineTransformMakeScale(1.2f, 1.2f); } completion:^(BOOL completed) { [rootView removeFromSuperview]; [rootView release]; }]; }]; }]; 




Total

As a result of writing this class, we got a very convenient “alert” that can be called up with a single line of code:



 [FHNotification showMessage:@”Very simple inApp-notification”]; 




findings


Advantages of this class:



Minuses:





QuartzCore.framework is also required for this class.

The source code can be downloaded on github , slightly updated and extended.

That's all. Thanks for attention

Source: https://habr.com/ru/post/120080/



All Articles