toast

  

 1 /***************************************************************************
2
3 Toast+UIView.h
4 Toast
5 Version 0.1
6
7 Copyright (c) 2011 Charles Scalesse.
8
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sublicense, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
16
17 The above copyright notice and this permission notice shall be included
18 in all copies or substantial portions of the Software.
19
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28 ***************************************************************************/
29
30
31 #import <Foundation/Foundation.h>
32
33 @interface UIView (Toast)
34
35 // each makeToast method creates a view and displays it as toast
36 -(void)makeToast:(NSString *)message;
37 -(void)makeToast:(NSString *)message duration:(float)interval position:(id)point;
38 -(void)makeToast:(NSString *)message duration:(float)interval position:(id)point title:(NSString *)title;
39 -(void)makeToast:(NSString *)message duration:(float)interval position:(id)point title:(NSString *)title image:(UIImage *)image;
40 -(void)makeToast:(NSString *)message duration:(float)interval position:(id)point image:(UIImage *)image;
41
42 // the showToast method displays an existing view as toast
43 -(void)showToast:(UIView *)toast;
44 -(void)showToast:(UIView *)toast duration:(float)interval position:(id)point;
45
46 @end
  1 //
2 // Toast+UIView.m
3 // Toast
4 // Version 0.1
5 //
6 // Copyright 2011 Charles Scalesse.
7 //
8
9 #import "Toast+UIView.h"
10 #import <QuartzCore/QuartzCore.h>
11 #import <objc/runtime.h>
12
13 #define kMaxWidth 0.8
14 #define kMaxHeight 0.8
15
16 #define kHorizontalPadding 10.0
17 #define kVerticalPadding 10.0
18 #define kCornerRadius 10.0
19 #define kOpacity 0.8
20 #define kFontSize 16.0
21 #define kMaxTitleLines 999
22 #define kMaxMessageLines 999
23
24 #define kFadeDuration 0.2
25
26 #define kDefaultLength 3
27 #define kDefaultPosition @"bottom"
28
29 #define kImageWidth 80.0
30 #define kImageHeight 80.0
31
32 static NSString *kDurationKey = @"duration";
33
34
35 @interface UIView (ToastPrivate)
36
37 -(CGPoint)getPositionFor:(id)position toast:(UIView *)toast;
38 -(UIView *)makeViewForMessage:(NSString *)message title:(NSString *)title image:(UIImage *)image;
39
40 @end
41
42
43 @implementation UIView (Toast)
44
45 #pragma mark -
46 #pragma mark Toast Methods
47
48 -(void)makeToast:(NSString *)message {
49 [self makeToast:message duration:kDefaultLength position:kDefaultPosition];
50 }
51
52 -(void)makeToast:(NSString *)message duration:(float)interval position:(id)point {
53 UIView *toast = [self makeViewForMessage:message title:nil image:nil];
54 [self showToast:toast duration:interval position:point];
55 }
56
57 -(void)makeToast:(NSString *)message duration:(float)interval position:(id)point title:(NSString *)title {
58 UIView *toast = [self makeViewForMessage:message title:title image:nil];
59 [self showToast:toast duration:interval position:point];
60 }
61
62 -(void)makeToast:(NSString *)message duration:(float)interval position:(id)point image:(UIImage *)image {
63 UIView *toast = [self makeViewForMessage:message title:nil image:image];
64 [self showToast:toast duration:interval position:point];
65 }
66
67 -(void)makeToast:(NSString *)message duration:(float)interval position:(id)point title:(NSString *)title image:(UIImage *)image {
68 UIView *toast = [self makeViewForMessage:message title:title image:image];
69 [self showToast:toast duration:interval position:point];
70 }
71
72 -(void)showToast:(UIView *)toast {
73 [self showToast:toast duration:kDefaultLength position:kDefaultPosition];
74 }
75
76 -(void)showToast:(UIView *)toast duration:(float)interval position:(id)point {
77
78 /****************************************************
79 * *
80 * Displays a view for a given duration & position. *
81 * *
82 ****************************************************/
83
84 CGPoint toastPoint = [self getPositionFor:point toast:toast];
85
86 //use an associative reference to associate the toast view with the display interval
87 objc_setAssociatedObject (toast, &kDurationKey, [NSNumber numberWithFloat:interval], OBJC_ASSOCIATION_RETAIN);
88
89 [toast setCenter:toastPoint];
90 [toast setAlpha:0.0];
91 [self addSubview:toast];
92
93 [UIView beginAnimations:@"fade_in" context:toast];
94 [UIView setAnimationDuration:kFadeDuration];
95 [UIView setAnimationDelegate:self];
96 [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
97 [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
98 [toast setAlpha:1.0];
99 [UIView commitAnimations];
100
101 }
102
103 #pragma mark -
104 #pragma mark Animation Delegate Method
105
106 - (void)animationDidStop:(NSString*)animationID finished:(BOOL)finished context:(void *)context {
107
108 UIView *toast = (UIView *)context;
109
110 // retrieve the display interval associated with the view
111 float interval = [(NSNumber *)objc_getAssociatedObject(toast, &kDurationKey) floatValue];
112
113 if([animationID isEqualToString:@"fade_in"]) {
114
115 [UIView beginAnimations:@"fade_out" context:toast];
116 [UIView setAnimationDelay:interval];
117 [UIView setAnimationDuration:kFadeDuration];
118 [UIView setAnimationDelegate:self];
119 [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
120 [UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
121 [toast setAlpha:0.0];
122 [UIView commitAnimations];
123
124 } else if ([animationID isEqualToString:@"fade_out"]) {
125
126 [toast removeFromSuperview];
127
128 }
129
130 }
131
132 #pragma mark -
133 #pragma mark Private Methods
134
135 -(CGPoint)getPositionFor:(id)point toast:(UIView *)toast {
136
137 /*************************************************************************************
138 * *
139 * Converts string literals @"top", @"bottom", @"center", or any point wrapped in an *
140 * NSValue object into a CGPoint *
141 * *
142 *************************************************************************************/
143
144 if([point isKindOfClass:[NSString class]]) {
145
146 if( [point caseInsensitiveCompare:@"top"] == NSOrderedSame ) {
147 return CGPointMake(self.bounds.size.width/2, (toast.frame.size.height / 2) + kVerticalPadding);
148 } else if( [point caseInsensitiveCompare:@"bottom"] == NSOrderedSame ) {
149 return CGPointMake(self.bounds.size.width/2, (self.bounds.size.height - (toast.frame.size.height / 2)) - kVerticalPadding);
150 } else if( [point caseInsensitiveCompare:@"center"] == NSOrderedSame ) {
151 return CGPointMake(self.bounds.size.width / 2, self.bounds.size.height / 2);
152 }
153
154 } else if ([point isKindOfClass:[NSValue class]]) {
155 return [point CGPointValue];
156 }
157
158 NSLog(@"Error: Invalid position for toast.");
159 return [self getPositionFor:kDefaultPosition toast:toast];
160 }
161
162 -(UIView *)makeViewForMessage:(NSString *)message title:(NSString *)title image:(UIImage *)image {
163
164 /***********************************************************************************
165 * *
166 * Dynamically build a toast view with any combination of message, title, & image. *
167 * *
168 ***********************************************************************************/
169
170 if((message == nil) && (title == nil) && (image == nil)) return nil;
171
172 UILabel *messageLabel = nil;
173 UILabel *titleLabel = nil;
174 UIImageView *imageView = nil;
175
176 // create the parent view
177 UIView *wrapperView = [[[UIView alloc] init] autorelease];
178 [wrapperView.layer setCornerRadius:kCornerRadius];
179 [wrapperView setBackgroundColor:[[UIColor blackColor] colorWithAlphaComponent:kOpacity]];
180
181 if(image != nil) {
182 imageView = [[[UIImageView alloc] initWithImage:image] autorelease];
183 [imageView setContentMode:UIViewContentModeScaleAspectFit];
184 [imageView setFrame:CGRectMake(kHorizontalPadding, kVerticalPadding, kImageWidth, kImageHeight)];
185 }
186
187 float imageWidth, imageHeight, imageLeft;
188
189 // the imageView frame values will be used to size & position the other views
190 if(imageView != nil) {
191 imageWidth = imageView.bounds.size.width;
192 imageHeight = imageView.bounds.size.height;
193 imageLeft = kHorizontalPadding;
194 } else {
195 imageWidth = imageHeight = imageLeft = 0;
196 }
197
198 if (title != nil) {
199 titleLabel = [[[UILabel alloc] init] autorelease];
200 [titleLabel setNumberOfLines:kMaxTitleLines];
201 [titleLabel setFont:[UIFont boldSystemFontOfSize:kFontSize]];
202 [titleLabel setTextAlignment:UITextAlignmentLeft];
203 [titleLabel setLineBreakMode:UILineBreakModeWordWrap];
204 [titleLabel setTextColor:[UIColor whiteColor]];
205 [titleLabel setBackgroundColor:[UIColor clearColor]];
206 [titleLabel setAlpha:1.0];
207 [titleLabel setText:title];
208
209 // size the title label according to the length of the text
210 CGSize maxSizeTitle = CGSizeMake((self.bounds.size.width * kMaxWidth) - imageWidth, self.bounds.size.height * kMaxHeight);
211 CGSize expectedSizeTitle = [title sizeWithFont:titleLabel.font constrainedToSize:maxSizeTitle lineBreakMode:titleLabel.lineBreakMode];
212 [titleLabel setFrame:CGRectMake(0, 0, expectedSizeTitle.width, expectedSizeTitle.height)];
213 }
214
215 if (message != nil) {
216 messageLabel = [[[UILabel alloc] init] autorelease];
217 [messageLabel setNumberOfLines:kMaxMessageLines];
218 [messageLabel setFont:[UIFont systemFontOfSize:kFontSize]];
219 [messageLabel setLineBreakMode:UILineBreakModeWordWrap];
220 [messageLabel setTextColor:[UIColor whiteColor]];
221 [messageLabel setBackgroundColor:[UIColor clearColor]];
222 [messageLabel setAlpha:1.0];
223 [messageLabel setText:message];
224
225 // size the message label according to the length of the text
226 CGSize maxSizeMessage = CGSizeMake((self.bounds.size.width * kMaxWidth) - imageWidth, self.bounds.size.height * kMaxHeight);
227 CGSize expectedSizeMessage = [message sizeWithFont:messageLabel.font constrainedToSize:maxSizeMessage lineBreakMode:messageLabel.lineBreakMode];
228 [messageLabel setFrame:CGRectMake(0, 0, expectedSizeMessage.width, expectedSizeMessage.height)];
229 }
230
231 // titleLabel frame values
232 float titleWidth, titleHeight, titleTop, titleLeft;
233
234 if(titleLabel != nil) {
235 titleWidth = titleLabel.bounds.size.width;
236 titleHeight = titleLabel.bounds.size.height;
237 titleTop = kVerticalPadding;
238 titleLeft = imageLeft + imageWidth + kHorizontalPadding;
239 } else {
240 titleWidth = titleHeight = titleTop = titleLeft = 0;
241 }
242
243 // messageLabel frame values
244 float messageWidth, messageHeight, messageLeft, messageTop;
245
246 if(messageLabel != nil) {
247 messageWidth = messageLabel.bounds.size.width;
248 messageHeight = messageLabel.bounds.size.height;
249 messageLeft = imageLeft + imageWidth + kHorizontalPadding;
250 messageTop = titleTop + titleHeight + kVerticalPadding;
251 } else {
252 messageWidth = messageHeight = messageLeft = messageTop = 0;
253 }
254
255 // compare the title & message widths and use the longer value to calculate the size of the wrapper width
256 // the same logic applies to the x value (left)
257 float longerWidth = (messageWidth < titleWidth) ? titleWidth : messageWidth;
258 float longerLeft = (messageLeft < titleLeft) ? titleLeft : messageLeft;
259
260 // if the image width is larger than longerWidth, use the image width to calculate the wrapper width.
261 // the same logic applies to the wrapper height
262 float wrapperWidth = ((longerLeft + longerWidth + kHorizontalPadding) < imageWidth + (kHorizontalPadding * 2)) ? imageWidth + (kHorizontalPadding * 2) : (longerLeft + longerWidth + kHorizontalPadding);
263 float wrapperHeight = ((messageTop + messageHeight + kVerticalPadding) < imageHeight + (kVerticalPadding * 2)) ? imageHeight + (kVerticalPadding * 2) : (messageTop + messageHeight + kVerticalPadding);
264
265 [wrapperView setFrame:CGRectMake(0, 0, wrapperWidth, wrapperHeight)];
266
267 if(titleLabel != nil) {
268 [titleLabel setFrame:CGRectMake(titleLeft, titleTop, titleWidth, titleHeight)];
269 [wrapperView addSubview:titleLabel];
270 }
271
272 if(messageLabel != nil) {
273 [messageLabel setFrame:CGRectMake(messageLeft, messageTop, messageWidth, messageHeight)];
274 [wrapperView addSubview:messageLabel];
275 }
276
277 if(imageView != nil) {
278 [wrapperView addSubview:imageView];
279 }
280
281 return wrapperView;
282 }
283
284 @end



转载于:https://www.cnblogs.com/rothwell/archive/2012/03/12/2392323.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值