Playlist Generator
1.0
|
00001 // 00002 // MBProgressHUD.m 00003 // Version 0.4 00004 // Created by Matej Bukovinski on 2.4.09. 00005 // 00006 00007 #import "MBProgressHUD.h" 00008 00009 @interface MBProgressHUD () 00010 00011 - (void)hideUsingAnimation:(BOOL)animated; 00012 - (void)showUsingAnimation:(BOOL)animated; 00013 - (void)done; 00014 - (void)updateLabelText:(NSString *)newText; 00015 - (void)updateDetailsLabelText:(NSString *)newText; 00016 - (void)updateProgress; 00017 - (void)updateIndicators; 00018 - (void)handleGraceTimer:(NSTimer *)theTimer; 00019 - (void)handleMinShowTimer:(NSTimer *)theTimer; 00020 - (void)setTransformForCurrentOrientation:(BOOL)animated; 00021 - (void)cleanUp; 00022 - (void)deviceOrientationDidChange:(NSNotification*)notification; 00023 - (void)launchExecution; 00024 - (void)deviceOrientationDidChange:(NSNotification *)notification; 00025 - (void)hideDelayed:(NSNumber *)animated; 00026 - (void)launchExecution; 00027 - (void)cleanUp; 00028 00029 @property (retain) UIView *indicator; 00030 @property (assign) float width; 00031 @property (assign) float height; 00032 @property (retain) NSTimer *graceTimer; 00033 @property (retain) NSTimer *minShowTimer; 00034 @property (retain) NSDate *showStarted; 00035 00036 @end 00037 00038 00039 @implementation MBProgressHUD 00040 00041 #pragma mark - 00042 #pragma mark Accessors 00043 00044 @synthesize animationType; 00045 00046 @synthesize delegate; 00047 @synthesize opacity; 00048 @synthesize labelFont; 00049 @synthesize detailsLabelFont; 00050 00051 @synthesize indicator; 00052 00053 @synthesize width; 00054 @synthesize height; 00055 @synthesize xOffset; 00056 @synthesize yOffset; 00057 @synthesize minSize; 00058 @synthesize square; 00059 @synthesize margin; 00060 @synthesize dimBackground; 00061 00062 @synthesize graceTime; 00063 @synthesize minShowTime; 00064 @synthesize graceTimer; 00065 @synthesize minShowTimer; 00066 @synthesize taskInProgress; 00067 @synthesize removeFromSuperViewOnHide; 00068 00069 @synthesize customView; 00070 00071 @synthesize showStarted; 00072 00073 - (void)setMode:(MBProgressHUDMode)newMode { 00074 // Dont change mode if it wasn't actually changed to prevent flickering 00075 if (mode && (mode == newMode)) { 00076 return; 00077 } 00078 00079 mode = newMode; 00080 00081 if ([NSThread isMainThread]) { 00082 [self updateIndicators]; 00083 [self setNeedsLayout]; 00084 [self setNeedsDisplay]; 00085 } else { 00086 [self performSelectorOnMainThread:@selector(updateIndicators) withObject:nil waitUntilDone:NO]; 00087 [self performSelectorOnMainThread:@selector(setNeedsLayout) withObject:nil waitUntilDone:NO]; 00088 [self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO]; 00089 } 00090 } 00091 00092 - (MBProgressHUDMode)mode { 00093 return mode; 00094 } 00095 00096 - (void)setLabelText:(NSString *)newText { 00097 if ([NSThread isMainThread]) { 00098 [self updateLabelText:newText]; 00099 [self setNeedsLayout]; 00100 [self setNeedsDisplay]; 00101 } else { 00102 [self performSelectorOnMainThread:@selector(updateLabelText:) withObject:newText waitUntilDone:NO]; 00103 [self performSelectorOnMainThread:@selector(setNeedsLayout) withObject:nil waitUntilDone:NO]; 00104 [self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO]; 00105 } 00106 } 00107 00108 - (NSString *)labelText { 00109 return labelText; 00110 } 00111 00112 - (void)setDetailsLabelText:(NSString *)newText { 00113 if ([NSThread isMainThread]) { 00114 [self updateDetailsLabelText:newText]; 00115 [self setNeedsLayout]; 00116 [self setNeedsDisplay]; 00117 } else { 00118 [self performSelectorOnMainThread:@selector(updateDetailsLabelText:) withObject:newText waitUntilDone:NO]; 00119 [self performSelectorOnMainThread:@selector(setNeedsLayout) withObject:nil waitUntilDone:NO]; 00120 [self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO]; 00121 } 00122 } 00123 00124 - (NSString *)detailsLabelText { 00125 return detailsLabelText; 00126 } 00127 00128 - (void)setProgress:(float)newProgress { 00129 progress = newProgress; 00130 00131 // Update display ony if showing the determinate progress view 00132 if (mode == MBProgressHUDModeDeterminate) { 00133 if ([NSThread isMainThread]) { 00134 [self updateProgress]; 00135 [self setNeedsDisplay]; 00136 } else { 00137 [self performSelectorOnMainThread:@selector(updateProgress) withObject:nil waitUntilDone:NO]; 00138 [self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO]; 00139 } 00140 } 00141 } 00142 00143 - (float)progress { 00144 return progress; 00145 } 00146 00147 #pragma mark - 00148 #pragma mark Accessor helpers 00149 00150 - (void)updateLabelText:(NSString *)newText { 00151 if (labelText != newText) { 00152 [labelText release]; 00153 labelText = [newText copy]; 00154 } 00155 } 00156 00157 - (void)updateDetailsLabelText:(NSString *)newText { 00158 if (detailsLabelText != newText) { 00159 [detailsLabelText release]; 00160 detailsLabelText = [newText copy]; 00161 } 00162 } 00163 00164 - (void)updateProgress { 00165 [(MBRoundProgressView *)indicator setProgress:progress]; 00166 } 00167 00168 - (void)updateIndicators { 00169 if (indicator) { 00170 [indicator removeFromSuperview]; 00171 } 00172 00173 if (mode == MBProgressHUDModeDeterminate) { 00174 self.indicator = [[[MBRoundProgressView alloc] init] autorelease]; 00175 } 00176 else if (mode == MBProgressHUDModeCustomView && self.customView != nil){ 00177 self.indicator = self.customView; 00178 } else { 00179 self.indicator = [[[UIActivityIndicatorView alloc] 00180 initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge] autorelease]; 00181 [(UIActivityIndicatorView *)indicator startAnimating]; 00182 } 00183 00184 00185 [self addSubview:indicator]; 00186 } 00187 00188 #pragma mark - 00189 #pragma mark Constants 00190 00191 #define PADDING 4.0f 00192 00193 #define LABELFONTSIZE 16.0f 00194 #define LABELDETAILSFONTSIZE 12.0f 00195 00196 #pragma mark - 00197 #pragma mark Class methods 00198 00199 + (MBProgressHUD *)showHUDAddedTo:(UIView *)view animated:(BOOL)animated { 00200 MBProgressHUD *hud = [[MBProgressHUD alloc] initWithView:view]; 00201 [view addSubview:hud]; 00202 [hud show:animated]; 00203 return [hud autorelease]; 00204 } 00205 00206 + (BOOL)hideHUDForView:(UIView *)view animated:(BOOL)animated { 00207 UIView *viewToRemove = nil; 00208 for (UIView *v in [view subviews]) { 00209 if ([v isKindOfClass:[MBProgressHUD class]]) { 00210 viewToRemove = v; 00211 } 00212 } 00213 if (viewToRemove != nil) { 00214 MBProgressHUD *HUD = (MBProgressHUD *)viewToRemove; 00215 HUD.removeFromSuperViewOnHide = YES; 00216 [HUD hide:animated]; 00217 return YES; 00218 } else { 00219 return NO; 00220 } 00221 } 00222 00223 00224 #pragma mark - 00225 #pragma mark Lifecycle methods 00226 00227 - (id)initWithWindow:(UIWindow *)window { 00228 return [self initWithView:window]; 00229 } 00230 00231 - (id)initWithView:(UIView *)view { 00232 // Let's check if the view is nil (this is a common error when using the windw initializer above) 00233 if (!view) { 00234 [NSException raise:@"MBProgressHUDViewIsNillException" 00235 format:@"The view used in the MBProgressHUD initializer is nil."]; 00236 } 00237 id me = [self initWithFrame:view.bounds]; 00238 // We need to take care of rotation ourselfs if we're adding the HUD to a window 00239 if ([view isKindOfClass:[UIWindow class]]) { 00240 [self setTransformForCurrentOrientation:NO]; 00241 } 00242 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange:) 00243 name:UIDeviceOrientationDidChangeNotification object:nil]; 00244 00245 return me; 00246 } 00247 00248 - (id)initWithFrame:(CGRect)frame { 00249 self = [super initWithFrame:frame]; 00250 if (self) { 00251 // Set default values for properties 00252 self.animationType = MBProgressHUDAnimationFade; 00253 self.mode = MBProgressHUDModeIndeterminate; 00254 self.labelText = nil; 00255 self.detailsLabelText = nil; 00256 self.opacity = 0.8f; 00257 self.labelFont = [UIFont boldSystemFontOfSize:LABELFONTSIZE]; 00258 self.detailsLabelFont = [UIFont boldSystemFontOfSize:LABELDETAILSFONTSIZE]; 00259 self.xOffset = 0.0f; 00260 self.yOffset = 0.0f; 00261 self.dimBackground = NO; 00262 self.margin = 20.0f; 00263 self.graceTime = 0.0f; 00264 self.minShowTime = 0.0f; 00265 self.removeFromSuperViewOnHide = NO; 00266 self.minSize = CGSizeZero; 00267 self.square = NO; 00268 00269 self.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; 00270 00271 // Transparent background 00272 self.opaque = NO; 00273 self.backgroundColor = [UIColor clearColor]; 00274 00275 // Make invisible for now 00276 self.alpha = 0.0f; 00277 00278 // Add label 00279 label = [[UILabel alloc] initWithFrame:self.bounds]; 00280 00281 // Add details label 00282 detailsLabel = [[UILabel alloc] initWithFrame:self.bounds]; 00283 00284 taskInProgress = NO; 00285 rotationTransform = CGAffineTransformIdentity; 00286 } 00287 return self; 00288 } 00289 00290 - (void)dealloc { 00291 [[NSNotificationCenter defaultCenter] removeObserver:self]; 00292 00293 [indicator release]; 00294 [label release]; 00295 [detailsLabel release]; 00296 [labelText release]; 00297 [detailsLabelText release]; 00298 [graceTimer release]; 00299 [minShowTimer release]; 00300 [showStarted release]; 00301 [customView release]; 00302 [super dealloc]; 00303 } 00304 00305 #pragma mark - 00306 #pragma mark Layout 00307 00308 - (void)layoutSubviews { 00309 CGRect frame = self.bounds; 00310 00311 // Compute HUD dimensions based on indicator size (add margin to HUD border) 00312 CGRect indFrame = indicator.bounds; 00313 self.width = indFrame.size.width + 2 * margin; 00314 self.height = indFrame.size.height + 2 * margin; 00315 00316 // Position the indicator 00317 indFrame.origin.x = floorf((frame.size.width - indFrame.size.width) / 2) + self.xOffset; 00318 indFrame.origin.y = floorf((frame.size.height - indFrame.size.height) / 2) + self.yOffset; 00319 indicator.frame = indFrame; 00320 00321 // Add label if label text was set 00322 if (nil != self.labelText) { 00323 // Get size of label text 00324 CGSize dims = [self.labelText sizeWithFont:self.labelFont]; 00325 00326 // Compute label dimensions based on font metrics if size is larger than max then clip the label width 00327 float lHeight = dims.height; 00328 float lWidth; 00329 if (dims.width <= (frame.size.width - 4 * margin)) { 00330 lWidth = dims.width; 00331 } 00332 else { 00333 lWidth = frame.size.width - 4 * margin; 00334 } 00335 00336 // Set label properties 00337 label.font = self.labelFont; 00338 label.adjustsFontSizeToFitWidth = NO; 00339 label.textAlignment = UITextAlignmentCenter; 00340 label.opaque = NO; 00341 label.backgroundColor = [UIColor clearColor]; 00342 label.textColor = [UIColor whiteColor]; 00343 label.text = self.labelText; 00344 00345 // Update HUD size 00346 if (self.width < (lWidth + 2 * margin)) { 00347 self.width = lWidth + 2 * margin; 00348 } 00349 self.height = self.height + lHeight + PADDING; 00350 00351 // Move indicator to make room for the label 00352 indFrame.origin.y -= (floorf(lHeight / 2 + PADDING / 2)); 00353 indicator.frame = indFrame; 00354 00355 // Set the label position and dimensions 00356 CGRect lFrame = CGRectMake(floorf((frame.size.width - lWidth) / 2) + xOffset, 00357 floorf(indFrame.origin.y + indFrame.size.height + PADDING), 00358 lWidth, lHeight); 00359 label.frame = lFrame; 00360 00361 [self addSubview:label]; 00362 00363 // Add details label delatils text was set 00364 if (nil != self.detailsLabelText) { 00365 00366 // Set label properties 00367 detailsLabel.font = self.detailsLabelFont; 00368 detailsLabel.adjustsFontSizeToFitWidth = NO; 00369 detailsLabel.textAlignment = UITextAlignmentCenter; 00370 detailsLabel.opaque = NO; 00371 detailsLabel.backgroundColor = [UIColor clearColor]; 00372 detailsLabel.textColor = [UIColor whiteColor]; 00373 detailsLabel.text = self.detailsLabelText; 00374 detailsLabel.numberOfLines = 0; 00375 00376 CGFloat maxHeight = frame.size.height - self.height - 2*margin; 00377 CGSize labelSize = [detailsLabel.text sizeWithFont:detailsLabel.font constrainedToSize:CGSizeMake(frame.size.width - 4*margin, maxHeight) lineBreakMode:detailsLabel.lineBreakMode]; 00378 lHeight = labelSize.height; 00379 lWidth = labelSize.width; 00380 00381 // Update HUD size 00382 if (self.width < lWidth) { 00383 self.width = lWidth + 2 * margin; 00384 } 00385 self.height = self.height + lHeight + PADDING; 00386 00387 // Move indicator to make room for the new label 00388 indFrame.origin.y -= (floorf(lHeight / 2 + PADDING / 2)); 00389 indicator.frame = indFrame; 00390 00391 // Move first label to make room for the new label 00392 lFrame.origin.y -= (floorf(lHeight / 2 + PADDING / 2)); 00393 label.frame = lFrame; 00394 00395 // Set label position and dimensions 00396 CGRect lFrameD = CGRectMake(floorf((frame.size.width - lWidth) / 2) + xOffset, 00397 lFrame.origin.y + lFrame.size.height + PADDING, lWidth, lHeight); 00398 detailsLabel.frame = lFrameD; 00399 00400 [self addSubview:detailsLabel]; 00401 } 00402 } 00403 00404 if (square) { 00405 CGFloat max = MAX(self.width, self.height); 00406 if (max <= frame.size.width - 2*margin) { 00407 self.width = max; 00408 } 00409 if (max <= frame.size.height - 2*margin) { 00410 self.height = max; 00411 } 00412 } 00413 00414 if (self.width < minSize.width) { 00415 self.width = minSize.width; 00416 } 00417 if (self.height < minSize.height) { 00418 self.height = minSize.height; 00419 } 00420 } 00421 00422 #pragma mark - 00423 #pragma mark Showing and execution 00424 00425 - (void)show:(BOOL)animated { 00426 useAnimation = animated; 00427 00428 // If the grace time is set postpone the HUD display 00429 if (self.graceTime > 0.0) { 00430 self.graceTimer = [NSTimer scheduledTimerWithTimeInterval:self.graceTime 00431 target:self 00432 selector:@selector(handleGraceTimer:) 00433 userInfo:nil 00434 repeats:NO]; 00435 } 00436 // ... otherwise show the HUD imediately 00437 else { 00438 [self setNeedsDisplay]; 00439 [self showUsingAnimation:useAnimation]; 00440 } 00441 } 00442 00443 - (void)hide:(BOOL)animated { 00444 useAnimation = animated; 00445 00446 // If the minShow time is set, calculate how long the hud was shown, 00447 // and pospone the hiding operation if necessary 00448 if (self.minShowTime > 0.0 && showStarted) { 00449 NSTimeInterval interv = [[NSDate date] timeIntervalSinceDate:showStarted]; 00450 if (interv < self.minShowTime) { 00451 self.minShowTimer = [NSTimer scheduledTimerWithTimeInterval:(self.minShowTime - interv) 00452 target:self 00453 selector:@selector(handleMinShowTimer:) 00454 userInfo:nil 00455 repeats:NO]; 00456 return; 00457 } 00458 } 00459 00460 // ... otherwise hide the HUD immediately 00461 [self hideUsingAnimation:useAnimation]; 00462 } 00463 00464 - (void)hide:(BOOL)animated afterDelay:(NSTimeInterval)delay { 00465 [self performSelector:@selector(hideDelayed:) withObject:[NSNumber numberWithBool:delay] afterDelay:delay]; 00466 } 00467 00468 - (void)hideDelayed:(NSNumber *)animated { 00469 [self hide:[animated boolValue]]; 00470 } 00471 00472 - (void)handleGraceTimer:(NSTimer *)theTimer { 00473 // Show the HUD only if the task is still running 00474 if (taskInProgress) { 00475 [self setNeedsDisplay]; 00476 [self showUsingAnimation:useAnimation]; 00477 } 00478 } 00479 00480 - (void)handleMinShowTimer:(NSTimer *)theTimer { 00481 [self hideUsingAnimation:useAnimation]; 00482 } 00483 00484 - (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(BOOL)animated { 00485 00486 methodForExecution = method; 00487 targetForExecution = [target retain]; 00488 objectForExecution = [object retain]; 00489 00490 // Launch execution in new thread 00491 taskInProgress = YES; 00492 [NSThread detachNewThreadSelector:@selector(launchExecution) toTarget:self withObject:nil]; 00493 00494 // Show HUD view 00495 [self show:animated]; 00496 } 00497 00498 - (void)launchExecution { 00499 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 00500 00501 // Start executing the requested task 00502 [targetForExecution performSelector:methodForExecution withObject:objectForExecution]; 00503 00504 // Task completed, update view in main thread (note: view operations should 00505 // be done only in the main thread) 00506 [self performSelectorOnMainThread:@selector(cleanUp) withObject:nil waitUntilDone:NO]; 00507 00508 [pool release]; 00509 } 00510 00511 - (void)animationFinished:(NSString *)animationID finished:(BOOL)finished context:(void*)context { 00512 [self done]; 00513 } 00514 00515 - (void)done { 00516 isFinished = YES; 00517 00518 // If delegate was set make the callback 00519 self.alpha = 0.0f; 00520 00521 if(delegate != nil) { 00522 if ([delegate respondsToSelector:@selector(hudWasHidden:)]) { 00523 [delegate performSelector:@selector(hudWasHidden:) withObject:self]; 00524 } else if ([delegate respondsToSelector:@selector(hudWasHidden)]) { 00525 [delegate performSelector:@selector(hudWasHidden)]; 00526 } 00527 } 00528 00529 if (removeFromSuperViewOnHide) { 00530 [self removeFromSuperview]; 00531 } 00532 } 00533 00534 - (void)cleanUp { 00535 taskInProgress = NO; 00536 00537 self.indicator = nil; 00538 00539 [targetForExecution release]; 00540 [objectForExecution release]; 00541 00542 [self hide:useAnimation]; 00543 } 00544 00545 #pragma mark - 00546 #pragma mark Fade in and Fade out 00547 00548 - (void)showUsingAnimation:(BOOL)animated { 00549 self.alpha = 0.0f; 00550 if (animated && animationType == MBProgressHUDAnimationZoom) { 00551 self.transform = CGAffineTransformConcat(rotationTransform, CGAffineTransformMakeScale(1.5f, 1.5f)); 00552 } 00553 00554 self.showStarted = [NSDate date]; 00555 // Fade in 00556 if (animated) { 00557 [UIView beginAnimations:nil context:NULL]; 00558 [UIView setAnimationDuration:0.30]; 00559 self.alpha = 1.0f; 00560 if (animationType == MBProgressHUDAnimationZoom) { 00561 self.transform = rotationTransform; 00562 } 00563 [UIView commitAnimations]; 00564 } 00565 else { 00566 self.alpha = 1.0f; 00567 } 00568 } 00569 00570 - (void)hideUsingAnimation:(BOOL)animated { 00571 // Fade out 00572 if (animated) { 00573 [UIView beginAnimations:nil context:NULL]; 00574 [UIView setAnimationDuration:0.30]; 00575 [UIView setAnimationDelegate:self]; 00576 [UIView setAnimationDidStopSelector:@selector(animationFinished: finished: context:)]; 00577 // 0.02 prevents the hud from passing through touches during the animation the hud will get completely hidden 00578 // in the done method 00579 if (animationType == MBProgressHUDAnimationZoom) { 00580 self.transform = CGAffineTransformConcat(rotationTransform, CGAffineTransformMakeScale(0.5f, 0.5f)); 00581 } 00582 self.alpha = 0.02f; 00583 [UIView commitAnimations]; 00584 } 00585 else { 00586 self.alpha = 0.0f; 00587 [self done]; 00588 } 00589 } 00590 00591 #pragma mark BG Drawing 00592 00593 - (void)drawRect:(CGRect)rect { 00594 00595 CGContextRef context = UIGraphicsGetCurrentContext(); 00596 00597 if (dimBackground) { 00598 //Gradient colours 00599 size_t gradLocationsNum = 2; 00600 CGFloat gradLocations[2] = {0.0f, 1.0f}; 00601 CGFloat gradColors[8] = {0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.75f}; 00602 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 00603 CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, gradColors, gradLocations, gradLocationsNum); 00604 CGColorSpaceRelease(colorSpace); 00605 00606 //Gradient center 00607 CGPoint gradCenter= CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2); 00608 //Gradient radius 00609 float gradRadius = MIN(self.bounds.size.width , self.bounds.size.height) ; 00610 //Gradient draw 00611 CGContextDrawRadialGradient (context, gradient, gradCenter, 00612 0, gradCenter, gradRadius, 00613 kCGGradientDrawsAfterEndLocation); 00614 CGGradientRelease(gradient); 00615 } 00616 00617 // Center HUD 00618 CGRect allRect = self.bounds; 00619 // Draw rounded HUD bacgroud rect 00620 CGRect boxRect = CGRectMake(roundf((allRect.size.width - self.width) / 2) + self.xOffset, 00621 roundf((allRect.size.height - self.height) / 2) + self.yOffset, self.width, self.height); 00622 // Corner radius 00623 float radius = 10.0f; 00624 00625 CGContextBeginPath(context); 00626 CGContextSetGrayFillColor(context, 0.0f, self.opacity); 00627 CGContextMoveToPoint(context, CGRectGetMinX(boxRect) + radius, CGRectGetMinY(boxRect)); 00628 CGContextAddArc(context, CGRectGetMaxX(boxRect) - radius, CGRectGetMinY(boxRect) + radius, radius, 3 * (float)M_PI / 2, 0, 0); 00629 CGContextAddArc(context, CGRectGetMaxX(boxRect) - radius, CGRectGetMaxY(boxRect) - radius, radius, 0, (float)M_PI / 2, 0); 00630 CGContextAddArc(context, CGRectGetMinX(boxRect) + radius, CGRectGetMaxY(boxRect) - radius, radius, (float)M_PI / 2, (float)M_PI, 0); 00631 CGContextAddArc(context, CGRectGetMinX(boxRect) + radius, CGRectGetMinY(boxRect) + radius, radius, (float)M_PI, 3 * (float)M_PI / 2, 0); 00632 CGContextClosePath(context); 00633 CGContextFillPath(context); 00634 } 00635 00636 #pragma mark - 00637 #pragma mark Manual oritentation change 00638 00639 #define RADIANS(degrees) ((degrees * (float)M_PI) / 180.0f) 00640 00641 - (void)deviceOrientationDidChange:(NSNotification *)notification { 00642 if (!self.superview) { 00643 return; 00644 } 00645 00646 if ([self.superview isKindOfClass:[UIWindow class]]) { 00647 [self setTransformForCurrentOrientation:YES]; 00648 } else { 00649 self.bounds = self.superview.bounds; 00650 [self setNeedsDisplay]; 00651 } 00652 } 00653 00654 - (void)setTransformForCurrentOrientation:(BOOL)animated { 00655 UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; 00656 NSInteger degrees = 0; 00657 00658 // Stay in sync with the superview 00659 if (self.superview) { 00660 self.bounds = self.superview.bounds; 00661 [self setNeedsDisplay]; 00662 } 00663 00664 if (UIInterfaceOrientationIsLandscape(orientation)) { 00665 if (orientation == UIInterfaceOrientationLandscapeLeft) { degrees = -90; } 00666 else { degrees = 90; } 00667 // Window coordinates differ! 00668 self.bounds = CGRectMake(0, 0, self.bounds.size.height, self.bounds.size.width); 00669 } else { 00670 if (orientation == UIInterfaceOrientationPortraitUpsideDown) { degrees = 180; } 00671 else { degrees = 0; } 00672 } 00673 00674 rotationTransform = CGAffineTransformMakeRotation(RADIANS(degrees)); 00675 00676 if (animated) { 00677 [UIView beginAnimations:nil context:nil]; 00678 } 00679 [self setTransform:rotationTransform]; 00680 if (animated) { 00681 [UIView commitAnimations]; 00682 } 00683 } 00684 00685 @end 00686 00688 00689 @implementation MBRoundProgressView 00690 00691 #pragma mark - 00692 #pragma mark Accessors 00693 00694 - (float)progress { 00695 return _progress; 00696 } 00697 00698 - (void)setProgress:(float)progress { 00699 _progress = progress; 00700 [self setNeedsDisplay]; 00701 } 00702 00703 #pragma mark - 00704 #pragma mark Lifecycle 00705 00706 - (id)init { 00707 return [self initWithFrame:CGRectMake(0.0f, 0.0f, 37.0f, 37.0f)]; 00708 } 00709 00710 - (id)initWithFrame:(CGRect)frame { 00711 self = [super initWithFrame:frame]; 00712 if (self) { 00713 self.backgroundColor = [UIColor clearColor]; 00714 self.opaque = NO; 00715 } 00716 return self; 00717 } 00718 00719 #pragma mark - 00720 #pragma mark Drawing 00721 00722 - (void)drawRect:(CGRect)rect { 00723 00724 CGRect allRect = self.bounds; 00725 CGRect circleRect = CGRectInset(allRect, 2.0f, 2.0f); 00726 00727 CGContextRef context = UIGraphicsGetCurrentContext(); 00728 00729 // Draw background 00730 CGContextSetRGBStrokeColor(context, 1.0f, 1.0f, 1.0f, 1.0f); // white 00731 CGContextSetRGBFillColor(context, 1.0f, 1.0f, 1.0f, 0.1f); // translucent white 00732 CGContextSetLineWidth(context, 2.0f); 00733 CGContextFillEllipseInRect(context, circleRect); 00734 CGContextStrokeEllipseInRect(context, circleRect); 00735 00736 // Draw progress 00737 CGPoint center = CGPointMake(allRect.size.width / 2, allRect.size.height / 2); 00738 CGFloat radius = (allRect.size.width - 4) / 2; 00739 CGFloat startAngle = - ((float)M_PI / 2); // 90 degrees 00740 CGFloat endAngle = (self.progress * 2 * (float)M_PI) + startAngle; 00741 CGContextSetRGBFillColor(context, 1.0f, 1.0f, 1.0f, 1.0f); // white 00742 CGContextMoveToPoint(context, center.x, center.y); 00743 CGContextAddArc(context, center.x, center.y, radius, startAngle, endAngle, 0); 00744 CGContextClosePath(context); 00745 CGContextFillPath(context); 00746 } 00747 00748 @end 00749