-
Notifications
You must be signed in to change notification settings - Fork 5
/
LoadingView.m
213 lines (184 loc) · 5.75 KB
/
LoadingView.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
//
// LoadingView.m
// LoadingView
//
// Created by Matt Gallagher on 12/04/09.
// Copyright Matt Gallagher 2009. All rights reserved.
//
// Permission is given to use this source code file, free of charge, in any
// project, commercial or otherwise, entirely at your risk, with the condition
// that any redistribution (in part or whole) of source code must retain
// this copyright and permission notice. Attribution in compiled projects is
// appreciated but not required.
//
#import "LoadingView.h"
#import <QuartzCore/QuartzCore.h>
//
// NewPathWithRoundRect
//
// Creates a CGPathRect with a round rect of the given radius.
//
CGPathRef NewPathWithRoundRect(CGRect rect, CGFloat cornerRadius)
{
//
// Create the boundary path
//
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL,
rect.origin.x,
rect.origin.y + rect.size.height - cornerRadius);
// Top left corner
CGPathAddArcToPoint(path, NULL,
rect.origin.x,
rect.origin.y,
rect.origin.x + rect.size.width,
rect.origin.y,
cornerRadius);
// Top right corner
CGPathAddArcToPoint(path, NULL,
rect.origin.x + rect.size.width,
rect.origin.y,
rect.origin.x + rect.size.width,
rect.origin.y + rect.size.height,
cornerRadius);
// Bottom right corner
CGPathAddArcToPoint(path, NULL,
rect.origin.x + rect.size.width,
rect.origin.y + rect.size.height,
rect.origin.x,
rect.origin.y + rect.size.height,
cornerRadius);
// Bottom left corner
CGPathAddArcToPoint(path, NULL,
rect.origin.x,
rect.origin.y + rect.size.height,
rect.origin.x,
rect.origin.y,
cornerRadius);
// Close the path at the rounded rect
CGPathCloseSubpath(path);
return path;
}
@implementation LoadingView
//
// loadingViewInView:
//
// Constructor for this view. Creates and adds a loading view for covering the
// provided aSuperview.
//
// Parameters:
// aSuperview - the superview that will be covered by the loading view
//
// returns the constructed view, already added as a subview of the aSuperview
// (and hence retained by the superview)
//
+ (id)loadingViewInView:(UIView *)aSuperview
{
LoadingView *loadingView =
[[LoadingView alloc] initWithFrame:[aSuperview bounds]];
if (!loadingView)
{
return nil;
}
loadingView.opaque = NO;
loadingView.autoresizingMask =
UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[aSuperview addSubview:loadingView];
const CGFloat DEFAULT_LABEL_WIDTH = 280.0;
const CGFloat DEFAULT_LABEL_HEIGHT = 50.0;
CGRect labelFrame = CGRectMake(0, 0, DEFAULT_LABEL_WIDTH, DEFAULT_LABEL_HEIGHT);
UILabel *loadingLabel =
[[[UILabel alloc]
initWithFrame:labelFrame]
autorelease];
loadingLabel.text = NSLocalizedString(@"Loading...", nil);
loadingLabel.textColor = [UIColor whiteColor];
loadingLabel.backgroundColor = [UIColor clearColor];
loadingLabel.textAlignment = UITextAlignmentCenter;
loadingLabel.font = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]];
loadingLabel.autoresizingMask =
UIViewAutoresizingFlexibleLeftMargin |
UIViewAutoresizingFlexibleRightMargin |
UIViewAutoresizingFlexibleTopMargin |
UIViewAutoresizingFlexibleBottomMargin;
[loadingView addSubview:loadingLabel];
UIActivityIndicatorView *activityIndicatorView =
[[[UIActivityIndicatorView alloc]
initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]
autorelease];
[loadingView addSubview:activityIndicatorView];
activityIndicatorView.autoresizingMask =
UIViewAutoresizingFlexibleLeftMargin |
UIViewAutoresizingFlexibleRightMargin |
UIViewAutoresizingFlexibleTopMargin |
UIViewAutoresizingFlexibleBottomMargin;
[activityIndicatorView startAnimating];
CGFloat totalHeight =
loadingLabel.frame.size.height +
activityIndicatorView.frame.size.height;
labelFrame.origin.x = floor(0.5 * (loadingView.frame.size.width - DEFAULT_LABEL_WIDTH));
labelFrame.origin.y = floor(0.5 * (loadingView.frame.size.height - totalHeight));
loadingLabel.frame = labelFrame;
CGRect activityIndicatorRect = activityIndicatorView.frame;
activityIndicatorRect.origin.x =
0.5 * (loadingView.frame.size.width - activityIndicatorRect.size.width);
activityIndicatorRect.origin.y =
loadingLabel.frame.origin.y + loadingLabel.frame.size.height;
activityIndicatorView.frame = activityIndicatorRect;
// Set up the fade-in animation
CATransition *animation = [CATransition animation];
[animation setType:kCATransitionFade];
[[aSuperview layer] addAnimation:animation forKey:@"layerAnimation"];
return loadingView;
}
//
// removeView
//
// Animates the view out from the superview. As the view is removed from the
// superview, it will be released.
//
- (void)removeView
{
UIView *aSuperview = [self superview];
[super removeFromSuperview];
// Set up the animation
CATransition *animation = [CATransition animation];
[animation setType:kCATransitionFade];
[[aSuperview layer] addAnimation:animation forKey:@"layerAnimation"];
}
//
// drawRect:
//
// Draw the view.
//
- (void)drawRect:(CGRect)rect
{
rect.size.height -= 1;
rect.size.width -= 1;
const CGFloat RECT_PADDING = 60.0;
rect = CGRectInset(rect, RECT_PADDING, RECT_PADDING);
rect.size.height = 190;
rect.origin.y = 140;
const CGFloat ROUND_RECT_CORNER_RADIUS = 10.0;
CGPathRef roundRectPath = NewPathWithRoundRect(rect, ROUND_RECT_CORNER_RADIUS);
CGContextRef context = UIGraphicsGetCurrentContext();
const CGFloat BACKGROUND_OPACITY = 0.85;
CGContextSetRGBFillColor(context, 0, 0, 0, BACKGROUND_OPACITY);
CGContextAddPath(context, roundRectPath);
CGContextFillPath(context);
const CGFloat STROKE_OPACITY = 0.25;
CGContextSetRGBStrokeColor(context, 1, 1, 1, STROKE_OPACITY);
CGContextAddPath(context, roundRectPath);
CGContextStrokePath(context);
CGPathRelease(roundRectPath);
}
//
// dealloc
//
// Release instance memory.
//
- (void)dealloc
{
[super dealloc];
}
@end