diff --git a/.gitignore b/.gitignore index 7ecfcf4c2..7de19aa6b 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ build/ *.mode1v3 *.mode2v3 *.perspectivev3 +xcuserdata/ # old skool .svn diff --git a/Demo/Classes/HudDemoAppDelegate.h b/Demo/Classes/HudDemoAppDelegate.h index 2e36b0cd0..57629b453 100644 --- a/Demo/Classes/HudDemoAppDelegate.h +++ b/Demo/Classes/HudDemoAppDelegate.h @@ -12,11 +12,11 @@ @interface HudDemoAppDelegate : NSObject { UIWindow *window; - HudDemoViewController *viewController; + UINavigationController *navController; } @property (nonatomic, retain) IBOutlet UIWindow *window; -@property (nonatomic, retain) IBOutlet HudDemoViewController *viewController; +@property (nonatomic, retain) IBOutlet UINavigationController *navController; @end diff --git a/Demo/Classes/HudDemoAppDelegate.m b/Demo/Classes/HudDemoAppDelegate.m index 50a34d427..a68acdec8 100644 --- a/Demo/Classes/HudDemoAppDelegate.m +++ b/Demo/Classes/HudDemoAppDelegate.m @@ -12,19 +12,19 @@ @implementation HudDemoAppDelegate @synthesize window; -@synthesize viewController; +@synthesize navController; - (void)applicationDidFinishLaunching:(UIApplication *)application { // Override point for customization after app launch - [window addSubview:viewController.view]; + [window addSubview:navController.view]; [window makeKeyAndVisible]; } - (void)dealloc { - [viewController release]; + [navController release]; [window release]; [super dealloc]; } diff --git a/Demo/Classes/HudDemoViewController.h b/Demo/Classes/HudDemoViewController.h index 78e930f72..940eeca6f 100644 --- a/Demo/Classes/HudDemoViewController.h +++ b/Demo/Classes/HudDemoViewController.h @@ -17,7 +17,10 @@ - (IBAction)showWithLabel:(id)sender; - (IBAction)showWithDetailsLabel:(id)sender; - (IBAction)showWithLabelDeterminate:(id)sender; +- (IBAction)showWithCustomView:(id)sender; - (IBAction)showWithLabelMixed:(id)sender; +- (IBAction)showUsingBlocks:(id)sender; +- (IBAction)showOnWindow:(id)sender; - (void)myTask; - (void)myProgressTask; diff --git a/Demo/Classes/HudDemoViewController.m b/Demo/Classes/HudDemoViewController.m index c14d7e026..6c31aa415 100644 --- a/Demo/Classes/HudDemoViewController.m +++ b/Demo/Classes/HudDemoViewController.m @@ -7,12 +7,18 @@ // #import "HudDemoViewController.h" +#import @implementation HudDemoViewController #pragma mark - #pragma mark Lifecycle methods +- (void)viewDidLoad { + UIView *content = [[self.view subviews] objectAtIndex:0]; + ((UIScrollView *)self.view).contentSize = content.bounds.size; +} + - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview // Release anything that's not essential, such as cached data @@ -25,6 +31,11 @@ - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interface return YES; } +- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { + UIView *content = [[self.view subviews] objectAtIndex:0]; + ((UIScrollView *)self.view).contentSize = content.bounds.size; +} + - (void)dealloc { [super dealloc]; } @@ -33,14 +44,14 @@ - (void)dealloc { #pragma mark IBActions - (IBAction)showSimple:(id)sender { - // The hud will dispable all input on the view - HUD = [[MBProgressHUD alloc] initWithView:self.view]; + // The hud will dispable all input on the view (use the higest view possible in the view hierarchy) + HUD = [[MBProgressHUD alloc] initWithView:self.navigationController.view]; //HUD.graceTime = 0.5; //HUD.minShowTime = 5.0; // Add HUD to screen - [self.view addSubview:HUD]; + [self.navigationController.view addSubview:HUD]; // Regisete for HUD callbacks so we can remove it from the window at the right time HUD.delegate = self; @@ -50,11 +61,11 @@ - (IBAction)showSimple:(id)sender { } - (IBAction)showWithLabel:(id)sender { - // The hud will dispable all input on the view - HUD = [[MBProgressHUD alloc] initWithView:self.view]; + // The hud will dispable all input on the view (use the higest view possible in the view hierarchy) + HUD = [[MBProgressHUD alloc] initWithView:self.navigationController.view]; // Add HUD to screen - [self.view addSubview:HUD]; + [self.navigationController.view addSubview:HUD]; // Regisete for HUD callbacks so we can remove it from the window at the right time HUD.delegate = self; @@ -66,11 +77,11 @@ - (IBAction)showWithLabel:(id)sender { } - (IBAction)showWithDetailsLabel:(id)sender { - // The hud will dispable all input on the view - HUD = [[MBProgressHUD alloc] initWithView:self.view]; + // The hud will dispable all input on the view (use the higest view possible in the view hierarchy) + HUD = [[MBProgressHUD alloc] initWithView:self.navigationController.view]; // Add HUD to screen - [self.view addSubview:HUD]; + [self.navigationController.view addSubview:HUD]; // Regisete for HUD callbacks so we can remove it from the window at the right time HUD.delegate = self; @@ -83,14 +94,14 @@ - (IBAction)showWithDetailsLabel:(id)sender { } - (IBAction)showWithLabelDeterminate:(id)sender { - // The hud will dispable all input on the view - HUD = [[MBProgressHUD alloc] initWithView:self.view]; + // The hud will dispable all input on the view (use the higest view possible in the view hierarchy) + HUD = [[MBProgressHUD alloc] initWithView:self.navigationController.view]; // Set determinate mode HUD.mode = MBProgressHUDModeDeterminate; // Add HUD to screen - [self.view addSubview:HUD]; + [self.navigationController.view addSubview:HUD]; // Regisete for HUD callbacks so we can remove it from the window at the right time HUD.delegate = self; @@ -101,12 +112,38 @@ - (IBAction)showWithLabelDeterminate:(id)sender { [HUD showWhileExecuting:@selector(myProgressTask) onTarget:self withObject:nil animated:YES]; } +- (IBAction)showWithCustomView:(id)sender { + // The hud will dispable all input on the view (use the higest view possible in the view hierarchy) + HUD = [[MBProgressHUD alloc] initWithView:self.navigationController.view]; + + // The sample image is based on the work by www.pixelpressicons.com, http://creativecommons.org/licenses/by/2.5/ca/ + // Make the customViews 37 by 37 pixels for best results (those are the bounds of the build-in progress indicators) + HUD.customView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"37x-Checkmark.png"]] autorelease]; + + // Set custom view mode + HUD.mode = MBProgressHUDModeCustomView; + + // Add HUD to screen + [self.navigationController.view addSubview:HUD]; + + // Regisete for HUD callbacks so we can remove it from the window at the right time + HUD.delegate = self; + + HUD.labelText = @"Completed"; + + // This would only show the completed text with no visible custom view + // HUD.customView = [[UIView alloc] initWithFrame:CGRectZero]; + + // Show the HUD while the provided method executes in a new thread + [HUD showWhileExecuting:@selector(myProgressTask) onTarget:self withObject:nil animated:YES]; +} + - (IBAction)showWithLabelMixed:(id)sender { - // The hud will dispable all input on the view - HUD = [[MBProgressHUD alloc] initWithView:self.view]; + // The hud will dispable all input on the view (use the higest view possible in the view hierarchy) + HUD = [[MBProgressHUD alloc] initWithView:self.navigationController.view]; // Add HUD to screen - [self.view addSubview:HUD]; + [self.navigationController.view addSubview:HUD]; // Regisete for HUD callbacks so we can remove it from the window at the right time HUD.delegate = self; @@ -117,6 +154,41 @@ - (IBAction)showWithLabelMixed:(id)sender { [HUD showWhileExecuting:@selector(myMixedTask) onTarget:self withObject:nil animated:YES]; } +- (IBAction)showUsingBlocks:(id)sender { + dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ + // Show the HUD in the main tread + dispatch_async(dispatch_get_main_queue(), ^{ + // No need to hod onto (retain) + MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES]; + hud.labelText = @"Loading"; + }); + + // Do a taks in the background + [self myTask]; + + // Hide the HUD in the main tread + dispatch_async(dispatch_get_main_queue(), ^{ + [MBProgressHUD hideHUDForView:self.navigationController.view animated:YES]; + }); + }); +} + +- (IBAction)showOnWindow:(id)sender { + // The hud will dispable all input on the view + HUD = [[MBProgressHUD alloc] initWithView:self.view.window]; + + // Add HUD to screen + [self.view.window addSubview:HUD]; + + // Regisete for HUD callbacks so we can remove it from the window at the right time + HUD.delegate = self; + + HUD.labelText = @"Loading"; + + // Show the HUD while the provided method executes in a new thread + [HUD showWhileExecuting:@selector(myTask) onTarget:self withObject:nil animated:YES]; +} + #pragma mark - #pragma mark Execution code @@ -155,6 +227,12 @@ - (void)myMixedTask { HUD.mode = MBProgressHUDModeIndeterminate; HUD.labelText = @"Cleaning up"; sleep(2); + // The sample image is based on the work by www.pixelpressicons.com, http://creativecommons.org/licenses/by/2.5/ca/ + // Make the customViews 37 by 37 pixels for best results (those are the bounds of the build-in progress indicators) + HUD.customView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"37x-Checkmark.png"]] autorelease]; + HUD.mode = MBProgressHUDModeCustomView; + HUD.labelText = @"Completed"; + sleep(2); } #pragma mark - diff --git a/Demo/Default.png b/Demo/Default.png new file mode 100644 index 000000000..1f8a9792e Binary files /dev/null and b/Demo/Default.png differ diff --git a/Demo/HudDemo.xcodeproj/project.pbxproj b/Demo/HudDemo.xcodeproj/project.pbxproj index 61fcc81c4..bfb8e913d 100755 --- a/Demo/HudDemo.xcodeproj/project.pbxproj +++ b/Demo/HudDemo.xcodeproj/project.pbxproj @@ -16,6 +16,10 @@ 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; 28D7ACF80DDB3853001CB0EB /* HudDemoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28D7ACF70DDB3853001CB0EB /* HudDemoViewController.m */; }; D22F7D810F85241C00550BB3 /* MBProgressHUD.m in Sources */ = {isa = PBXBuildFile; fileRef = D22F7D800F85241C00550BB3 /* MBProgressHUD.m */; }; + D277FDB311FC834200304321 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = D277FDB211FC834200304321 /* Default.png */; }; + D277FDB911FC877E00304321 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = D277FDB711FC877E00304321 /* Icon.png */; }; + D277FDBA11FC877E00304321 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D277FDB811FC877E00304321 /* Icon@2x.png */; }; + D2F88CD6115E9F7F00E6DB82 /* 37x-Checkmark.png in Resources */ = {isa = PBXBuildFile; fileRef = D2F88CD5115E9F7F00E6DB82 /* 37x-Checkmark.png */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -28,12 +32,16 @@ 2899E5210DE3E06400AC0155 /* HudDemoViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HudDemoViewController.xib; sourceTree = ""; }; 28AD733E0D9D9553002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = ""; }; 28D7ACF60DDB3853001CB0EB /* HudDemoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HudDemoViewController.h; sourceTree = ""; }; - 28D7ACF70DDB3853001CB0EB /* HudDemoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HudDemoViewController.m; sourceTree = ""; }; + 28D7ACF70DDB3853001CB0EB /* HudDemoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HudDemoViewController.m; sourceTree = ""; usesTabs = 1; }; 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 32CA4F630368D1EE00C91783 /* HudDemo_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HudDemo_Prefix.pch; sourceTree = ""; }; 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; D22F7D7F0F85241C00550BB3 /* MBProgressHUD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MBProgressHUD.h; path = ../MBProgressHUD.h; sourceTree = SOURCE_ROOT; }; D22F7D800F85241C00550BB3 /* MBProgressHUD.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MBProgressHUD.m; path = ../../MBProgressHUD.m; sourceTree = ""; }; + D277FDB211FC834200304321 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + D277FDB711FC877E00304321 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + D277FDB811FC877E00304321 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; + D2F88CD5115E9F7F00E6DB82 /* 37x-Checkmark.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "37x-Checkmark.png"; path = "Images/37x-Checkmark.png"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -95,8 +103,8 @@ 29B97317FDCFA39411CA2CEA /* Resources */ = { isa = PBXGroup; children = ( - 2899E5210DE3E06400AC0155 /* HudDemoViewController.xib */, - 28AD733E0D9D9553002E5188 /* MainWindow.xib */, + D277FDBF11FC880100304321 /* UI */, + D277FDBD11FC879500304321 /* Images */, 8D1107310486CEB800E47090 /* Info.plist */, ); name = Resources; @@ -112,6 +120,26 @@ name = Frameworks; sourceTree = ""; }; + D277FDBD11FC879500304321 /* Images */ = { + isa = PBXGroup; + children = ( + D277FDB711FC877E00304321 /* Icon.png */, + D277FDB811FC877E00304321 /* Icon@2x.png */, + D277FDB211FC834200304321 /* Default.png */, + D2F88CD5115E9F7F00E6DB82 /* 37x-Checkmark.png */, + ); + name = Images; + sourceTree = ""; + }; + D277FDBF11FC880100304321 /* UI */ = { + isa = PBXGroup; + children = ( + 2899E5210DE3E06400AC0155 /* HudDemoViewController.xib */, + 28AD733E0D9D9553002E5188 /* MainWindow.xib */, + ); + name = UI; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -156,6 +184,10 @@ files = ( 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */, 2899E5220DE3E06400AC0155 /* HudDemoViewController.xib in Resources */, + D2F88CD6115E9F7F00E6DB82 /* 37x-Checkmark.png in Resources */, + D277FDB311FC834200304321 /* Default.png in Resources */, + D277FDB911FC877E00304321 /* Icon.png in Resources */, + D277FDBA11FC877E00304321 /* Icon@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -208,11 +240,12 @@ ARCHS = "$(ARCHS_STANDARD_32_BIT)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; ONLY_ACTIVE_ARCH = YES; PREBINDING = NO; - SDKROOT = iphoneos2.2; + SDKROOT = iphoneos4.0; }; name = Debug; }; @@ -222,10 +255,11 @@ ARCHS = "$(ARCHS_STANDARD_32_BIT)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; PREBINDING = NO; - SDKROOT = iphoneos2.2; + SDKROOT = iphoneos4.0; }; name = Release; }; diff --git a/Demo/HudDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Demo/HudDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..9410801df --- /dev/null +++ b/Demo/HudDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,6 @@ + + + + + diff --git a/Demo/HudDemoViewController.xib b/Demo/HudDemoViewController.xib index 8e3538b60..93ce51012 100644 --- a/Demo/HudDemoViewController.xib +++ b/Demo/HudDemoViewController.xib @@ -2,17 +2,17 @@ 528 - 10C540 - 740 - 1038.25 - 458.00 + 10F569 + 788 + 1038.29 + 461.00 com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 62 + 117 YES - + YES @@ -31,145 +31,217 @@ YES IBFilesOwner + IBCocoaTouchFramework IBFirstResponder + IBCocoaTouchFramework - + 274 YES - - - 294 - {{20, 20}, {280, 40}} - - NO - NO - 0 - 0 - - Helvetica-Bold - 15 - 16 - - 1 - Simple indeterminate progress - - 1 - MSAxIDEAA - - - 1 - MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA - - - 3 - MAA - - - - - 294 - {{20, 68}, {280, 40}} - - NO - NO - 0 - 0 - - 1 - With label - - - 1 - MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA - - - - - - 294 - {{20, 116}, {280, 40}} - - NO - NO - 0 - 0 - - 1 - With details label - With details label - With details label - With details label - - - 1 - MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA + + + 290 + + YES + + + 294 + {{20, 20}, {280, 40}} + + NO + NO + IBCocoaTouchFramework + 0 + 3 + + Helvetica-Bold + 15 + 16 + + 1 + Simple indeterminate progress + + 1 + MSAxIDEAA + + + 1 + MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA + + + 3 + MAA + + + + + 294 + {{20, 68}, {280, 40}} + + NO + NO + IBCocoaTouchFramework + 0 + 3 + + 1 + With label + + + 1 + MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA + + + + + + 294 + {{20, 116}, {280, 40}} + + NO + NO + IBCocoaTouchFramework + 0 + 3 + + 1 + With details label + With details label + With details label + With details label + + + 1 + MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA + + + + + + 294 + {{20, 164}, {280, 40}} + + NO + NO + IBCocoaTouchFramework + 0 + 3 + + 1 + Determinate mode + + + 1 + MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA + + + + + + 294 + {{20, 260}, {280, 40}} + + NO + NO + IBCocoaTouchFramework + 0 + 3 + + 1 + Mode switching + + + 1 + MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA + + + + + + 294 + {{20, 308}, {280, 40}} + + NO + NO + IBCocoaTouchFramework + 0 + 3 + + 1 + GCD and blocks + + + 1 + MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA + + + + + + 294 + {{20, 356}, {280, 40}} + + NO + NO + IBCocoaTouchFramework + 0 + 3 + + 1 + On Window + + + 1 + MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA + + + + + + 294 + {{20, 212}, {280, 40}} + + NO + NO + IBCocoaTouchFramework + 0 + 3 + + 1 + Custom view + + + 1 + MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA + + + - - - - - 294 - {{20, 164}, {280, 40}} - - NO - NO - 0 - 0 - - 1 - Determinate mode - - + {320, 416} + + 1 - MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA + MC44ODYyNzQ1MDk4IDAuOTA1ODgyMzUyOSAwLjkyOTQxMTc2NDcAA - - - - - 294 - {{20, 212}, {280, 40}} - - NO NO - 0 - 0 - - 1 - Mode switching - - - 1 - MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA - - + + IBCocoaTouchFramework {320, 460} - - 1 - MC43NjQ0MTc3MSAwLjgxMjIyNzg1IDAuODIxMTc5NTEAA - - NO - + YES + YES + IBCocoaTouchFramework YES - - - view - - - - 7 - showSimple: @@ -215,6 +287,41 @@ 21 + + + showWithCustomView: + + + 7 + + 47 + + + + showUsingBlocks: + + + 7 + + 51 + + + + view + + + + 70 + + + + showOnWindow: + + + 7 + + 73 + @@ -237,8 +344,17 @@ - 6 - + 52 + + + YES + + + + + + 54 + YES @@ -246,33 +362,51 @@ + + + - + - 20 - - + 8 + + - 16 - - + 9 + + 10 - + - 9 - - + 16 + + - 8 - - + 20 + + + + + 49 + + + + + 43 + + + + + 71 + + @@ -285,8 +419,13 @@ 10.IBPluginDependency 16.IBPluginDependency 20.IBPluginDependency - 6.IBEditorWindowLastContentRect - 6.IBPluginDependency + 43.IBPluginDependency + 49.IBPluginDependency + 52.IBEditorWindowLastContentRect + 52.IBPluginDependency + 54.IBEditorWindowLastContentRect + 54.IBPluginDependency + 71.IBPluginDependency 8.IBPluginDependency 9.IBPluginDependency @@ -297,7 +436,12 @@ com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin - {{179, 181}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{245, 110}, {320, 460}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{217, 96}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -319,7 +463,7 @@ - 42 + 73 @@ -331,7 +475,10 @@ YES YES + showOnWindow: showSimple: + showUsingBlocks: + showWithCustomView: showWithDetailsLabel: showWithLabel: showWithLabelDeterminate: @@ -344,6 +491,58 @@ id id id + id + id + id + + + + YES + + YES + showOnWindow: + showSimple: + showUsingBlocks: + showWithCustomView: + showWithDetailsLabel: + showWithLabel: + showWithLabelDeterminate: + showWithLabelMixed: + + + YES + + showOnWindow: + id + + + showSimple: + id + + + showUsingBlocks: + id + + + showWithCustomView: + id + + + showWithDetailsLabel: + id + + + showWithLabel: + id + + + showWithLabelDeterminate: + id + + + showWithLabelMixed: + id + @@ -352,15 +551,206 @@ + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIButton + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UIButton.h + + + + UIControl + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIControl.h + + + + UIResponder + NSObject + + + + UIScrollView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIScrollView.h + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UIPopoverController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UISplitViewController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + 0 + IBCocoaTouchFramework com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS - + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 @@ -369,6 +759,6 @@ YES HudDemo.xcodeproj 3 - 3.1 + 117 diff --git a/Demo/Icon.png b/Demo/Icon.png new file mode 100644 index 000000000..430cb6c27 Binary files /dev/null and b/Demo/Icon.png differ diff --git a/Demo/Icon@2x.png b/Demo/Icon@2x.png new file mode 100644 index 000000000..68d2e0bef Binary files /dev/null and b/Demo/Icon@2x.png differ diff --git a/Demo/Images/37x-Checkmark.png b/Demo/Images/37x-Checkmark.png new file mode 100644 index 000000000..65f1ab6da Binary files /dev/null and b/Demo/Images/37x-Checkmark.png differ diff --git a/Demo/Info.plist b/Demo/Info.plist index fdf834060..cd4302bc7 100644 --- a/Demo/Info.plist +++ b/Demo/Info.plist @@ -11,7 +11,7 @@ CFBundleIconFile CFBundleIdentifier - com.yourcompany.${PRODUCT_NAME:identifier} + com.bukovinski.${PRODUCT_NAME:identifier} CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/Demo/MainWindow.xib b/Demo/MainWindow.xib index b72ae0d5d..e8a8990a2 100644 --- a/Demo/MainWindow.xib +++ b/Demo/MainWindow.xib @@ -1,31 +1,43 @@ - + 528 - 9E17 - 672 - 949.33 - 352.00 + 10F569 + 788 + 1038.29 + 461.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 117 + YES - YES com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + YES + + + YES + + YES IBFilesOwner + IBCocoaTouchFramework IBFirstResponder + IBCocoaTouchFramework - - - HudDemoViewController - + + IBCocoaTouchFramework @@ -33,11 +45,46 @@ {320, 480} 1 - MSAxIDEAA + MC44ODYyNzQ1MDk4IDAuOTA1ODgyMzUyOSAwLjkyOTQxMTc2NDcAA NO NO + IBCocoaTouchFramework + + + + + 1 + + IBCocoaTouchFramework + NO + + + 256 + {0, 0} + NO + YES + YES + IBCocoaTouchFramework + + + YES + + MBProgressHUD + + MBProgressHUD + IBCocoaTouchFramework + + + HudDemoViewController + + 1 + + IBCocoaTouchFramework + NO + + @@ -53,19 +100,19 @@ - viewController + window - + - 11 + 14 - window + navController - + - 14 + 19 @@ -73,52 +120,77 @@ YES 0 - - YES - + -1 - - RmlsZSdzIE93bmVyA + + File's Owner 3 - + HudDemo App Delegate -2 - - - - 10 - - + 12 - + + + + 15 + + + YES + + + + + + + 16 + + + YES + + + + + + 17 + + + + + 18 + + YES - + YES -1.CustomClassName -2.CustomClassName - 10.CustomClassName - 10.IBEditorWindowLastContentRect - 10.IBPluginDependency 12.IBEditorWindowLastContentRect 12.IBPluginDependency + 15.IBEditorWindowLastContentRect + 15.IBPluginDependency + 16.CustomClassName + 16.IBPluginDependency + 17.IBPluginDependency + 18.IBPluginDependency 3.CustomClassName 3.IBPluginDependency @@ -126,10 +198,13 @@ YES UIApplication UIResponder + {{525, 346}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{150, 451}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin HudDemoViewController - {{512, 351}, {320, 480}} com.apple.InterfaceBuilder.IBCocoaTouchPlugin - {{525, 346}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin HudDemoAppDelegate com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -137,9 +212,7 @@ YES - - YES - + YES @@ -147,15 +220,13 @@ YES - - YES - + YES - 14 + 19 @@ -165,17 +236,36 @@ NSObject YES - + YES - viewController + navController window YES - HudDemoViewController + UINavigationController UIWindow + + YES + + YES + navController + window + + + YES + + navController + UINavigationController + + + window + UIWindow + + + IBProjectSource Classes/HudDemoAppDelegate.h @@ -192,15 +282,313 @@ HudDemoViewController UIViewController + + YES + + YES + showSimple: + showUsingBlocks: + showWithCustomView: + showWithDetailsLabel: + showWithLabel: + showWithLabelDeterminate: + showWithLabelMixed: + + + YES + id + id + id + id + id + id + id + + + + YES + + YES + showSimple: + showUsingBlocks: + showWithCustomView: + showWithDetailsLabel: + showWithLabel: + showWithLabelDeterminate: + showWithLabelMixed: + + + YES + + showSimple: + id + + + showUsingBlocks: + id + + + showWithCustomView: + id + + + showWithDetailsLabel: + id + + + showWithLabel: + id + + + showWithLabelDeterminate: + id + + + showWithLabelMixed: + id + + + IBProjectSource Classes/HudDemoViewController.h + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIApplication + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIApplication.h + + + + UIBarButtonItem + UIBarItem + + IBFrameworkSource + UIKit.framework/Headers/UIBarButtonItem.h + + + + UIBarItem + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIBarItem.h + + + + UINavigationBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UINavigationBar.h + + + + UINavigationController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UINavigationItem + NSObject + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UIPopoverController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UISplitViewController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + UIWindow + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIWindow.h + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES HudDemo.xcodeproj 3 + 117 diff --git a/MBProgressHUD.h b/MBProgressHUD.h index 86597305d..a3770e3b1 100644 --- a/MBProgressHUD.h +++ b/MBProgressHUD.h @@ -1,7 +1,7 @@ // // MBProgressHUD.h -// Version 0.32 -// Created by Matej Bukovinski on 04.01.10. +// Version 0.4 +// Created by Matej Bukovinski on 2.4.09. // // This code is distributed under the terms and conditions of the MIT license. @@ -28,23 +28,30 @@ #import -/** - * MBProgressHUD operation modes. - */ +///////////////////////////////////////////////////////////////////////////////////////////// + typedef enum { /** Progress is shown using an UIActivityIndicatorView. This is the default. */ MBProgressHUDModeIndeterminate, /** Progress is shown using a MBRoundProgressView. */ MBProgressHUDModeDeterminate, + /** Shows a custom view */ + MBProgressHUDModeCustomView } MBProgressHUDMode; +typedef enum { + /** Opacity animation */ + MBProgressHUDAnimationFade, + /** Opacity + scale animation */ + MBProgressHUDAnimationZoom +} MBProgressHUDAnimation; + +///////////////////////////////////////////////////////////////////////////////////////////// -/** - * Defines callback methods for MBProgressHUD delegates. - */ @protocol MBProgressHUDDelegate @required + /** * A callback function that is called after the HUD was fully hidden from the screen. */ @@ -52,13 +59,12 @@ typedef enum { @end +///////////////////////////////////////////////////////////////////////////////////////////// /** * A progress view for showing definite progress by filling up a circle (similar to the indicator for building in xcode). */ -@interface MBRoundProgressView : UIProgressView { - -} +@interface MBRoundProgressView : UIProgressView {} /** * Create a 37 by 37 pixel indicator. @@ -68,8 +74,10 @@ typedef enum { @end +///////////////////////////////////////////////////////////////////////////////////////////// + /** - * Displays a simple HUD window containing a UIActivityIndicatorView and two optional labels for short messages. + * Displays a simple HUD window containing a progress indicator and two optional labels for short messages. * * This is a simple drop-in class for displaying a progress HUD view similar to Apples private UIProgressHUD class. * The MBProgressHUD window spans over the entire space given to it by the initWithFrame constructor and catches all @@ -77,23 +85,28 @@ typedef enum { * drawn centered as a rounded semi-transparent view witch resizes depending on the user specified content. * * This view supports three modes of operation: - * - The default mode displays just a UIActivityIndicatorView. + * - MBProgressHUDModeIndeterminate - shows a UIActivityIndicatorView + * - MBProgressHUDModeDeterminate - shows a custom round progress indicator (MBRoundProgressView) + * - MBProgressHUDModeCustomView - shows an arbitrary, user specified view (@see customView) + * + * All three modes can have optional labels assigned: * - If the labelText property is set and non-empty then a label containing the provided content is placed below the - * UIActivityIndicatorView. + * indicator view. * - If also the detailsLabelText property is set then another label is placed below the first label. */ @interface MBProgressHUD : UIView { MBProgressHUDMode mode; - + MBProgressHUDAnimation animationType; + SEL methodForExecution; id targetForExecution; id objectForExecution; BOOL useAnimation; - + float yOffset; float xOffset; - + float width; float height; @@ -103,23 +116,52 @@ typedef enum { NSTimer *graceTimer; NSTimer *minShowTimer; NSDate *showStarted; - + UIView *indicator; UILabel *label; UILabel *detailsLabel; - + float progress; - + id delegate; NSString *labelText; NSString *detailsLabelText; float opacity; UIFont *labelFont; UIFont *detailsLabelFont; - + BOOL isFinished; + BOOL removeFromSuperViewOnHide; + + UIView *customView; + + CGAffineTransform rotationTransform; } +/** + * Creates a new hud, adds it to provided view and shows it. The counterpart to this method is hideHUDForView:animated:. + * + * @param view The view that the HUD will be added to + * @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use + * animations while disappearing. + * @return A reference to the created HUD. + * + * @see hideHUDForView:animated: + */ ++ (MBProgressHUD *)showHUDAddedTo:(UIView *)view animated:(BOOL)animated; + +/** + * Finds a HUD sibview and hides it. The counterpart to this method is showHUDAddedTo:animated:. + * + * @param view The view that is going to be searched for a HUD subview. + * @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use + * animations while disappearing. + * @return YES if a HUD was found and removed, NO otherwise. + * + * @see hideHUDForView:animated: + */ ++ (BOOL)hideHUDForView:(UIView *)view animated:(BOOL)animated; + /** * A convenience constructor that initializes the HUD with the window's bounds. Calls the designated constructor with * window.bounds as the parameter. @@ -138,12 +180,27 @@ typedef enum { */ - (id)initWithView:(UIView *)view; +/** + * The UIView (i.g., a UIIMageView) to be shown when the HUD is in MBProgressHUDModeCustomView. + * For best results use a 37 by 37 pixel view (so the bounds match the build in indicator bounds). + */ +@property (retain) UIView *customView; + /** * MBProgressHUD operation mode. Switches between indeterminate (MBProgressHUDModeIndeterminate) and determinate * progress (MBProgressHUDModeDeterminate). The default is MBProgressHUDModeIndeterminate. + * + * @see MBProgressHUDMode */ @property (assign) MBProgressHUDMode mode; +/** + * The animation type that should be used when the HUD is shown and hidden. + * + * @see MBProgressHUDAnimation + */ +@property (assign) MBProgressHUDAnimation animationType; + /** * The HUD delegate object. If set the delegate will receive hudWasHidden callbacks when the HUD was hidden. The * delegate should conform to the MBProgressHUDDelegate protocol and implement the hudWasHidden method. The delegate @@ -208,6 +265,12 @@ typedef enum { */ @property (assign) BOOL taskInProgress; +/** + * Removes the HUD from it's parent view when hidden. + * Defaults to NO. + */ +@property (assign) BOOL removeFromSuperViewOnHide; + /** * Font to be used for the main label. Set this property if the default is not adequate. */ @@ -228,8 +291,8 @@ typedef enum { * the user interface can be updated. Call this method when your task is already set-up to be executed in a new thread * (e.g., when using something like NSOperation or calling an asynchronous call like NSUrlRequest). * - * @param animated If set to YES the HUD will appear using a fade animation. If set to NO the HUD will not use - * animations while appearing. + * @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use + * animations while disappearing. */ - (void)show:(BOOL)animated; @@ -237,7 +300,7 @@ typedef enum { * Hide the HUD, this still calls the hudWasHidden delegate. This is the counterpart of the hide: method. Use it to * hide the HUD when your task completes. * - * @param animated If set to YES the HUD will disappear using a fade animation. If set to NO the HUD will not use + * @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use * animations while disappearing. */ - (void)hide:(BOOL)animated; @@ -251,8 +314,8 @@ typedef enum { * @param method The method to be executed while the HUD is shown. This method will be executed in a new thread. * @param target The object that the target method belongs to. * @param object An optional object to be passed to the method. - * @param animated If set to YES the HUD will appear and disappear using a fade animation. If set to NO the HUD will - * not use animations while appearing and disappearing. + * @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use + * animations while disappearing. */ - (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(BOOL)animated; diff --git a/MBProgressHUD.m b/MBProgressHUD.m index bcfdc96fe..808b9352c 100644 --- a/MBProgressHUD.m +++ b/MBProgressHUD.m @@ -1,7 +1,7 @@ // // MBProgressHUD.m -// Version 0.32 -// Created by Matej Bukovinski on 04.01.10. +// Version 0.4 +// Created by Matej Bukovinski on 2.4.09. // #import "MBProgressHUD.h" @@ -10,27 +10,21 @@ @interface MBProgressHUD () - (void)hideUsingAnimation:(BOOL)animated; - (void)showUsingAnimation:(BOOL)animated; - - (void)fillRoundedRect:(CGRect)rect inContext:(CGContextRef)context; - - (void)done; - - (void)updateLabelText:(NSString *)newText; - (void)updateDetailsLabelText:(NSString *)newText; - (void)updateProgress; - (void)updateIndicators; - - (void)handleGraceTimer:(NSTimer *)theTimer; - (void)handleMinShowTimer:(NSTimer *)theTimer; +- (void)setTransformForCurrentOrientation:(BOOL)animated; @property (retain) UIView *indicator; - @property (assign) float width; @property (assign) float height; - @property (retain) NSTimer *graceTimer; @property (retain) NSTimer *minShowTimer; - @property (retain) NSDate *showStarted; @end @@ -41,15 +35,12 @@ @implementation MBProgressHUD #pragma mark - #pragma mark Accessors -@synthesize mode; +@synthesize animationType; @synthesize delegate; -@synthesize labelText; -@synthesize detailsLabelText; @synthesize opacity; @synthesize labelFont; @synthesize detailsLabelFont; -@synthesize progress; @synthesize indicator; @@ -63,6 +54,9 @@ @implementation MBProgressHUD @synthesize graceTimer; @synthesize minShowTimer; @synthesize taskInProgress; +@synthesize removeFromSuperViewOnHide; + +@synthesize customView; @synthesize showStarted; @@ -71,36 +65,75 @@ - (void)setMode:(MBProgressHUDMode)newMode { if (mode && (mode == newMode)) { return; } - + mode = newMode; + + if ([NSThread isMainThread]) { + [self updateIndicators]; + [self setNeedsLayout]; + [self setNeedsDisplay]; + } else { + [self performSelectorOnMainThread:@selector(updateIndicators) withObject:nil waitUntilDone:NO]; + [self performSelectorOnMainThread:@selector(setNeedsLayout) withObject:nil waitUntilDone:NO]; + [self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO]; + } +} - [self performSelectorOnMainThread:@selector(updateIndicators) withObject:nil waitUntilDone:NO]; - [self performSelectorOnMainThread:@selector(setNeedsLayout) withObject:nil waitUntilDone:NO]; - [self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO]; +- (MBProgressHUDMode)mode { + return mode; } - (void)setLabelText:(NSString *)newText { - [self performSelectorOnMainThread:@selector(updateLabelText:) withObject:newText waitUntilDone:NO]; - [self performSelectorOnMainThread:@selector(setNeedsLayout) withObject:nil waitUntilDone:NO]; - [self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO]; + if ([NSThread isMainThread]) { + [self updateLabelText:newText]; + [self setNeedsLayout]; + [self setNeedsDisplay]; + } else { + [self performSelectorOnMainThread:@selector(updateLabelText:) withObject:newText waitUntilDone:NO]; + [self performSelectorOnMainThread:@selector(setNeedsLayout) withObject:nil waitUntilDone:NO]; + [self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO]; + } +} + +- (NSString *)labelText { + return labelText; } - (void)setDetailsLabelText:(NSString *)newText { - [self performSelectorOnMainThread:@selector(updateDetailsLabelText:) withObject:newText waitUntilDone:NO]; - [self performSelectorOnMainThread:@selector(setNeedsLayout) withObject:nil waitUntilDone:NO]; - [self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO]; + if ([NSThread isMainThread]) { + [self updateDetailsLabelText:newText]; + [self setNeedsLayout]; + [self setNeedsDisplay]; + } else { + [self performSelectorOnMainThread:@selector(updateDetailsLabelText:) withObject:newText waitUntilDone:NO]; + [self performSelectorOnMainThread:@selector(setNeedsLayout) withObject:nil waitUntilDone:NO]; + [self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO]; + } +} + +- (NSString *)detailsLabelText { + return detailsLabelText; } - (void)setProgress:(float)newProgress { progress = newProgress; - + // Update display ony if showing the determinate progress view if (mode == MBProgressHUDModeDeterminate) { - [self performSelectorOnMainThread:@selector(updateProgress) withObject:nil waitUntilDone:NO]; - [self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO]; + if ([NSThread isMainThread]) { + [self updateProgress]; + [self setNeedsDisplay]; + } else { + [self performSelectorOnMainThread:@selector(updateProgress) withObject:nil waitUntilDone:NO]; + [self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO]; + } } } +- (float)progress { + return progress; +} + #pragma mark - #pragma mark Accessor helpers @@ -126,18 +159,19 @@ - (void)updateIndicators { if (indicator) { [indicator removeFromSuperview]; } - - self.indicator = nil; if (mode == MBProgressHUDModeDeterminate) { - indicator = [[MBRoundProgressView alloc] initWithDefaultSize]; + self.indicator = [[[MBRoundProgressView alloc] initWithDefaultSize] autorelease]; } - else { - indicator = [[UIActivityIndicatorView alloc] - initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; + else if (mode == MBProgressHUDModeCustomView && self.customView != nil){ + self.indicator = self.customView; + } else { + self.indicator = [[[UIActivityIndicatorView alloc] + initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge] autorelease]; [(UIActivityIndicatorView *)indicator startAnimating]; - } - + } + + [self addSubview:indicator]; } @@ -147,11 +181,40 @@ - (void)updateIndicators { #define MARGIN 20.0 #define PADDING 4.0 -#define LABELFONTSIZE 22.0 -#define LABELDETAILSFONTSIZE 16.0 +#define LABELFONTSIZE 16.0 +#define LABELDETAILSFONTSIZE 12.0 #define PI 3.14159265358979323846 + +#pragma mark - +#pragma mark Class methods + ++ (MBProgressHUD *)showHUDAddedTo:(UIView *)view animated:(BOOL)animated { + MBProgressHUD *hud = [[MBProgressHUD alloc] initWithView:view]; + [view addSubview:hud]; + [hud show:animated]; + return [hud autorelease]; +} + ++ (BOOL)hideHUDForView:(UIView *)view animated:(BOOL)animated { + UIView *viewToRemove = nil; + for (UIView *v in [view subviews]) { + if ([v isKindOfClass:[MBProgressHUD class]]) { + viewToRemove = v; + } + } + if (viewToRemove != nil) { + MBProgressHUD *HUD = (MBProgressHUD *)viewToRemove; + HUD.removeFromSuperViewOnHide = YES; + [HUD hide:animated]; + return YES; + } else { + return NO; + } +} + + #pragma mark - #pragma mark Lifecycle methods @@ -165,44 +228,57 @@ - (id)initWithView:(UIView *)view { [NSException raise:@"MBProgressHUDViewIsNillException" format:@"The view used in the MBProgressHUD initializer is nil."]; } - return [self initWithFrame:view.bounds]; + id me = [self initWithFrame:view.bounds]; + // We need to take care of rotation ourselfs if we're adding the HUD to a window + if ([view isKindOfClass:[UIWindow class]]) { + [self setTransformForCurrentOrientation:NO]; + } + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange:) + name:UIDeviceOrientationDidChangeNotification object:nil]; + + return me; } - (id)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { // Set default values for properties + self.animationType = MBProgressHUDAnimationFade; self.mode = MBProgressHUDModeIndeterminate; self.labelText = nil; self.detailsLabelText = nil; - self.opacity = 0.9; + self.opacity = 0.8; self.labelFont = [UIFont boldSystemFontOfSize:LABELFONTSIZE]; self.detailsLabelFont = [UIFont boldSystemFontOfSize:LABELDETAILSFONTSIZE]; self.xOffset = 0.0; self.yOffset = 0.0; self.graceTime = 0.0; self.minShowTime = 0.0; - + self.removeFromSuperViewOnHide = NO; + self.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; // Transparent background self.opaque = NO; self.backgroundColor = [UIColor clearColor]; - + // Make invisible for now self.alpha = 0.0; - + // Add label label = [[UILabel alloc] initWithFrame:self.bounds]; - + // Add details label detailsLabel = [[UILabel alloc] initWithFrame:self.bounds]; taskInProgress = NO; + rotationTransform = CGAffineTransformIdentity; } return self; } - (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [indicator release]; [label release]; [detailsLabel release]; @@ -211,6 +287,7 @@ - (void)dealloc { [graceTimer release]; [minShowTimer release]; [showStarted release]; + [customView release]; [super dealloc]; } @@ -219,22 +296,22 @@ - (void)dealloc { - (void)layoutSubviews { CGRect frame = self.bounds; - + // Compute HUD dimensions based on indicator size (add margin to HUD border) CGRect indFrame = indicator.bounds; self.width = indFrame.size.width + 2 * MARGIN; self.height = indFrame.size.height + 2 * MARGIN; - + // Position the indicator indFrame.origin.x = floor((frame.size.width - indFrame.size.width) / 2) + self.xOffset; indFrame.origin.y = floor((frame.size.height - indFrame.size.height) / 2) + self.yOffset; indicator.frame = indFrame; - + // Add label if label text was set if (nil != self.labelText) { // Get size of label text CGSize dims = [self.labelText sizeWithFont:self.labelFont]; - + // Compute label dimensions based on font metrics if size is larger than max then clip the label width float lHeight = dims.height; float lWidth; @@ -244,7 +321,7 @@ - (void)layoutSubviews { else { lWidth = frame.size.width - 4 * MARGIN; } - + // Set label properties label.font = self.labelFont; label.adjustsFontSizeToFitWidth = NO; @@ -253,30 +330,30 @@ - (void)layoutSubviews { label.backgroundColor = [UIColor clearColor]; label.textColor = [UIColor whiteColor]; label.text = self.labelText; - + // Update HUD size if (self.width < (lWidth + 2 * MARGIN)) { self.width = lWidth + 2 * MARGIN; } self.height = self.height + lHeight + PADDING; - + // Move indicator to make room for the label indFrame.origin.y -= (floor(lHeight / 2 + PADDING / 2)); indicator.frame = indFrame; - + // Set the label position and dimensions CGRect lFrame = CGRectMake(floor((frame.size.width - lWidth) / 2) + xOffset, floor(indFrame.origin.y + indFrame.size.height + PADDING), lWidth, lHeight); label.frame = lFrame; - + [self addSubview:label]; - + // Add details label delatils text was set if (nil != self.detailsLabelText) { // Get size of label text dims = [self.detailsLabelText sizeWithFont:self.detailsLabelFont]; - + // Compute label dimensions based on font metrics if size is larger than max then clip the label width lHeight = dims.height; if (dims.width <= (frame.size.width - 2 * MARGIN)) { @@ -285,7 +362,7 @@ - (void)layoutSubviews { else { lWidth = frame.size.width - 4 * MARGIN; } - + // Set label properties detailsLabel.font = self.detailsLabelFont; detailsLabel.adjustsFontSizeToFitWidth = NO; @@ -294,26 +371,26 @@ - (void)layoutSubviews { detailsLabel.backgroundColor = [UIColor clearColor]; detailsLabel.textColor = [UIColor whiteColor]; detailsLabel.text = self.detailsLabelText; - + // Update HUD size if (self.width < lWidth) { self.width = lWidth + 2 * MARGIN; } self.height = self.height + lHeight + PADDING; - + // Move indicator to make room for the new label indFrame.origin.y -= (floor(lHeight / 2 + PADDING / 2)); indicator.frame = indFrame; - + // Move first label to make room for the new label lFrame.origin.y -= (floor(lHeight / 2 + PADDING / 2)); label.frame = lFrame; - + // Set label position and dimensions CGRect lFrameD = CGRectMake(floor((frame.size.width - lWidth) / 2) + xOffset, lFrame.origin.y + lFrame.size.height + PADDING, lWidth, lHeight); detailsLabel.frame = lFrameD; - + [self addSubview:detailsLabel]; } } @@ -374,11 +451,11 @@ - (void)handleMinShowTimer:(NSTimer *)theTimer { } - (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(BOOL)animated { - + methodForExecution = method; targetForExecution = [target retain]; objectForExecution = [object retain]; - + // Launch execution in new thread taskInProgress = YES; [NSThread detachNewThreadSelector:@selector(launchExecution) toTarget:self withObject:nil]; @@ -389,14 +466,14 @@ - (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object - (void)launchExecution { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - + // Start executing the requested task [targetForExecution performSelector:methodForExecution withObject:objectForExecution]; - + // Task completed, update view in main thread (note: view operations should // be done only in the main thread) [self performSelectorOnMainThread:@selector(cleanUp) withObject:nil waitUntilDone:NO]; - + [pool release]; } @@ -406,25 +483,29 @@ - (void)animationFinished:(NSString *)animationID finished:(BOOL)finished contex - (void)done { isFinished = YES; - + // If delegate was set make the callback self.alpha = 0.0; if(delegate != nil && [delegate conformsToProtocol:@protocol(MBProgressHUDDelegate)]) { - if([delegate respondsToSelector:@selector(hudWasHidden)]) { - [delegate performSelector:@selector(hudWasHidden)]; - } + if([delegate respondsToSelector:@selector(hudWasHidden)]) { + [delegate performSelector:@selector(hudWasHidden)]; + } } + + if (removeFromSuperViewOnHide) { + [self removeFromSuperview]; + } } - (void)cleanUp { taskInProgress = NO; self.indicator = nil; - + [targetForExecution release]; [objectForExecution release]; - + [self hide:useAnimation]; } @@ -432,12 +513,20 @@ - (void)cleanUp { #pragma mark Fade in and Fade out - (void)showUsingAnimation:(BOOL)animated { + self.alpha = 0.0; + if (animated && animationType == MBProgressHUDAnimationZoom) { + self.transform = CGAffineTransformConcat(rotationTransform, CGAffineTransformMakeScale(1.5, 1.5)); + } + self.showStarted = [NSDate date]; // Fade in if (animated) { [UIView beginAnimations:nil context:NULL]; - [UIView setAnimationDuration:0.40]; + [UIView setAnimationDuration:0.30]; self.alpha = 1.0; + if (animationType == MBProgressHUDAnimationZoom) { + self.transform = rotationTransform; + } [UIView commitAnimations]; } else { @@ -449,11 +538,14 @@ - (void)hideUsingAnimation:(BOOL)animated { // Fade out if (animated) { [UIView beginAnimations:nil context:NULL]; - [UIView setAnimationDuration:0.40]; + [UIView setAnimationDuration:0.30]; [UIView setAnimationDelegate:self]; [UIView setAnimationDidStopSelector:@selector(animationFinished: finished: context:)]; // 0.02 prevents the hud from passing through touches during the animation the hud will get completely hidden // in the done method + if (animationType == MBProgressHUDAnimationZoom) { + self.transform = CGAffineTransformConcat(rotationTransform, CGAffineTransformMakeScale(0.5, 0.5)); + } self.alpha = 0.02; [UIView commitAnimations]; } @@ -477,7 +569,7 @@ - (void)drawRect:(CGRect)rect { - (void)fillRoundedRect:(CGRect)rect inContext:(CGContextRef)context { float radius = 10.0f; - + CGContextBeginPath(context); CGContextSetGrayFillColor(context, 0.0, self.opacity); CGContextMoveToPoint(context, CGRectGetMinX(rect) + radius, CGRectGetMinY(rect)); @@ -489,6 +581,43 @@ - (void)fillRoundedRect:(CGRect)rect inContext:(CGContextRef)context { CGContextFillPath(context); } +#pragma mark - +#pragma mark Manual oritentation change + +#define RADIANS(degrees) ((degrees * M_PI) / 180.0) + +- (void)deviceOrientationDidChange:(NSNotification *)notification { + if ([self.superview isKindOfClass:[UIWindow class]]) { + [self setTransformForCurrentOrientation:YES]; + } + // Stay in sync with the parent view (make sure we cover it fully) + self.frame = self.superview.bounds; + [self setNeedsDisplay]; +} + +- (void)setTransformForCurrentOrientation:(BOOL)animated { + UIDeviceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; + NSInteger degrees = 0; + + if (UIInterfaceOrientationIsLandscape(orientation)) { + if (orientation == UIInterfaceOrientationLandscapeLeft) { degrees = -90; } + else { degrees = 90; } + } else { + if (orientation == UIInterfaceOrientationPortraitUpsideDown) { degrees = 180; } + else { degrees = 0; } + } + + rotationTransform = CGAffineTransformMakeRotation(RADIANS(degrees)); + + if (animated) { + [UIView beginAnimations:nil context:nil]; + } + [self setTransform:rotationTransform]; + if (animated) { + [UIView commitAnimations]; + } +} + @end @@ -502,16 +631,16 @@ - (void)drawRect:(CGRect)rect { CGRect allRect = self.bounds; CGRect circleRect = CGRectMake(allRect.origin.x + 2, allRect.origin.y + 2, allRect.size.width - 4, allRect.size.height - 4); - + CGContextRef context = UIGraphicsGetCurrentContext(); - + // Draw background CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0); // white CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 0.1); // translucent white CGContextSetLineWidth(context, 2.0); CGContextFillEllipseInRect(context, circleRect); CGContextStrokeEllipseInRect(context, circleRect); - + // Draw progress float x = (allRect.size.width / 2); float y = (allRect.size.height / 2); diff --git a/README.mdown b/README.mdown index 510c38d86..ccb08204a 100644 --- a/README.mdown +++ b/README.mdown @@ -3,10 +3,13 @@ MBProgressHUD MBProgressHUD is an iPhone drop-in class that displays a translucent HUD with a progress indicator and some optional labels while work is being done in a background thread. The HUD is meant as a replacement for the undocumented, private UIKit UIProgressHUD with some additional features. -[![](http://grab.by/grabs/cfab318151331b5f0dfce573bf7ba669.png)](http://grab.by/grabs/64efd841e78d3724f4b9e6cdf1a9be58.png) -[![](http://grab.by/grabs/051c768a35a3a8dcce5162f6cde4bb6b.png)](http://grab.by/grabs/37edc22342fcafee5cb6480f1114e882.png) -[![](http://grab.by/grabs/11695987da568e635c4bfb817c247e11.png)](http://grab.by/grabs/11295a7e38b0cfda85b173612f03c2b6.png) -[![](http://grab.by/grabs/e977015442945e6596d695d55c14bc23.png)](http://grab.by/grabs/b72d772d1b578fe78b40ae30cd6ac66e.png) +MBProgressHUD is iOS4 and iPad compatible and released under the MIT license (see MBProgressHUD.h). + +[![](http://dl.dropbox.com/u/378729/MBProgressHUD/1-thumb.png)](http://dl.dropbox.com/u/378729/MBProgressHUD/1.png) +[![](http://dl.dropbox.com/u/378729/MBProgressHUD/2-thumb.png)](http://dl.dropbox.com/u/378729/MBProgressHUD/2.png) +[![](http://dl.dropbox.com/u/378729/MBProgressHUD/3-thumb.png)](http://dl.dropbox.com/u/378729/MBProgressHUD/3.png) +[![](http://dl.dropbox.com/u/378729/MBProgressHUD/4-thumb.png)](http://dl.dropbox.com/u/378729/MBProgressHUD/4.png) +[![](http://dl.dropbox.com/u/378729/MBProgressHUD/5-thumb.png)](http://dl.dropbox.com/u/378729/MBProgressHUD/5.png) Adding MBProgressHUD to your project ==================================== @@ -18,6 +21,13 @@ The simplest way to add the MBProgressHUD to your project is to directly add the 3. Open your project in Xcode, than drag and drop `MBProgressHUD.h` and `MBProgressHUD.m` to your classes group (in the Groups & Files view). 4. Make sure to select Copy items when asked. +If you have a git tracked project, you can add MBProgressHUD as a submodule to your project. + +1. Move inside your git tracked project. +2. Add MBProgressHUD as a submodule using `git submodule add git://github.com/matej/MBProgressHUD.git MBProgressHUD` . +3. Open your project in Xcode, than drag and drop `MBProgressHUD.h` and `MBProgressHUD.m` to your classes group (in the Groups & Files view). +4. Don't select Copy items and select a suitable Reference type (relative to project should work fine most of the time). + Usage ===== @@ -36,29 +46,50 @@ The above copyright notice and this permission notice shall be included in all c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +======= +Extensive documentation is provided in the header file (MBProgressHUD.h). Change-log ========== -Version 0.32 @ 4.01.10 +**Version 0.4** @ 25.07.10 + +- Different animation modes. Default set to zoom. +- Class convenience methods (tadelv - http://github.com/tadelv). +- Autorotation when added to a UIWindow (wuf810 - http://github.com/wuf810). +- Extended demo app. +- Several smaller fixes. + +**Version 0.33** @ 27.03.10 + +- Custom view operation mode added. +- Fixed a memory leak. + +**Version 0.32** @ 4.01.10 + - Added minShowTime, graceTime, xOffset, yOffset. - Various fixes. -Version 0.31 @ 8.10.09 +**Version 0.31** @ 8.10.09 + - Fix for touch through during the fade-out animation. -Version 0.3 @ 30.9.09 +**Version 0.3** @ 30.9.09 + - Added show: and hide: methods. - Now using UIViews layoutSubviews to automate layout calls. - Added some floors to round pixel positions and thereby prevent unsharp views. - Some additional documentation and code cleanup. -Version 0.2 @ 21.7.09 +**Version 0.2** @ 21.7.09 + - Added determinate progress mode and switching capabilities between determinate and indeterminate modes. - Various bugfixes. -Version 0.11 @ 2.6.09. +**Version 0.11** @ 2.6.09. + - Updated labelText and detailsLabelText properties to support text modifications while the HUD is being shown. -Version 0.1 @ 2.4.09 +**Version 0.1** @ 2.4.09 + - Initial release. \ No newline at end of file