diff --git a/Example_App/Example_App.xcodeproj/project.pbxproj b/Example_App/Example_App.xcodeproj/project.pbxproj new file mode 100644 index 0000000..a1d16b2 --- /dev/null +++ b/Example_App/Example_App.xcodeproj/project.pbxproj @@ -0,0 +1,323 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + BF539D5314A52AFC00697F53 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF539D5214A52AFC00697F53 /* UIKit.framework */; }; + BF539D5514A52AFC00697F53 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF539D5414A52AFC00697F53 /* Foundation.framework */; }; + BF539D5714A52AFC00697F53 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF539D5614A52AFC00697F53 /* CoreGraphics.framework */; }; + BF539D5D14A52AFC00697F53 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = BF539D5B14A52AFC00697F53 /* InfoPlist.strings */; }; + BF539D5F14A52AFC00697F53 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = BF539D5E14A52AFC00697F53 /* main.m */; }; + BF539D6314A52AFC00697F53 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = BF539D6214A52AFC00697F53 /* AppDelegate.m */; }; + BF539D6614A52AFC00697F53 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BF539D6514A52AFC00697F53 /* ViewController.m */; }; + BF539D6914A52AFC00697F53 /* ViewController_iPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = BF539D6714A52AFC00697F53 /* ViewController_iPhone.xib */; }; + BF539D6C14A52AFC00697F53 /* ViewController_iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = BF539D6A14A52AFC00697F53 /* ViewController_iPad.xib */; }; + BF539D7C14A53BAB00697F53 /* MTStatusBarOverlay.m in Sources */ = {isa = PBXBuildFile; fileRef = BF539D7914A53BAB00697F53 /* MTStatusBarOverlay.m */; }; + BF539D7D14A53BAB00697F53 /* MTStatusBarTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BF539D7B14A53BAB00697F53 /* MTStatusBarTableViewCell.m */; }; + BF539D8314A53C7700697F53 /* NSString+UUID.m in Sources */ = {isa = PBXBuildFile; fileRef = BF539D8214A53C7600697F53 /* NSString+UUID.m */; }; + BF539D8614A5427D00697F53 /* NSTimer+Blocks.m in Sources */ = {isa = PBXBuildFile; fileRef = BF539D8514A5427D00697F53 /* NSTimer+Blocks.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + BF539D4E14A52AFC00697F53 /* Example_App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example_App.app; sourceTree = BUILT_PRODUCTS_DIR; }; + BF539D5214A52AFC00697F53 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + BF539D5414A52AFC00697F53 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + BF539D5614A52AFC00697F53 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + BF539D5A14A52AFC00697F53 /* Example_App-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Example_App-Info.plist"; sourceTree = ""; }; + BF539D5C14A52AFC00697F53 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + BF539D5E14A52AFC00697F53 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + BF539D6014A52AFC00697F53 /* Example_App-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Example_App-Prefix.pch"; sourceTree = ""; }; + BF539D6114A52AFC00697F53 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + BF539D6214A52AFC00697F53 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + BF539D6414A52AFC00697F53 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; + BF539D6514A52AFC00697F53 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; + BF539D6814A52AFC00697F53 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController_iPhone.xib; sourceTree = ""; }; + BF539D6B14A52AFC00697F53 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController_iPad.xib; sourceTree = ""; }; + BF539D7814A53BAB00697F53 /* MTStatusBarOverlay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MTStatusBarOverlay.h; path = ../../MTStatusBarOverlay.h; sourceTree = ""; }; + BF539D7914A53BAB00697F53 /* MTStatusBarOverlay.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MTStatusBarOverlay.m; path = ../../MTStatusBarOverlay.m; sourceTree = ""; }; + BF539D7A14A53BAB00697F53 /* MTStatusBarTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MTStatusBarTableViewCell.h; path = ../../MTStatusBarTableViewCell.h; sourceTree = ""; }; + BF539D7B14A53BAB00697F53 /* MTStatusBarTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MTStatusBarTableViewCell.m; path = ../../MTStatusBarTableViewCell.m; sourceTree = ""; }; + BF539D8114A53C7600697F53 /* NSString+UUID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+UUID.h"; sourceTree = ""; }; + BF539D8214A53C7600697F53 /* NSString+UUID.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+UUID.m"; sourceTree = ""; }; + BF539D8414A5427700697F53 /* NSTimer+Blocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSTimer+Blocks.h"; sourceTree = ""; }; + BF539D8514A5427D00697F53 /* NSTimer+Blocks.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSTimer+Blocks.m"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + BF539D4B14A52AFC00697F53 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + BF539D5314A52AFC00697F53 /* UIKit.framework in Frameworks */, + BF539D5514A52AFC00697F53 /* Foundation.framework in Frameworks */, + BF539D5714A52AFC00697F53 /* CoreGraphics.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + BF539D4314A52AFA00697F53 = { + isa = PBXGroup; + children = ( + BF539D5814A52AFC00697F53 /* Example_App */, + BF539D5114A52AFC00697F53 /* Frameworks */, + BF539D4F14A52AFC00697F53 /* Products */, + ); + sourceTree = ""; + }; + BF539D4F14A52AFC00697F53 /* Products */ = { + isa = PBXGroup; + children = ( + BF539D4E14A52AFC00697F53 /* Example_App.app */, + ); + name = Products; + sourceTree = ""; + }; + BF539D5114A52AFC00697F53 /* Frameworks */ = { + isa = PBXGroup; + children = ( + BF539D5214A52AFC00697F53 /* UIKit.framework */, + BF539D5414A52AFC00697F53 /* Foundation.framework */, + BF539D5614A52AFC00697F53 /* CoreGraphics.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + BF539D5814A52AFC00697F53 /* Example_App */ = { + isa = PBXGroup; + children = ( + BF539D6114A52AFC00697F53 /* AppDelegate.h */, + BF539D6214A52AFC00697F53 /* AppDelegate.m */, + BF539D6414A52AFC00697F53 /* ViewController.h */, + BF539D6514A52AFC00697F53 /* ViewController.m */, + BF539D6714A52AFC00697F53 /* ViewController_iPhone.xib */, + BF539D6A14A52AFC00697F53 /* ViewController_iPad.xib */, + BF539D7814A53BAB00697F53 /* MTStatusBarOverlay.h */, + BF539D7914A53BAB00697F53 /* MTStatusBarOverlay.m */, + BF539D7A14A53BAB00697F53 /* MTStatusBarTableViewCell.h */, + BF539D7B14A53BAB00697F53 /* MTStatusBarTableViewCell.m */, + BF539D8114A53C7600697F53 /* NSString+UUID.h */, + BF539D8214A53C7600697F53 /* NSString+UUID.m */, + BF539D8414A5427700697F53 /* NSTimer+Blocks.h */, + BF539D8514A5427D00697F53 /* NSTimer+Blocks.m */, + BF539D5914A52AFC00697F53 /* Supporting Files */, + ); + path = Example_App; + sourceTree = ""; + }; + BF539D5914A52AFC00697F53 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + BF539D5A14A52AFC00697F53 /* Example_App-Info.plist */, + BF539D5B14A52AFC00697F53 /* InfoPlist.strings */, + BF539D5E14A52AFC00697F53 /* main.m */, + BF539D6014A52AFC00697F53 /* Example_App-Prefix.pch */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + BF539D4D14A52AFC00697F53 /* Example_App */ = { + isa = PBXNativeTarget; + buildConfigurationList = BF539D6F14A52AFC00697F53 /* Build configuration list for PBXNativeTarget "Example_App" */; + buildPhases = ( + BF539D4A14A52AFC00697F53 /* Sources */, + BF539D4B14A52AFC00697F53 /* Frameworks */, + BF539D4C14A52AFC00697F53 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Example_App; + productName = Example_App; + productReference = BF539D4E14A52AFC00697F53 /* Example_App.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + BF539D4514A52AFA00697F53 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0430; + ORGANIZATIONNAME = "Richardson High School"; + }; + buildConfigurationList = BF539D4814A52AFA00697F53 /* Build configuration list for PBXProject "Example_App" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = BF539D4314A52AFA00697F53; + productRefGroup = BF539D4F14A52AFC00697F53 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + BF539D4D14A52AFC00697F53 /* Example_App */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + BF539D4C14A52AFC00697F53 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + BF539D5D14A52AFC00697F53 /* InfoPlist.strings in Resources */, + BF539D6914A52AFC00697F53 /* ViewController_iPhone.xib in Resources */, + BF539D6C14A52AFC00697F53 /* ViewController_iPad.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + BF539D4A14A52AFC00697F53 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + BF539D5F14A52AFC00697F53 /* main.m in Sources */, + BF539D6314A52AFC00697F53 /* AppDelegate.m in Sources */, + BF539D6614A52AFC00697F53 /* ViewController.m in Sources */, + BF539D7C14A53BAB00697F53 /* MTStatusBarOverlay.m in Sources */, + BF539D7D14A53BAB00697F53 /* MTStatusBarTableViewCell.m in Sources */, + BF539D8314A53C7700697F53 /* NSString+UUID.m in Sources */, + BF539D8614A5427D00697F53 /* NSTimer+Blocks.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + BF539D5B14A52AFC00697F53 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + BF539D5C14A52AFC00697F53 /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + BF539D6714A52AFC00697F53 /* ViewController_iPhone.xib */ = { + isa = PBXVariantGroup; + children = ( + BF539D6814A52AFC00697F53 /* en */, + ); + name = ViewController_iPhone.xib; + sourceTree = ""; + }; + BF539D6A14A52AFC00697F53 /* ViewController_iPad.xib */ = { + isa = PBXVariantGroup; + children = ( + BF539D6B14A52AFC00697F53 /* en */, + ); + name = ViewController_iPad.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + BF539D6D14A52AFC00697F53 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CLANG_ENABLE_OBJC_ARC = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 5.0; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + BF539D6E14A52AFC00697F53 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CLANG_ENABLE_OBJC_ARC = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 5.0; + OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + BF539D7014A52AFC00697F53 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "Example_App/Example_App-Prefix.pch"; + INFOPLIST_FILE = "Example_App/Example_App-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 4.0; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Debug; + }; + BF539D7114A52AFC00697F53 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "Example_App/Example_App-Prefix.pch"; + INFOPLIST_FILE = "Example_App/Example_App-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 4.0; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + BF539D4814A52AFA00697F53 /* Build configuration list for PBXProject "Example_App" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + BF539D6D14A52AFC00697F53 /* Debug */, + BF539D6E14A52AFC00697F53 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + BF539D6F14A52AFC00697F53 /* Build configuration list for PBXNativeTarget "Example_App" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + BF539D7014A52AFC00697F53 /* Debug */, + BF539D7114A52AFC00697F53 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = BF539D4514A52AFA00697F53 /* Project object */; +} diff --git a/Example_App/Example_App/AppDelegate.h b/Example_App/Example_App/AppDelegate.h new file mode 100644 index 0000000..f96874a --- /dev/null +++ b/Example_App/Example_App/AppDelegate.h @@ -0,0 +1,19 @@ +// +// AppDelegate.h +// Example_App +// +// Created by Riley Testut on 12/23/11. +// Copyright (c) 2011 Richardson High School. All rights reserved. +// + +#import + +@class ViewController; + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + +@property (strong, nonatomic) ViewController *viewController; + +@end diff --git a/Example_App/Example_App/AppDelegate.m b/Example_App/Example_App/AppDelegate.m new file mode 100644 index 0000000..4abb9c4 --- /dev/null +++ b/Example_App/Example_App/AppDelegate.m @@ -0,0 +1,71 @@ +// +// AppDelegate.m +// Example_App +// +// Created by Riley Testut on 12/23/11. +// Copyright (c) 2011 Richardson High School. All rights reserved. +// + +#import "AppDelegate.h" + +#import "ViewController.h" + +@implementation AppDelegate + +@synthesize window = _window; +@synthesize viewController = _viewController; + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + // Override point for customization after application launch. + if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { + self.viewController = [[ViewController alloc] initWithNibName:@"ViewController_iPhone" bundle:nil]; + } else { + self.viewController = [[ViewController alloc] initWithNibName:@"ViewController_iPad" bundle:nil]; + } + self.window.rootViewController = self.viewController; + [self.window makeKeyAndVisible]; + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application +{ + /* + Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. + */ +} + +- (void)applicationDidEnterBackground:(UIApplication *)application +{ + /* + Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + */ +} + +- (void)applicationWillEnterForeground:(UIApplication *)application +{ + /* + Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. + */ +} + +- (void)applicationDidBecomeActive:(UIApplication *)application +{ + /* + Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + */ +} + +- (void)applicationWillTerminate:(UIApplication *)application +{ + /* + Called when the application is about to terminate. + Save data if appropriate. + See also applicationDidEnterBackground:. + */ +} + +@end diff --git a/Example_App/Example_App/Example_App-Info.plist b/Example_App/Example_App/Example_App-Info.plist new file mode 100644 index 0000000..041ae2a --- /dev/null +++ b/Example_App/Example_App/Example_App-Info.plist @@ -0,0 +1,47 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFiles + + CFBundleIdentifier + com.testuttech.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Example_App/Example_App/Example_App-Prefix.pch b/Example_App/Example_App/Example_App-Prefix.pch new file mode 100644 index 0000000..e54b86d --- /dev/null +++ b/Example_App/Example_App/Example_App-Prefix.pch @@ -0,0 +1,14 @@ +// +// Prefix header for all source files of the 'Example_App' target in the 'Example_App' project +// + +#import + +#ifndef __IPHONE_4_0 +#warning "This project uses features only available in iOS SDK 4.0 and later." +#endif + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/Example_App/Example_App/NSString+UUID.h b/Example_App/Example_App/NSString+UUID.h new file mode 100644 index 0000000..4d44601 --- /dev/null +++ b/Example_App/Example_App/NSString+UUID.h @@ -0,0 +1,15 @@ +// +// NSString+UUID.h +// Camera Prime +// +// Created by Riley on 3/19/11. +// Copyright 2011 Testut Tech. All rights reserved. +// + +#import + +@interface NSString (NSString_UUID) + ++(NSString *)randomUUID; + +@end diff --git a/Example_App/Example_App/NSString+UUID.m b/Example_App/Example_App/NSString+UUID.m new file mode 100644 index 0000000..5f5a819 --- /dev/null +++ b/Example_App/Example_App/NSString+UUID.m @@ -0,0 +1,36 @@ +// +// NSString+UUID.m +// Camera Prime +// +// Created by Riley on 3/19/11. +// Copyright 2011 Testut Tech. All rights reserved. +// + +#import "NSString+UUID.h" + + +@implementation NSString (NSString_UUID) + ++(NSString *)randomUUID { + NSMutableString *uuid = nil; + CFUUIDRef theUUID = CFUUIDCreate(kCFAllocatorDefault); + if (theUUID) { + uuid = (__bridge_transfer NSMutableString *)CFUUIDCreateString(kCFAllocatorDefault, theUUID); + } + else { + CFUUIDRef theSecondUUID = CFUUIDCreate(kCFAllocatorDefault); + if (theSecondUUID) { + uuid = (__bridge_transfer NSMutableString *)CFUUIDCreateString(kCFAllocatorDefault, theSecondUUID); + } + else { + NSLog(@"Ok, we have a problem here. Reverting to dates"); + NSString *string = [[NSString alloc] initWithFormat:@"%@", [NSDate date]]; + uuid = (NSMutableString *)string; + } + CFRelease(theSecondUUID); + } + CFRelease(theUUID); + return uuid; +} + +@end diff --git a/Example_App/Example_App/NSTimer+Blocks.h b/Example_App/Example_App/NSTimer+Blocks.h new file mode 100755 index 0000000..ed76885 --- /dev/null +++ b/Example_App/Example_App/NSTimer+Blocks.h @@ -0,0 +1,21 @@ +// +// NSTimer+Blocks.h +// +// Created by Jiva DeVoe on 1/14/11. +// Copyright 2011 Random Ideas, LLC. All rights reserved. +// +// +/*Copyright (C) 2011 by Random Ideas, LLC + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +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.*/ + +#import + +@interface NSTimer (Blocks) ++(id)scheduledTimerWithTimeInterval:(NSTimeInterval)inTimeInterval block:(void (^)())inBlock repeats:(BOOL)inRepeats; ++(id)timerWithTimeInterval:(NSTimeInterval)inTimeInterval block:(void (^)())inBlock repeats:(BOOL)inRepeats; +@end diff --git a/Example_App/Example_App/NSTimer+Blocks.m b/Example_App/Example_App/NSTimer+Blocks.m new file mode 100755 index 0000000..7c32b10 --- /dev/null +++ b/Example_App/Example_App/NSTimer+Blocks.m @@ -0,0 +1,43 @@ +// +// NSTimer+Blocks.m +// +// Created by Jiva DeVoe on 1/14/11. +// Copyright 2011 Random Ideas, LLC. All rights reserved. +// + +/*Copyright (C) 2011 by Random Ideas, LLC + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + 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.*/ + +#import "NSTimer+Blocks.h" + +@implementation NSTimer (Blocks) + ++(id)scheduledTimerWithTimeInterval:(NSTimeInterval)inTimeInterval block:(void (^)())inBlock repeats:(BOOL)inRepeats +{ + void (^block)() = [inBlock copy]; + id ret = [self scheduledTimerWithTimeInterval:inTimeInterval target:self selector:@selector(jdExecuteSimpleBlock:) userInfo:block repeats:inRepeats]; + return ret; +} + ++(id)timerWithTimeInterval:(NSTimeInterval)inTimeInterval block:(void (^)())inBlock repeats:(BOOL)inRepeats +{ + void (^block)() = [inBlock copy]; + id ret = [self timerWithTimeInterval:inTimeInterval target:self selector:@selector(jdExecuteSimpleBlock:) userInfo:block repeats:inRepeats]; + return ret; +} + ++(void)jdExecuteSimpleBlock:(NSTimer *)inTimer; +{ + if([inTimer userInfo]) + { + void (^block)() = (void (^)())[inTimer userInfo]; + block(); + } +} + +@end diff --git a/Example_App/Example_App/ViewController.h b/Example_App/Example_App/ViewController.h new file mode 100644 index 0000000..608ae8f --- /dev/null +++ b/Example_App/Example_App/ViewController.h @@ -0,0 +1,20 @@ +// +// ViewController.h +// Example_App +// +// Created by Riley Testut on 12/23/11. +// Copyright (c) 2011 Richardson High School. All rights reserved. +// + +#import +#import "MTStatusBarOverlay.h" + +@interface ViewController : UIViewController +@property (strong, nonatomic) IBOutlet UIView *portrait; +@property (strong, nonatomic) IBOutlet UIView *landscape; +- (IBAction)changeStatusBarStyle:(id)sender; +- (IBAction)postMessage:(id)sender; +- (IBAction)postProgressMessage:(id)sender; +- (IBAction)postErrorMessage:(id)sender; +- (IBAction)postFinishedMessage:(id)sender; +@end diff --git a/Example_App/Example_App/ViewController.m b/Example_App/Example_App/ViewController.m new file mode 100644 index 0000000..b5da900 --- /dev/null +++ b/Example_App/Example_App/ViewController.m @@ -0,0 +1,168 @@ +// +// ViewController.m +// Example_App +// +// Created by Riley Testut on 12/23/11. +// Copyright (c) 2011 Richardson High School. All rights reserved. +// + +#import "ViewController.h" +#import "MTStatusBarOverlay.h" +#import "NSString+UUID.h" +#import "NSTimer+Blocks.h" + +#define degreesToRadians(x) (M_PI * (x) / 180.0) + +@implementation ViewController +@synthesize portrait; +@synthesize landscape; + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + // Release any cached data, images, etc that aren't in use. +} + +#pragma mark - View lifecycle + +- (void)viewDidLoad +{ + [super viewDidLoad]; + MTStatusBarOverlay *overlay = [MTStatusBarOverlay sharedOverlay]; + overlay.animation = MTStatusBarOverlayAnimationFallDown; + overlay.detailViewMode = MTDetailViewModeHistory; + overlay.delegate = self; + overlay.mainProgress = 0.0; + overlay.historyEnabled = YES; + self.wantsFullScreenLayout = YES; + // Do any additional setup after loading the view, typically from a nib. +} + +- (void)viewDidUnload +{ + [self setLandscape:nil]; + [self setPortrait:nil]; + [super viewDidUnload]; + // Release any retained subviews of the main view. + // e.g. self.myOutlet = nil; +} + +- (void)viewWillAppear:(BOOL)animated +{ + [super viewWillAppear:animated]; +} + +- (void)viewDidAppear:(BOOL)animated +{ + [super viewDidAppear:animated]; +} + +- (void)viewWillDisappear:(BOOL)animated +{ + [super viewWillDisappear:animated]; +} + +- (void)viewDidDisappear:(BOOL)animated +{ + [super viewDidDisappear:animated]; +} + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +{ + return YES; +} + +- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { + if (toInterfaceOrientation == UIInterfaceOrientationPortrait) { + self.view = self.portrait; + self.view.transform = CGAffineTransformIdentity; + self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(0)); + self.view.bounds = CGRectMake(0, 0, 300.0, 480.0); + } + else if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) { + self.view = self.landscape; + self.view.transform = CGAffineTransformIdentity; + self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(-90)); + self.view.bounds = CGRectMake(0, 0, 460.0, 320.0); + } + else if (toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) { + self.view = self.portrait; + self.view.transform = CGAffineTransformIdentity; + self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(180)); + self.view.bounds = CGRectMake(0, 0, 300.0, 480.0); + } + else if (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) { + self.view = self.landscape; + self.view.transform = CGAffineTransformIdentity; + self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(90)); + self.view.bounds = CGRectMake(0, 0, 460.0, 320.0); + } +} + +- (IBAction)changeStatusBarStyle:(id)sender { + NSInteger selectionIndex = [(UISegmentedControl *)sender selectedSegmentIndex]; + UIStatusBarStyle style = UIStatusBarStyleDefault; + switch (selectionIndex) { + case 0: + style = UIStatusBarStyleDefault; + break; + case 1: + style = UIStatusBarStyleBlackOpaque; + break; + case 2: + style = UIStatusBarStyleBlackTranslucent; + break; + + default: + break; + } + + [UIApplication sharedApplication].statusBarStyle = style; +} + +- (IBAction)postMessage:(id)sender { + UIButton *button = (UIButton *)sender; + NSString *message = @"Posted a normal message!"; + NSString *key = [NSString randomUUID];//This generates new random key for each message. Depending on how you use MTStatusBarOverlay, you may want to have a constant string for each message. + + if ([[button titleForState:UIControlStateNormal] isEqualToString:@"Disappear"]) { + [[MTStatusBarOverlay sharedOverlay] postMessage:message key:key duration:2.0]; + } + else [[MTStatusBarOverlay sharedOverlay] postMessage:message key:key]; + +} + +- (IBAction)postProgressMessage:(id)sender { + UIButton *button = (UIButton *)sender; + NSString *message = @"Posted a progress message!"; + NSString *key = [NSString randomUUID];//This generates new random key for each message. Depending on how you use MTStatusBarOverlay, you may want to have a constant string for each message. + + [[MTStatusBarOverlay sharedOverlay] postMessage:message key:key]; + + __block double progress = 0.00; + __block NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:.1 block:^{ + [[MTStatusBarOverlay sharedOverlay] setProgress:progress key:key]; + progress = progress + .01; + if (progress > 1.05) {//To show that even though you may put in a value higher than 1, it will never show more than 100% + [timer invalidate]; + if ([[button titleForState:UIControlStateNormal] isEqualToString:@"Disappear"]) { + [[MTStatusBarOverlay sharedOverlay] removeMessageFromHistoryForKey:key]; + } + } + } repeats:YES]; +} + +- (IBAction)postErrorMessage:(id)sender { + NSString *message = @"Posted an error message!"; + NSString *key = [NSString randomUUID];//This generates new random key for each message. Depending on how you use MTStatusBarOverlay, you may want to have a constant string for each message. + + [[MTStatusBarOverlay sharedOverlay] postErrorMessage:message key:key duration:5.0]; +} + +- (IBAction)postFinishedMessage:(id)sender { + NSString *message = @"Posted a finish message!"; + NSString *key = [NSString randomUUID];//This generates new random key for each message. Depending on how you use MTStatusBarOverlay, you may want to have a constant string for each message. + + [[MTStatusBarOverlay sharedOverlay] postFinishMessage:message key:key duration:5.0]; +} +@end diff --git a/Example_App/Example_App/en.lproj/InfoPlist.strings b/Example_App/Example_App/en.lproj/InfoPlist.strings new file mode 100644 index 0000000..477b28f --- /dev/null +++ b/Example_App/Example_App/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/Example_App/Example_App/en.lproj/ViewController_iPad.xib b/Example_App/Example_App/en.lproj/ViewController_iPad.xib new file mode 100644 index 0000000..cd02abe --- /dev/null +++ b/Example_App/Example_App/en.lproj/ViewController_iPad.xib @@ -0,0 +1,120 @@ + + + + 1280 + 11C25 + 1919 + 1138.11 + 566.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 916 + + + IBProxyObject + IBUIView + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + PluginDependencyRecalculationVersion + + + + + IBFilesOwner + IBIPadFramework + + + IBFirstResponder + IBIPadFramework + + + + 274 + {{0, 20}, {768, 1004}} + + + + 3 + MQA + + 2 + + + + 2 + + IBIPadFramework + + + + + + + view + + + + 3 + + + + + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 2 + + + + + + + ViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + + 3 + + + + + ViewController + UIViewController + + IBProjectSource + ./Classes/ViewController.h + + + + + 0 + IBIPadFramework + YES + 3 + 916 + + diff --git a/Example_App/Example_App/en.lproj/ViewController_iPhone.xib b/Example_App/Example_App/en.lproj/ViewController_iPhone.xib new file mode 100644 index 0000000..7c3438e --- /dev/null +++ b/Example_App/Example_App/en.lproj/ViewController_iPhone.xib @@ -0,0 +1,1146 @@ + + + + 1296 + 11D50b + 2182 + 1138.32 + 568.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 1181 + + + IBUIButton + IBUISegmentedControl + IBUIView + IBUILabel + IBProxyObject + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + PluginDependencyRecalculationVersion + + + + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 292 + + + + 297 + {{160, 115}, {140, 37}} + + + + _NS:225 + NO + IBCocoaTouchFramework + 0 + 0 + 1 + Don't Disappear + + 3 + MQA + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + 3 + MC41AA + + + 2 + 15 + + + Helvetica-Bold + 15 + 16 + + + + + 300 + {{34, 200}, {98, 37}} + + + + _NS:225 + NO + IBCocoaTouchFramework + 0 + 0 + 1 + Disappear + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + + + + + 300 + {{34, 115}, {98, 37}} + + + + _NS:225 + NO + IBCocoaTouchFramework + 0 + 0 + 1 + Disappear + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + + + + + 266 + {{5, 266}, {311, 21}} + + + + _NS:328 + NO + YES + 7 + NO + IBCocoaTouchFramework + Post Error Message + + 1 + MCAwIDAAA + + + 1 + 10 + 1 + + 1 + 17 + + + Helvetica + 17 + 16 + + + + + 266 + {{-8, 366}, {337, 21}} + + + + _NS:328 + NO + YES + 7 + NO + IBCocoaTouchFramework + Post Finished Message + + + 1 + 10 + 1 + + + + + + 290 + {{25, 86}, {269, 21}} + + + + _NS:328 + NO + YES + 7 + NO + IBCocoaTouchFramework + Post Message + + + 1 + 10 + 1 + + + + + + 290 + {{10, 25}, {300, 44}} + + + + _NS:273 + NO + IBCocoaTouchFramework + 3 + 0 + + White + Black + Translucent + + + + + + + + + + + + + {0, 0} + {0, 0} + {0, 0} + + + + + + + + + + 298 + {{-12, 171}, {342, 21}} + + + + _NS:328 + NO + YES + 7 + NO + IBCocoaTouchFramework + Post Progress Message + + + 1 + 10 + 1 + + + + + + 297 + {{160, 200}, {140, 37}} + + + + _NS:225 + NO + IBCocoaTouchFramework + 0 + 0 + 1 + Don't Disappear + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + + + + + 300 + {{110, 295}, {98, 37}} + + + + _NS:225 + NO + IBCocoaTouchFramework + 0 + 0 + 1 + Disappear + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + + + + + 268 + {{110, 395}, {98, 37}} + + + + _NS:225 + NO + IBCocoaTouchFramework + 0 + 0 + 1 + Disappear + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + + + + {320, 460} + + + + _NS:196 + + 10 + + 549453824 + {512, 1} + + + + + + TU0AKgAACAjFzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ +y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ +xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ +xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ +xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ +xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/ +xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/ +y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ +y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ +xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ +xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ +xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ +xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/ +xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/ +y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ +y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ +xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ +xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ +xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ +xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/ +xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/ +y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ +y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ +xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ +xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ +xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ +xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/ +xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/ +y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ +y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ +xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ +xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ +xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ +xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/ +xczS/8vS2P/L0tj/xczU/wANAQAAAwAAAAECAAAAAQEAAwAAAAEAAQAAAQIAAwAAAAQAAAiqAQMAAwAA +AAEAAQAAAQYAAwAAAAEAAgAAAREABAAAAAEAAAAIARIAAwAAAAEAAQAAARUAAwAAAAEABAAAARYAAwAA +AAEAAQAAARcABAAAAAEAAAgAARwAAwAAAAEAAQAAAVIAAwAAAAEAAQAAAVMAAwAAAAQAAAiyAAAAAAAI +AAgACAAIAAEAAQABAAE + + + + + + 3 + MCAwAA + + + groupTableViewBackgroundColor + + IBCocoaTouchFramework + + + + 274 + + + + 290 + {{20, 27}, {440, 44}} + + + _NS:273 + NO + IBCocoaTouchFramework + 3 + 0 + + White + Black + Translucent + + + + + + + + + + + + + {0, 0} + {0, 0} + {0, 0} + + + + + + + + + + 297 + {{340, 131}, {140, 37}} + + + _NS:225 + NO + IBCocoaTouchFramework + 0 + 0 + 1 + Don't Disappear + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + + + + + 297 + {{243, 131}, {98, 37}} + + + _NS:225 + NO + IBCocoaTouchFramework + 0 + 0 + 1 + Disappear + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + + + + + 297 + {{277, 102}, {342, 21}} + + + _NS:328 + NO + YES + 7 + NO + IBCocoaTouchFramework + Post Progress Message + + + 1 + 10 + + + + + + 300 + {{97, 131}, {140, 37}} + + + _NS:225 + NO + IBCocoaTouchFramework + 0 + 0 + 1 + Don't Disappear + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + + + + + 300 + {{0, 131}, {98, 37}} + + + _NS:225 + NO + IBCocoaTouchFramework + 0 + 0 + 1 + Disappear + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + + + + + 300 + {{44, 102}, {269, 21}} + + + _NS:328 + NO + YES + 7 + NO + IBCocoaTouchFramework + Post Message + + + 1 + 10 + + + + + + 297 + {{340, 224}, {140, 37}} + + _NS:225 + NO + IBCocoaTouchFramework + 0 + 0 + 1 + Don't Disappear + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + + + + + 297 + {{243, 224}, {98, 37}} + + + _NS:225 + NO + IBCocoaTouchFramework + 0 + 0 + 1 + Disappear + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + + + + + 297 + {{277, 195}, {311, 21}} + + + _NS:328 + NO + YES + 7 + NO + IBCocoaTouchFramework + Post Error Message + + + 1 + 10 + + + + + + 300 + {{97, 224}, {140, 37}} + + + _NS:225 + NO + IBCocoaTouchFramework + 0 + 0 + 1 + Don't Disappear + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + + + + + 300 + {{0, 224}, {98, 37}} + + + _NS:225 + NO + IBCocoaTouchFramework + 0 + 0 + 1 + Disappear + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + + + + + 300 + {{20, 191}, {337, 21}} + + + _NS:328 + NO + YES + 7 + NO + IBCocoaTouchFramework + Post Finished Message + + + 1 + 10 + + + + + {480, 300} + + + NO + + 3 + 3 + + IBCocoaTouchFramework + + + + + + + view + + + + 103 + + + + landscape + + + + 104 + + + + portrait + + + + 105 + + + + postFinishedMessage: + + + 7 + + 91 + + + + postErrorMessage: + + + 7 + + 86 + + + + postProgressMessage: + + + 7 + + 99 + + + + postProgressMessage: + + + 7 + + 101 + + + + postMessage: + + + 7 + + 90 + + + + postMessage: + + + 7 + + 94 + + + + changeStatusBarStyle: + + + 13 + + 95 + + + + postErrorMessage: + + + 7 + + 89 + + + + postErrorMessage: + + + 7 + + 97 + + + + postFinishedMessage: + + + 7 + + 102 + + + + postFinishedMessage: + + + 7 + + 96 + + + + postProgressMessage: + + + 7 + + 87 + + + + postProgressMessage: + + + 7 + + 93 + + + + postMessage: + + + 7 + + 88 + + + + postMessage: + + + 7 + + 100 + + + + + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 59 + + + + + + + + + + + + + + + + + + 72 + + + + + 71 + + + + + 70 + + + + + 69 + + + + + 68 + + + + + 67 + + + + + 66 + + + + + 65 + + + + + 63 + + + + + 62 + + + + + 61 + + + + + 58 + + + + + + + + + + + + + + + + + + + + 73 + + + + + 74 + + + + + 75 + + + + + 76 + + + + + 77 + + + + + 78 + + + + + 79 + + + + + 80 + + + + + 81 + + + + + 82 + + + + + 83 + + + + + 84 + + + + + 85 + + + + + + + ViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + + 105 + + + + + ViewController + UIViewController + + id + id + id + id + id + + + + changeStatusBarStyle: + id + + + postErrorMessage: + id + + + postFinishedMessage: + id + + + postMessage: + id + + + postProgressMessage: + id + + + + UIView + UIView + + + + landscape + UIView + + + portrait + UIView + + + + IBProjectSource + ./Classes/ViewController.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + YES + 3 + 1181 + + diff --git a/Example_App/Example_App/main.m b/Example_App/Example_App/main.m new file mode 100644 index 0000000..56a5088 --- /dev/null +++ b/Example_App/Example_App/main.m @@ -0,0 +1,18 @@ +// +// main.m +// Example_App +// +// Created by Riley Testut on 12/23/11. +// Copyright (c) 2011 Richardson High School. All rights reserved. +// + +#import + +#import "AppDelegate.h" + +int main(int argc, char *argv[]) +{ + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/MTStatusBarOverlay.h b/MTStatusBarOverlay.h index 5a7ca0b..e49c307 100755 --- a/MTStatusBarOverlay.h +++ b/MTStatusBarOverlay.h @@ -46,7 +46,8 @@ typedef enum MTDetailViewMode { typedef enum MTMessageType { MTMessageTypeActivity, // shows actvity indicator MTMessageTypeFinish, // shows checkmark - MTMessageTypeError // shows error-mark + MTMessageTypeError, // shows error-mark + MTMessageTypePlain // doesn't show anything special } MTMessageType; @@ -56,6 +57,8 @@ typedef enum MTMessageType { #define kMTStatusBarOverlayDurationKey @"MessageDuration" #define kMTStatusBarOverlayAnimationKey @"MessageAnimation" #define kMTStatusBarOverlayImmediateKey @"MessageImmediate" +#define kMTStatusBarOverlayKeyKey @"MessageKey" +#define kSetProgressOnStatusBarKey @"UniqueProgressLabelSetProgressKey" // keys used for saving state to NSUserDefaults #define kMTStatusBarOverlayStateShrinked @"kMTStatusBarOverlayStateShrinked" @@ -78,14 +81,16 @@ typedef enum MTMessageType { a detail-view that shows additional information. You can show a history of all the previous messages for free by setting historyEnabled to YES */ -@interface MTStatusBarOverlay : UIWindow +@interface MTStatusBarOverlay : UIWindow // the view that holds all the components of the overlay (except for the detailView) @property (nonatomic, strong) UIView *backgroundView; // the detailView is shown when animation is set to "FallDown" @property (nonatomic, strong) UIView *detailView; -// the current progress -@property (nonatomic, assign) double progress; +// progress displayed on MTStatusBarOverlay +@property (nonatomic, assign) double mainProgress; +// dictionary which holds all progress +@property (nonatomic, strong) NSMutableDictionary *progressDictionary; // the frame of the status bar when animation is set to "Shrink" and it is shrinked @property (nonatomic, assign) CGRect smallFrame; // the current active animation @@ -140,26 +145,34 @@ typedef enum MTMessageType { - (void)postMessageDictionary:(NSDictionary *)messageDictionary; // shows an activity indicator and the given message -- (void)postMessage:(NSString *)message; -- (void)postMessage:(NSString *)message duration:(NSTimeInterval)duration; -- (void)postMessage:(NSString *)message duration:(NSTimeInterval)duration animated:(BOOL)animated; -- (void)postMessage:(NSString *)message animated:(BOOL)animated; +- (void)postMessage:(NSString *)message key:(NSString *)key; +- (void)postMessage:(NSString *)message key:(NSString *)key duration:(NSTimeInterval)duration; +- (void)postMessage:(NSString *)message key:(NSString *)key duration:(NSTimeInterval)duration animated:(BOOL)animated; +- (void)postMessage:(NSString *)message key:(NSString *)key animated:(BOOL)animated; + // clears the message queue and shows this message instantly -- (void)postImmediateMessage:(NSString *)message animated:(BOOL)animated; -- (void)postImmediateMessage:(NSString *)message duration:(NSTimeInterval)duration; -- (void)postImmediateMessage:(NSString *)message duration:(NSTimeInterval)duration animated:(BOOL)animated; +- (void)postImmediateMessage:(NSString *)message key:(NSString *)key animated:(BOOL)animated; +- (void)postImmediateMessage:(NSString *)message key:(NSString *)key duration:(NSTimeInterval)duration; +- (void)postImmediateMessage:(NSString *)message key:(NSString *)key duration:(NSTimeInterval)duration animated:(BOOL)animated; // shows a checkmark instead of the activity indicator and hides the status bar after the specified duration -- (void)postFinishMessage:(NSString *)message duration:(NSTimeInterval)duration; -- (void)postFinishMessage:(NSString *)message duration:(NSTimeInterval)duration animated:(BOOL)animated; +- (void)postFinishMessage:(NSString *)message key:(NSString *)key duration:(NSTimeInterval)duration; +- (void)postFinishMessage:(NSString *)message key:(NSString *)key duration:(NSTimeInterval)duration animated:(BOOL)animated; // clears the message queue and shows this message instantly -- (void)postImmediateFinishMessage:(NSString *)message duration:(NSTimeInterval)duration animated:(BOOL)animated; +- (void)postImmediateFinishMessage:(NSString *)message key:(NSString *)key duration:(NSTimeInterval)duration animated:(BOOL)animated; // shows a error-sign instead of the activity indicator and hides the status bar after the specified duration -- (void)postErrorMessage:(NSString *)message duration:(NSTimeInterval)duration; -- (void)postErrorMessage:(NSString *)message duration:(NSTimeInterval)duration animated:(BOOL)animated; +- (void)postErrorMessage:(NSString *)message key:(NSString *)key duration:(NSTimeInterval)duration; +- (void)postErrorMessage:(NSString *)message key:(NSString *)key duration:(NSTimeInterval)duration animated:(BOOL)animated; // clears the message queue and shows this message instantly -- (void)postImmediateErrorMessage:(NSString *)message duration:(NSTimeInterval)duration animated:(BOOL)animated; +- (void)postImmediateErrorMessage:(NSString *)message key:(NSString *)key duration:(NSTimeInterval)duration animated:(BOOL)animated; + +// remove all or certain messages +- (void)removeMessageFromHistoryForKey:(NSString *)key; +- (void)removeAllMessages; + +// set progress +- (void)setProgress:(double)progress key:(NSString *)key; // hides the status bar overlay and resets it - (void)hide; diff --git a/MTStatusBarOverlay.m b/MTStatusBarOverlay.m index 884bc2e..24a5589 100755 --- a/MTStatusBarOverlay.m +++ b/MTStatusBarOverlay.m @@ -20,6 +20,7 @@ // ------------------------------- #import "MTStatusBarOverlay.h" +#import "MTStatusBarTableViewCell.h" #import @@ -51,6 +52,9 @@ #define IsIPhoneEmulationMode (!IsIPad && \ MAX([UIApplication sharedApplication].statusBarFrame.size.width, [UIApplication sharedApplication].statusBarFrame.size.height) > 480.f) +//Doesn't matter what number this is, as long as it is much greater than any realistic index of a message. No one will have 515 messages. +#define kCurrentMessage 515 + //////////////////////////////////////////////////////////////////////// @@ -165,6 +169,23 @@ #pragma mark Class Extension //////////////////////////////////////////////////////////////////////// +@interface UIView (FindViewController) +- (UIViewController *)viewController; +@end + +@implementation UIView (FindViewController) + +- (UIViewController *)viewController; +{ + id nextResponder = [self nextResponder]; + if ([nextResponder isKindOfClass:[UIViewController class]]) { + return nextResponder; + } else { + return nil; + } +} +@end + @interface MTStatusBarOverlay () @property (nonatomic, strong) UIActivityIndicatorView *activityIndicator; @@ -186,14 +207,26 @@ @interface MTStatusBarOverlay () @property (nonatomic, strong) NSMutableArray *messageHistory; @property (nonatomic, strong) UITableView *historyTableView; @property (nonatomic, assign) BOOL forcedToHide; +@property (nonatomic, assign) UIStatusBarStyle currentStatusBarStyle; + +//the view that contains the progress bar +@property (nonatomic, strong) UIView *maskingProgressView; +//the progress bar, which is actually a label +@property (nonatomic, strong) UILabel *maskingLabel; +//an array that holds all the keys for the messages +@property (nonatomic, strong) NSMutableArray *keyArray; +//detect whether the status bar is hidden or not +@property (nonatomic) BOOL statusBarHidden; // intern method that posts a new entry to the message-queue -- (void)postMessage:(NSString *)message type:(MTMessageType)messageType duration:(NSTimeInterval)duration animated:(BOOL)animated immediate:(BOOL)immediate; +- (void)postMessage:(NSString *)message key:(NSString *)key type:(MTMessageType)messageType duration:(NSTimeInterval)duration animated:(BOOL)animated immediate:(BOOL)immediate; // intern method that clears the messageQueue and then posts a new entry to it -- (void)postImmediateMessage:(NSString *)message type:(MTMessageType)messageType duration:(NSTimeInterval)duration animated:(BOOL)animated; +- (void)postImmediateMessage:(NSString *)message key:(NSString *)key type:(MTMessageType)messageType duration:(NSTimeInterval)duration animated:(BOOL)animated; // intern method that does all the work of showing the next message in the queue - (void)showNextMessage; +-(CGRect)statusBarFrame; + // is called when the user touches the statusbar - (void)contentViewClicked:(UIGestureRecognizer *)gestureRecognizer; // is called when the user swipes down the statusbar @@ -221,9 +254,14 @@ - (void)setHidden:(BOOL)hidden useAlpha:(BOOL)useAlpha; - (void)setHiddenUsingAlpha:(BOOL)hidden; // set hidden-state of detailView - (void)setDetailViewHidden:(BOOL)hidden animated:(BOOL)animated; +- (void)changeWindowHeightTo:(CGFloat)newHeight; + +// sets progress on specific cell +- (void)setProgress:(double) onCell:(UITableViewCell *)cell; // History-tracking -- (void)addMessageToHistory:(NSString *)message; +- (void)addMessageToHistory:(NSString *)message key:(NSString *)key messageType:(MTMessageType)messageType; +- (void)removeMessageAtIndexFromHistory:(NSUInteger)index; - (void)clearHistory; // selectors @@ -234,9 +272,6 @@ - (void)didChangeStatusBarFrame:(NSNotification *)notification; - (void)applicationDidBecomeActive:(NSNotification *)notifaction; - (void)applicationWillResignActive:(NSNotification *)notifaction; -// returns the current frame for the detail view depending on the interface orientation -- (CGRect)backgroundViewFrameForStatusBarInterfaceOrientation; - @end @@ -249,7 +284,8 @@ @implementation MTStatusBarOverlay @synthesize statusLabel1 = statusLabel1_; @synthesize statusLabel2 = statusLabel2_; @synthesize hiddenStatusLabel = hiddenStatusLabel_; -@synthesize progress = progress_; +@synthesize progressDictionary = progressDictionary_; +@synthesize mainProgress = mainProgress_; @synthesize progressView = progressView_; @synthesize activityIndicator = activityIndicator_; @synthesize finishedLabel = finishedLabel_; @@ -271,6 +307,11 @@ @implementation MTStatusBarOverlay @synthesize delegate = delegate_; @synthesize forcedToHide = forcedToHide_; @synthesize lastPostedMessage = lastPostedMessage_; +@synthesize maskingProgressView = maskingProgressView_; +@synthesize maskingLabel = maskingLabel_; +@synthesize keyArray = keyArray_; +@synthesize statusBarHidden = statusBarHidden_; +@synthesize currentStatusBarStyle = currentStatusBarStyle_; //////////////////////////////////////////////////////////////////////// #pragma mark - @@ -279,14 +320,7 @@ @implementation MTStatusBarOverlay - (id)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { - CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame; - - // only use height of 20px even is status bar is doubled - statusBarFrame.size.height = statusBarFrame.size.height == 2*kStatusBarHeight ? kStatusBarHeight : statusBarFrame.size.height; - // if we are on the iPad but in iPhone-Mode (non-universal-app) correct the width - if(IsIPhoneEmulationMode) { - statusBarFrame.size.width = 320.f; - } + CGRect statusBarFrame = [self statusBarFrame]; // Place the window on the correct level and position self.windowLevel = UIWindowLevelStatusBar+1.f; @@ -334,7 +368,7 @@ - (id)initWithFrame:(CGRect)frame { historyTableView_ = [[UITableView alloc] initWithFrame:CGRectMake(0, kStatusBarHeight, kDefaultDetailViewFrame.size.width, kDefaultDetailViewFrame.size.height - kStatusBarHeight)]; historyTableView_.dataSource = self; - historyTableView_.delegate = nil; + historyTableView_.delegate = self; historyTableView_.rowHeight = kHistoryTableRowHeight; historyTableView_.separatorStyle = UITableViewCellSeparatorStyleNone; // make table view-background transparent @@ -347,8 +381,7 @@ - (id)initWithFrame:(CGRect)frame { [self addSubview:detailView_]; // Create view that stores all the content - CGRect backgroundFrame = [self backgroundViewFrameForStatusBarInterfaceOrientation]; - backgroundView_ = [[UIView alloc] initWithFrame:backgroundFrame]; + backgroundView_ = [[UIView alloc] initWithFrame:statusBarFrame]; backgroundView_.clipsToBounds = YES; backgroundView_.autoresizingMask = UIViewAutoresizingFlexibleWidth; oldBackgroundViewFrame_ = backgroundView_.frame; @@ -371,6 +404,7 @@ - (id)initWithFrame:(CGRect)frame { // Background-Image of the Content View statusBarBackgroundImageView_ = [[UIImageView alloc] initWithFrame:backgroundView_.frame]; + statusBarBackgroundImageView_.backgroundColor = [UIColor blackColor]; statusBarBackgroundImageView_.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; [self addSubviewToBackgroundView:statusBarBackgroundImageView_]; @@ -422,12 +456,30 @@ - (id)initWithFrame:(CGRect)frame { // the hidden status label at the beginning hiddenStatusLabel_ = statusLabel2_; - progress_ = 1.0; - progressView_ = [[UIImageView alloc] initWithFrame:statusBarBackgroundImageView_.frame]; - progressView_.opaque = NO; - progressView_.hidden = YES; - progressView_.alpha = kProgressViewAlpha; - [self addSubviewToBackgroundView:progressView_]; + mainProgress_ = 1.0; + progressDictionary_ = [NSMutableDictionary dictionary]; + maskingProgressView_ = [[UIView alloc] initWithFrame:[self statusBarFrame]]; + maskingProgressView_.clipsToBounds = YES; + maskingProgressView_.backgroundColor = [UIColor clearColor]; + maskingProgressView_.hidden = YES; + + maskingLabel_ = [[UILabel alloc] initWithFrame:CGRectMake(30.0f, 0.0f, backgroundView_.frame.size.width - 60.0f,backgroundView_.frame.size.height-1)]; + maskingLabel_.backgroundColor = [UIColor clearColor]; + maskingLabel_.font = [UIFont boldSystemFontOfSize:kStatusLabelSize]; + maskingLabel_.textAlignment = UITextAlignmentCenter; + maskingLabel_.numberOfLines = 1; + maskingLabel_.lineBreakMode = UILineBreakModeTailTruncation; + maskingLabel_.autoresizingMask = UIViewAutoresizingFlexibleWidth; + maskingLabel_.textColor = [UIColor blueColor]; + + NSMutableDictionary *keyDictionary = [[NSMutableDictionary alloc] initWithObjectsAndKeys:@"Remove Messages", @"key", [NSNumber numberWithInteger:MTMessageTypePlain], @"messageType", nil]; + self.keyArray = [[NSMutableArray alloc] initWithObjects:keyDictionary, nil]; + + UIView *holdingView = [[UIView alloc] initWithFrame:maskingProgressView_.frame]; + [holdingView addSubview:maskingLabel_]; + + [maskingProgressView_ addSubview:holdingView]; + [self addSubviewToBackgroundView:maskingProgressView_]; messageQueue_ = [[NSMutableArray alloc] init]; canRemoveImmediateMessagesFromQueue_ = YES; @@ -446,9 +498,6 @@ - (id)initWithFrame:(CGRect)frame { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillResignActive:) name:UIApplicationWillResignActiveNotification object:nil]; - - // initial rotation, fixes the issue with a wrong bar appearance in landscape only mode - [self rotateToStatusBarFrame:nil]; } return self; @@ -465,6 +514,21 @@ - (void)dealloc { #pragma mark Status Bar Appearance //////////////////////////////////////////////////////////////////////// +-(CGRect)statusBarFrame { + UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; + CGRect statusBarFrame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 20); + if (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight) { + statusBarFrame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.height, 20); + } + // only use height of 20px even is status bar is doubled + //statusBarFrame.size.height = statusBarFrame.size.height == 2*kStatusBarHeight ? kStatusBarHeight : statusBarFrame.size.height; + // if we are on the iPad but in iPhone-Mode (non-universal-app) correct the width + if(IsIPhoneEmulationMode) { + statusBarFrame.size.width = 320; + } + return statusBarFrame; +} + - (void)addSubviewToBackgroundView:(UIView *)view { view.userInteractionEnabled = NO; [self.backgroundView addSubview:view]; @@ -504,78 +568,71 @@ - (void)restoreState { #pragma mark Message Posting //////////////////////////////////////////////////////////////////////// -- (void)postMessage:(NSString *)message { - [self postMessage:message animated:YES]; +- (void)postMessage:(NSString *)message key:(NSString *)key { + [self postMessage:message key:key animated:YES]; } -- (void)postMessage:(NSString *)message animated:(BOOL)animated { - [self postMessage:message type:MTMessageTypeActivity duration:0 animated:animated immediate:NO]; +- (void)postMessage:(NSString *)message key:(NSString *)key animated:(BOOL)animated { + [self postMessage:message key:key type:MTMessageTypeActivity duration:0 animated:animated immediate:NO]; } -- (void)postMessage:(NSString *)message duration:(NSTimeInterval)duration { - [self postMessage:message type:MTMessageTypeActivity duration:duration animated:YES immediate:NO]; +- (void)postMessage:(NSString *)message key:(NSString *)key duration:(NSTimeInterval)duration { + [self postMessage:message key:key type:MTMessageTypeActivity duration:duration animated:YES immediate:NO]; } -- (void)postMessage:(NSString *)message duration:(NSTimeInterval)duration animated:(BOOL)animated { - [self postMessage:message type:MTMessageTypeActivity duration:duration animated:animated immediate:NO]; +- (void)postMessage:(NSString *)message key:(NSString *)key duration:(NSTimeInterval)duration animated:(BOOL)animated { + [self postMessage:message key:key type:MTMessageTypeActivity duration:duration animated:animated immediate:NO]; } -- (void)postImmediateMessage:(NSString *)message animated:(BOOL)animated { - [self postImmediateMessage:message type:MTMessageTypeActivity duration:0 animated:animated]; +- (void)postImmediateMessage:(NSString *)message key:(NSString *)key animated:(BOOL)animated { + [self postImmediateMessage:message key:key type:MTMessageTypeActivity duration:0 animated:animated]; } -- (void)postImmediateMessage:(NSString *)message duration:(NSTimeInterval)duration { - [self postImmediateMessage:message type:MTMessageTypeActivity duration:duration animated:YES]; +- (void)postImmediateMessage:(NSString *)message key:(NSString *)key duration:(NSTimeInterval)duration { + [self postImmediateMessage:message key:key type:MTMessageTypeActivity duration:duration animated:YES]; } -- (void)postImmediateMessage:(NSString *)message duration:(NSTimeInterval)duration animated:(BOOL)animated { - [self postImmediateMessage:message type:MTMessageTypeActivity duration:duration animated:animated]; +- (void)postImmediateMessage:(NSString *)message key:(NSString *)key duration:(NSTimeInterval)duration animated:(BOOL)animated { + [self postImmediateMessage:message key:key type:MTMessageTypeActivity duration:duration animated:animated]; } -- (void)postFinishMessage:(NSString *)message duration:(NSTimeInterval)duration { - [self postFinishMessage:message duration:duration animated:YES]; +- (void)postFinishMessage:(NSString *)message key:(NSString *)key duration:(NSTimeInterval)duration { + [self postFinishMessage:message key:key duration:duration animated:YES]; } -- (void)postFinishMessage:(NSString *)message duration:(NSTimeInterval)duration animated:(BOOL)animated { - [self postMessage:message type:MTMessageTypeFinish duration:duration animated:animated immediate:NO]; +- (void)postFinishMessage:(NSString *)message key:(NSString *)key duration:(NSTimeInterval)duration animated:(BOOL)animated { + [self postMessage:message key:key type:MTMessageTypeFinish duration:duration animated:animated immediate:NO]; } -- (void)postImmediateFinishMessage:(NSString *)message duration:(NSTimeInterval)duration animated:(BOOL)animated { - [self postImmediateMessage:message type:MTMessageTypeFinish duration:duration animated:animated]; +- (void)postImmediateFinishMessage:(NSString *)message key:(NSString *)key duration:(NSTimeInterval)duration animated:(BOOL)animated { + [self postImmediateMessage:message key:key type:MTMessageTypeFinish duration:duration animated:animated]; } -- (void)postErrorMessage:(NSString *)message duration:(NSTimeInterval)duration { - [self postErrorMessage:message duration:duration animated:YES]; +- (void)postErrorMessage:(NSString *)message key:(NSString *)key duration:(NSTimeInterval)duration { + [self postErrorMessage:message key:key duration:duration animated:YES]; } -- (void)postErrorMessage:(NSString *)message duration:(NSTimeInterval)duration animated:(BOOL)animated { - [self postMessage:message type:MTMessageTypeError duration:duration animated:animated immediate:NO]; +- (void)postErrorMessage:(NSString *)message key:(NSString *)key duration:(NSTimeInterval)duration animated:(BOOL)animated { + [self postMessage:message key:key type:MTMessageTypeError duration:duration animated:animated immediate:NO]; } -- (void)postImmediateErrorMessage:(NSString *)message duration:(NSTimeInterval)duration animated:(BOOL)animated { - [self postImmediateMessage:message type:MTMessageTypeError duration:duration animated:animated]; +- (void)postImmediateErrorMessage:(NSString *)message key:(NSString *)key duration:(NSTimeInterval)duration animated:(BOOL)animated { + [self postImmediateMessage:message key:key type:MTMessageTypeError duration:duration animated:animated]; } -- (void)postMessageDictionary:(NSDictionary *)messageDictionary { - [self postMessage:[messageDictionary valueForKey:kMTStatusBarOverlayMessageKey] - type:[[messageDictionary valueForKey:kMTStatusBarOverlayMessageTypeKey] intValue] - duration:[[messageDictionary valueForKey:kMTStatusBarOverlayDurationKey] doubleValue] - animated:[[messageDictionary valueForKey:kMTStatusBarOverlayAnimationKey] boolValue] - immediate:[[messageDictionary valueForKey:kMTStatusBarOverlayImmediateKey] boolValue]]; -} -- (void)postMessage:(NSString *)message type:(MTMessageType)messageType duration:(NSTimeInterval)duration animated:(BOOL)animated immediate:(BOOL)immediate { +- (void)postMessage:(NSString *)message key:(NSString *)key type:(MTMessageType)messageType duration:(NSTimeInterval)duration animated:(BOOL)animated immediate:(BOOL)immediate { mt_dispatch_sync_on_main_thread(^{ // don't add to queue when message is empty if (message.length == 0) { return; } - NSDictionary *messageDictionaryRepresentation = [NSDictionary dictionaryWithObjectsAndKeys:message, kMTStatusBarOverlayMessageKey, [NSNumber numberWithInt:messageType], kMTStatusBarOverlayMessageTypeKey, [NSNumber numberWithDouble:duration], kMTStatusBarOverlayDurationKey, [NSNumber numberWithBool:animated], kMTStatusBarOverlayAnimationKey, - [NSNumber numberWithBool:immediate], kMTStatusBarOverlayImmediateKey, nil]; + [NSNumber numberWithBool:immediate], kMTStatusBarOverlayImmediateKey, + key, kMTStatusBarOverlayKeyKey, nil]; @synchronized (self.messageQueue) { [self.messageQueue insertObject:messageDictionaryRepresentation atIndex:0]; @@ -588,7 +645,7 @@ - (void)postMessage:(NSString *)message type:(MTMessageType)messageType duration }); } -- (void)postImmediateMessage:(NSString *)message type:(MTMessageType)messageType duration:(NSTimeInterval)duration animated:(BOOL)animated { +- (void)postImmediateMessage:(NSString *)message key:(NSString *)key type:(MTMessageType)messageType duration:(NSTimeInterval)duration animated:(BOOL)animated { @synchronized(self.messageQueue) { NSMutableArray *clearedMessages = [NSMutableArray array]; @@ -607,7 +664,64 @@ - (void)postImmediateMessage:(NSString *)message type:(MTMessageType)messageType } } - [self postMessage:message type:messageType duration:duration animated:animated immediate:YES]; + [self postMessage:message key:key type:messageType duration:duration animated:animated immediate:YES]; +} + +- (void)postMessageDictionary:(NSDictionary *)messageDictionary { + [self postMessage:[messageDictionary valueForKey:kMTStatusBarOverlayMessageKey] + key:[messageDictionary valueForKey:kMTStatusBarOverlayKeyKey] + type:[[messageDictionary valueForKey:kMTStatusBarOverlayMessageTypeKey] intValue] + duration:[[messageDictionary valueForKey:kMTStatusBarOverlayDurationKey] doubleValue] + animated:[[messageDictionary valueForKey:kMTStatusBarOverlayAnimationKey] boolValue] + immediate:[[messageDictionary valueForKey:kMTStatusBarOverlayImmediateKey] boolValue]]; +} + +//////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark Removing Messages +//////////////////////////////////////////////////////////////////////// + +- (void)removeMessageFromHistoryForKey:(NSString *)key { + NSUInteger count = [self.messageHistory count]; + BOOL successful = NO; + if ([key isEqualToString:[[self.keyArray lastObject] objectForKey:@"key"]]) { + [self removeMessageAtIndexFromHistory:kCurrentMessage];//arbitrary number I chose designating this message is the one being shown on the status bar + successful = YES; + } + else if (count > 0) { + for (int i = count - 1; i >= 0; i--) { + NSMutableDictionary *dictionary = [self.messageHistory objectAtIndex:i]; + NSString *compare = [dictionary objectForKey:key]; + if ([compare isEqualToString:@"Key"]) { + [self removeMessageAtIndexFromHistory:i]; + successful = YES; + i = -1; + } + } + } +} + +-(void)removeAllMessages { + @synchronized(self.messageQueue) { + NSMutableArray *clearedMessages = [NSMutableArray array]; + + for (id messageDictionary in self.messageQueue) { + if (messageDictionary != [self.messageQueue lastObject] && + (self.canRemoveImmediateMessagesFromQueue || [[messageDictionary valueForKey:kMTStatusBarOverlayImmediateKey] boolValue] == NO)) { + [clearedMessages addObject:messageDictionary]; + } + } + + [self.messageQueue removeObjectsInArray:clearedMessages]; + + // call delegate + if (self.delegate != nil && [self.delegate respondsToSelector:@selector(statusBarOverlayDidHide)] && clearedMessages.count > 0) { + [self.delegate statusBarOverlayDidClearMessageQueue:clearedMessages]; + } + } + [self performSelector:@selector(hide)]; + [self clearHistory]; + [self.historyTableView reloadData]; } //////////////////////////////////////////////////////////////////////// @@ -642,6 +756,13 @@ - (void)showNextMessage { MTMessageType messageType = (MTMessageType)[[nextMessageDictionary valueForKey:kMTStatusBarOverlayMessageTypeKey] intValue]; NSTimeInterval duration = (NSTimeInterval)[[nextMessageDictionary valueForKey:kMTStatusBarOverlayDurationKey] doubleValue]; BOOL animated = [[nextMessageDictionary valueForKey:kMTStatusBarOverlayAnimationKey] boolValue]; + NSString *key = [nextMessageDictionary valueForKey:kMTStatusBarOverlayKeyKey]; + @synchronized(self.messageQueue) { + if ([self.messageHistory count] == 0) { + animated = NO; + } + } + maskingLabel_.text = message; // don't show anything if status bar is hidden (queue gets cleared) if([UIApplication sharedApplication].statusBarHidden) { @@ -655,7 +776,7 @@ - (void)showNextMessage { } // don't duplicate animation if already displaying with text - if (!self.reallyHidden && [self.visibleStatusLabel.text isEqualToString:message]) { + if (!self.reallyHidden && [self.visibleStatusLabel.text isEqualToString:message] && [[[self.keyArray lastObject] objectForKey:@"key"] isEqualToString:key]) { // remove unneccesary message @synchronized(self.messageQueue) { if (self.messageQueue.count > 0) @@ -684,10 +805,10 @@ - (void)showNextMessage { self.visibleStatusLabel.text = @""; // show status bar overlay with animation - [UIView animateWithDuration:self.shrinked ? 0 : kAppearAnimationDuration + [UIView animateWithDuration:self.shrinked ? 0 : kAppearAnimationDuration delay:0 options:UIViewAnimationOptionAllowUserInteraction animations:^{ [self setHidden:NO useAlpha:YES]; - }]; + } completion:NULL]; } @@ -695,11 +816,17 @@ - (void)showNextMessage { // set text of currently not visible label to new text self.hiddenStatusLabel.text = message; // update progressView to only cover displayed text - [self updateProgressViewSizeForLabel:self.hiddenStatusLabel]; + if (messageType == MTMessageTypeActivity) { + [self updateProgressViewSizeForLabel:self.hiddenStatusLabel]; + } + else { + self.maskingProgressView.frame = CGRectMake(0, self.maskingProgressView.frame.origin.y, 0, self.maskingProgressView.frame.size.height); + } + self.maskingProgressView.hidden = YES; - // position hidden status label under visible status label + // position hidden status label above visible status label self.hiddenStatusLabel.frame = CGRectMake(self.hiddenStatusLabel.frame.origin.x, - kStatusBarHeight, + 0 - kStatusBarHeight, self.hiddenStatusLabel.frame.size.width, self.hiddenStatusLabel.frame.size.height); @@ -709,20 +836,26 @@ - (void)showNextMessage { delay:0 options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction animations:^{ - // move both status labels up + // move both status labels down self.statusLabel1.frame = CGRectMake(self.statusLabel1.frame.origin.x, - self.statusLabel1.frame.origin.y - kStatusBarHeight, + self.statusLabel1.frame.origin.y + kStatusBarHeight, self.statusLabel1.frame.size.width, self.statusLabel1.frame.size.height); self.statusLabel2.frame = CGRectMake(self.statusLabel2.frame.origin.x, - self.statusLabel2.frame.origin.y - kStatusBarHeight, + self.statusLabel2.frame.origin.y + kStatusBarHeight, self.statusLabel2.frame.size.width, self.statusLabel2.frame.size.height); + [self addMessageToHistory:self.visibleStatusLabel.text key:[[self.keyArray lastObject] objectForKey:@"key"] messageType:[[[self.keyArray lastObject] objectForKey:@"messageType"] integerValue]]; } - completion:^(BOOL finished) { - // add old message to history - [self addMessageToHistory:self.visibleStatusLabel.text]; - + completion:^(BOOL finished) { + self.mainProgress = 0.0; + if (messageType == MTMessageTypeActivity) { + [self updateProgressViewSizeForLabel:self.hiddenStatusLabel]; + self.maskingProgressView.hidden = NO; + } + else { + self.maskingProgressView.hidden = YES; + } // after animation, set new hidden status label indicator if (self.hiddenStatusLabel == self.statusLabel1) { self.hiddenStatusLabel = self.statusLabel2; @@ -747,11 +880,16 @@ - (void)showNextMessage { // w/o animation just save old text and set new one else { // add old message to history - [self addMessageToHistory:self.visibleStatusLabel.text]; + [self addMessageToHistory:self.visibleStatusLabel.text key:[[self.keyArray lastObject] objectForKey:@"key"] messageType:[[[self.keyArray lastObject] objectForKey:@"messageType"] integerValue]]; // set new text self.visibleStatusLabel.text = message; // update progressView to only cover displayed text - [self updateProgressViewSizeForLabel:self.visibleStatusLabel]; + if (messageType == MTMessageTypeActivity) { + [self updateProgressViewSizeForLabel:self.visibleStatusLabel]; + } + else { + self.maskingProgressView.frame = CGRectMake(0, self.maskingProgressView.frame.origin.y, 0, self.maskingProgressView.frame.size.height); + } // remove the message from the queue @synchronized(self.messageQueue) { @@ -766,7 +904,20 @@ - (void)showNextMessage { [self performSelector:@selector(showNextMessage) withObject:nil afterDelay:kMinimumMessageVisibleTime]; } + self.mainProgress = 0.0; + self.lastPostedMessage = message; + + if (self.keyArray.count > 0) [self.keyArray removeLastObject]; + NSDictionary *keyDictionary = [[NSDictionary alloc] initWithObjectsAndKeys:key, @"key", [NSNumber numberWithInteger:messageType], @"messageType", nil]; + [self.keyArray insertObject:keyDictionary atIndex:0]; + + if (duration > 0) { + dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, duration * NSEC_PER_SEC); + dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ + [self performSelector:@selector(removeMessageFromHistoryForKey:) withObject:key]; + }); + } } - (void)hide { @@ -782,10 +933,7 @@ - (void)hide { [self setDetailViewHidden:YES animated:YES]; // hide status bar overlay with animation - [UIView animateWithDuration:self.shrinked ? 0. : kAppearAnimationDuration - delay:0 - options:UIViewAnimationOptionAllowUserInteraction - animations:^{ + [UIView animateWithDuration:self.shrinked ? 0. : kAppearAnimationDuration delay:0 options:UIViewAnimationOptionAllowUserInteraction animations:^{ [self setHidden:YES useAlpha:YES]; } completion:^(BOOL finished) { // call delegate @@ -867,8 +1015,8 @@ - (void)rotateToStatusBarFrame:(NSValue *)statusBarFrameValue { self.frame = CGRectMake(0.f,kScreenHeight - kStatusBarHeight,kScreenWidth,kStatusBarHeight); self.smallFrame = CGRectMake(self.frame.size.width - kWidthSmall, 0.f, kWidthSmall, self.frame.size.height); } - - self.backgroundView.frame = [self backgroundViewFrameForStatusBarInterfaceOrientation]; + self.maskingLabel.center = CGPointMake(self.visibleStatusLabel.center.x, self.maskingLabel.center.y); + [self setProgress:mainProgress_ key:kSetProgressOnStatusBarKey]; // if the statusBar is currently shrinked, update the frames for the new rotation state if (shrinkedBeforeTransformation) { @@ -888,7 +1036,7 @@ - (void)rotateToStatusBarFrame:(NSValue *)statusBarFrameValue { [UIView animateWithDuration:kAppearAnimationDuration delay:kRotationAppearDelay - options:UIViewAnimationOptionCurveEaseInOut + options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction animations:^{ [self setHiddenUsingAlpha:NO]; } @@ -901,17 +1049,93 @@ - (void)rotateToStatusBarFrame:(NSValue *)statusBarFrameValue { #pragma mark Setter/Getter //////////////////////////////////////////////////////////////////////// -- (void)setProgress:(double)progress { +- (void)setProgress:(double)progress key:(NSString *)key { // bound progress to 0.0 - 1.0 + progress = MAX(0.0, MIN(progress, 1.0)); + + NSNumber *progressNumber = [NSNumber numberWithDouble:progress]; // do not decrease progress if it is no reset - if (progress == 0.0 || progress > progress_) { - progress_ = progress; + if (progress == 0.0 || progress > [[self.progressDictionary objectForKey:key] doubleValue]) { + [self.progressDictionary setObject:progressNumber forKey:key]; + } + + BOOL success = NO; + if (![key isEqualToString:kSetProgressOnStatusBarKey]) { + for (int i = 0; i < [self.historyTableView numberOfRowsInSection:0]; i++) { + MTStatusBarTableViewCell *cell = (MTStatusBarTableViewCell *)[self.historyTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]]; + if ([cell.uuid isEqualToString:key]) { + [self setProgress:[progressNumber doubleValue] onCell:cell]; + success = YES; + i = [self.messageHistory count] + 1; + } + } } // update UI on main thread - [self performSelectorOnMainThread:@selector(updateProgressViewSizeForLabel:) withObject:self.visibleStatusLabel waitUntilDone:NO]; + if (!success) { + if (progress == 0.0 || progress > self.mainProgress) { + self.mainProgress = progress; + } + [self performSelectorOnMainThread:@selector(updateProgressViewSizeForLabel:) withObject:self.maskingLabel waitUntilDone:NO]; + } +} + +- (void)setProgress:(double)progress onCell:(MTStatusBarTableViewCell *)cell { + dispatch_async(dispatch_get_main_queue(), ^{ + NSMutableString *string = [[NSMutableString alloc] initWithFormat:@"%.0f", progress * 100]; + [string appendString:@"%"]; + cell.progressLabel.text = string; + }); +} + +- (void)showErrorMessage:(NSString *)string forKey:(id)key duration:(double)duration { + [self showMessage:string forType:MTMessageTypeError forKey:key duration:duration]; +} + +- (void)showFinishMessage:(NSString *)string forKey:(id)key duration:(double)duration { + [self showMessage:string forType:MTMessageTypeFinish forKey:key duration:duration]; +} + +- (void)showMessage:(NSString *)string forType:(MTMessageType)messageType forKey:(id)key duration:(double)duration { + BOOL success = NO; + for (int i = 0; i < [self.messageHistory count]; i++) { + NSString *uuid = [[self.messageHistory objectAtIndex:i] objectForKey:@"Key"]; + if ([uuid isEqualToString:key]) { + MTStatusBarTableViewCell *cell = (MTStatusBarTableViewCell *)[self.historyTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]]; + dispatch_async(dispatch_get_main_queue(), ^{ + [cell.activityIndicator stopAnimating]; + cell.textLabel.text = string; + cell.messageType = messageType; + if (messageType == MTMessageTypeFinish) { + cell.progressLabel.font = [UIFont boldSystemFontOfSize:kFinishedFontSize]; + cell.progressLabel.text = kFinishedText; + } + else if (messageType == MTMessageTypeError) { + cell.progressLabel.font = [UIFont boldSystemFontOfSize:kErrorFontSize]; + cell.progressLabel.text = kErrorText; + } + }); + success = YES; + i = [self.messageHistory count] + 1; + } + } + if (!success) { + dispatch_async(dispatch_get_main_queue(), ^{ + [self.activityIndicator stopAnimating]; + self.maskingProgressView.hidden = YES; + self.maskingProgressView.frame = [self statusBarFrame]; + mainProgress_ = 0.0; + self.visibleStatusLabel.text = string; + [self updateUIForMessageType:messageType duration:0]; + }); + } + + dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, duration * NSEC_PER_SEC); + dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ + [self performSelector:@selector(removeMessageFromHistoryForKey:) withObject:key]; + }); } - (void)setDetailText:(NSString *)detailText { @@ -962,7 +1186,7 @@ - (BOOL)isShrinked { } - (void)setShrinked:(BOOL)shrinked animated:(BOOL)animated { - [UIView animateWithDuration:animated ? kAnimationDurationShrink : 0. + [UIView animateWithDuration:animated ? kAnimationDurationShrink : 0. delay:0 options:UIViewAnimationOptionAllowUserInteraction animations:^{ // shrink the overlay if (shrinked) { @@ -992,7 +1216,7 @@ - (void)setShrinked:(BOOL)shrinked animated:(BOOL)animated { // update status bar background [self setStatusBarBackgroundForStyle:[UIApplication sharedApplication].statusBarStyle]; - }]; + } completion:NULL]; } @@ -1006,35 +1230,48 @@ - (void)setDetailViewHidden:(BOOL)hidden animated:(BOOL)animated { if (hidden) { [UIView animateWithDuration:animated ? kAnimationDurationFallDown : 0. delay:0. - options:UIViewAnimationOptionCurveEaseOut + options:UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionAllowUserInteraction animations: ^{ self.detailView.frame = CGRectMake(self.detailView.frame.origin.x, - self.detailView.frame.size.height, self.detailView.frame.size.width, self.detailView.frame.size.height); } completion:NULL]; + [self changeWindowHeightTo:[self statusBarFrame].size.height]; } // show detail view else { + float padding = 20.0f;//this hides the top corners of the history table so you don't see them when the MTStatusBarOverlay is translucent. + + CGFloat multiplier = [self.messageHistory count]; + if (multiplier > kMaxHistoryTableRowCount) multiplier = kMaxHistoryTableRowCount; + CGFloat detailViewHeight = ([self.historyTableView rowHeight] * multiplier) + kStatusBarHeight + padding; + self.detailView.frame = CGRectMake(self.detailView.frame.origin.x, self.detailView.frame.origin.y, + self.detailView.frame.size.width, detailViewHeight); + [self changeWindowHeightTo:detailViewHeight]; [UIView animateWithDuration:animated ? kAnimationDurationFallDown : 0. delay:0. - options:UIViewAnimationOptionCurveEaseIn + options:UIViewAnimationOptionCurveEaseIn | UIViewAnimationOptionAllowUserInteraction animations: ^{ - int y = 0; + float y = 0.0f; // if history is enabled let the detailView "grow" with // the number of messages in the history up until the set maximum + + if (self.detailViewMode == MTDetailViewModeHistory) { - y = -(kMaxHistoryTableRowCount - MIN(self.messageHistory.count, kMaxHistoryTableRowCount)) * kHistoryTableRowHeight; - self.historyTableView.frame = CGRectMake(self.historyTableView.frame.origin.x, kStatusBarHeight - y, - self.historyTableView.frame.size.width, self.historyTableView.frame.size.height); - } + + y = MIN(self.messageHistory.count, kMaxHistoryTableRowCount) * kHistoryTableRowHeight; + + self.historyTableView.frame = CGRectMake(self.historyTableView.frame.origin.x, kStatusBarHeight + padding, + self.historyTableView.frame.size.width, y); + } if (self.detailViewMode == MTDetailViewModeDetailText) { self.detailView.frame = CGRectMake(self.detailView.frame.origin.x, y, self.detailView.frame.size.width, self.detailTextView.frame.size.height + kStatusBarHeight); } else { - self.detailView.frame = CGRectMake(self.detailView.frame.origin.x, y, + self.detailView.frame = CGRectMake(self.detailView.frame.origin.x, 0 - padding, self.detailView.frame.size.width, self.detailView.frame.size.height); } } @@ -1051,6 +1288,28 @@ - (UILabel *)visibleStatusLabel { return self.statusLabel1; } +- (void)changeWindowHeightTo:(CGFloat)newHeight { + UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; + CGPoint origin = CGPointMake(self.frame.origin.x, self.frame.origin.y); + switch (orientation) { + case UIInterfaceOrientationLandscapeRight: + origin = CGPointMake([UIScreen mainScreen].bounds.size.width - newHeight, 0); + break; + case UIInterfaceOrientationLandscapeLeft: + origin = CGPointMake(0, 0); + break; + case UIInterfaceOrientationPortrait: + origin = CGPointMake(0, 0); + break; + case UIInterfaceOrientationPortraitUpsideDown: + origin = CGPointMake(0, [UIScreen mainScreen].bounds.size.height - newHeight); + default: + break; + } + self.bounds = CGRectMake(0, 0, self.bounds.size.width, newHeight); + self.frame = CGRectMake(origin.x, origin.y, self.frame.size.width, self.frame.size.height); +} + //////////////////////////////////////////////////////////////////////// #pragma mark - #pragma mark UITableViewDataSource @@ -1062,29 +1321,92 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellID = @"MTStatusBarOverlayHistoryCellID"; - UITableViewCell *cell = nil; + MTStatusBarTableViewCell *cell = nil; // step 1: is there a reusable cell? - cell = [tableView dequeueReusableCellWithIdentifier:cellID]; + cell = (MTStatusBarTableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellID]; // step 2: no? -> create new cell if (cell == nil) { - cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellID]; - - cell.textLabel.font = [UIFont boldSystemFontOfSize:10]; - cell.textLabel.textColor = [UIApplication sharedApplication].statusBarStyle == UIStatusBarStyleDefault ? kLightThemeHistoryTextColor : kDarkThemeHistoryTextColor; - - cell.detailTextLabel.font = [UIFont boldSystemFontOfSize:12]; - cell.detailTextLabel.textColor = [UIApplication sharedApplication].statusBarStyle == UIStatusBarStyleDefault ? kLightThemeHistoryTextColor : kDarkThemeHistoryTextColor; + cell = [[MTStatusBarTableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellID]; } // step 3: set up cell value - cell.textLabel.text = [self.messageHistory objectAtIndex:indexPath.row]; - cell.detailTextLabel.text = kFinishedText; + + cell.textLabel.font = self.statusLabel1.font; + cell.textLabel.textColor = [UIApplication sharedApplication].statusBarStyle == UIStatusBarStyleDefault ? kLightThemeHistoryTextColor : kDarkThemeHistoryTextColor; + + cell.progressLabel.font = [UIFont boldSystemFontOfSize:12]; + cell.progressLabel.textColor = [UIApplication sharedApplication].statusBarStyle == UIStatusBarStyleDefault ? kLightThemeHistoryTextColor : kDarkThemeHistoryTextColor; + + if ([self.messageHistory count] > indexPath.row) { + cell.textLabel.text = [[self.messageHistory objectAtIndex:indexPath.row] objectForKey:@"Text"]; + cell.uuid = [[self.messageHistory objectAtIndex:indexPath.row] objectForKey:@"Key"]; + cell.messageType = [[[self.messageHistory objectAtIndex:indexPath.row] objectForKey:@"MessageType"] integerValue]; + } + + cell.progressLabel.font = cell.textLabel.font; + cell.progressLabel.text = @""; + + if (![cell.uuid isEqualToString:@"Remove Messages"] && indexPath.row < [tableView numberOfRowsInSection:0] - 1 && cell.messageType == MTMessageTypeActivity) { + [cell.activityIndicator startAnimating]; + } + else [cell.activityIndicator stopAnimating]; + if (cell.messageType == MTMessageTypeFinish) { + cell.progressLabel.font = [UIFont boldSystemFontOfSize:kFinishedFontSize]; + cell.progressLabel.text = kFinishedText; + } + else if (cell.messageType == MTMessageTypeError) { + cell.progressLabel.font = [UIFont boldSystemFontOfSize:kErrorFontSize]; + cell.progressLabel.text = kErrorText; + } + else if (cell.messageType == MTMessageTypeActivity) { + cell.progressLabel.font = cell.textLabel.font; + if ([self.progressDictionary objectForKey:cell.uuid]) { + [self setProgress:[[self.progressDictionary objectForKey:cell.uuid] doubleValue] onCell:cell]; + } + } + + if (cell.messageType == MTMessageTypePlain || [cell.uuid isEqualToString:@"Remove Messages"]) { + cell.progressLabel.text = @""; + } + + if (indexPath.row == [tableView numberOfRowsInSection:0] - 1) cell.selectionStyle = UITableViewCellSelectionStyleGray; + else cell.selectionStyle = UITableViewCellSelectionStyleNone; + + return cell; } +//=========================================================== +#pragma mark - +#pragma mark Table View Delegate Methods +//=========================================================== + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + if (![self isDetailViewHidden]) { + if (indexPath.row == [tableView numberOfRowsInSection:0] - 1) { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Remove", @"Remove messages title") + message:NSLocalizedString(@"Are you sure you want to remove all messages?", @"Remove messages message") + delegate:self + cancelButtonTitle:NSLocalizedString(@"No", @"Delete Messages No") + otherButtonTitles:NSLocalizedString(@"Yes", @"Delete Messages Yes"), nil]; + alert.tag = 1; + [alert show]; + } + } +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { + if (alertView.tag == 1) { + if (buttonIndex == 1) { + [self removeAllMessages]; + } + [self.historyTableView deselectRowAtIndexPath:[NSIndexPath indexPathForRow:[self.historyTableView numberOfRowsInSection:0] - 1 inSection:0] animated:YES]; + } +} + //////////////////////////////////////////////////////////////////////// #pragma mark - #pragma mark Gesture Recognizer @@ -1141,6 +1463,19 @@ - (void)contentViewSwipedDown:(UIGestureRecognizer *)gestureRecognizer { } } +- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event +{ + for (UIView * view in [self subviews]) + { + if (!view.hidden && [view pointInside:[self convertPoint:point + toView:view] withEvent:event]) + { + return YES; + } + } + return NO; +} + //////////////////////////////////////////////////////////////////////// #pragma mark - #pragma mark UIApplication Notifications @@ -1167,18 +1502,30 @@ - (void)setStatusBarBackgroundForStyle:(UIStatusBarStyle)style { // on iPad the Default Status Bar Style is black too if (style == UIStatusBarStyleDefault && !IsIPad && !IsIPhoneEmulationMode) { // choose image depending on size + statusBarBackgroundImageView_.backgroundColor = [UIColor clearColor]; if (self.shrinked) { self.statusBarBackgroundImageView.image = [self.defaultStatusBarImageShrinked stretchableImageWithLeftCapWidth:2.0f topCapHeight:0.0f]; } else { self.statusBarBackgroundImageView.image = [self.defaultStatusBarImage stretchableImageWithLeftCapWidth:2.0f topCapHeight:0.0f]; } - statusBarBackgroundImageView_.backgroundColor = [UIColor clearColor]; } + // black status bar? -> no image else { + if (style == UIStatusBarStyleBlackTranslucent) { + statusBarBackgroundImageView_.backgroundColor = [UIColor colorWithWhite:0.0f alpha:0.5f]; + } + else { + statusBarBackgroundImageView_.backgroundColor = [UIColor blackColor]; + } self.statusBarBackgroundImageView.image = nil; - statusBarBackgroundImageView_.backgroundColor = [UIColor blackColor]; } + + if (style != currentStatusBarStyle_) { + [self.historyTableView reloadData]; + } + + currentStatusBarStyle_ = style; } - (void)setColorSchemeForStatusBarStyle:(UIStatusBarStyle)style messageType:(MTMessageType)messageType { @@ -1282,7 +1629,7 @@ - (void)updateUIForMessageType:(MTMessageType)messageType duration:(NSTimeInterv break; case MTMessageTypeFinish: // will call hide after delay - self.hideInProgress = YES; + //self.hideInProgress = YES; // show finished-label, hide acitvity indicator self.finishedLabel.hidden = self.hidesActivity; self.activityIndicator.hidden = YES; @@ -1293,11 +1640,11 @@ - (void)updateUIForMessageType:(MTMessageType)messageType duration:(NSTimeInterv // update font and text self.finishedLabel.font = [UIFont fontWithName:@"HelveticaNeue-Bold" size:kFinishedFontSize]; self.finishedLabel.text = kFinishedText; - self.progress = 1.0; + self.mainProgress = 1.0; break; case MTMessageTypeError: // will call hide after delay - self.hideInProgress = YES; + //self.hideInProgress = YES; // show finished-label, hide activity indicator self.finishedLabel.hidden = self.hidesActivity; self.activityIndicator.hidden = YES; @@ -1308,17 +1655,16 @@ - (void)updateUIForMessageType:(MTMessageType)messageType duration:(NSTimeInterv // update font and text self.finishedLabel.font = [UIFont boldSystemFontOfSize:kErrorFontSize]; self.finishedLabel.text = kErrorText; - self.progress = 1.0; + self.mainProgress = 1.0; break; + case MTMessageTypePlain: + self.activityIndicator.hidden = YES; + self.mainProgress = 0.0; + + // stop activity indicator + [self.activityIndicator stopAnimating]; } - // if a duration is specified, hide after given duration - if (duration > 0.) { - // hide after duration - [self performSelector:@selector(hide) withObject:nil afterDelay:duration]; - // clear history after duration - [self performSelector:@selector(clearHistory) withObject:nil afterDelay:duration]; - } } - (void)callDelegateWithNewMessage:(NSString *)newMessage { @@ -1326,7 +1672,7 @@ - (void)callDelegateWithNewMessage:(NSString *)newMessage { NSString *oldMessage = nil; if (self.messageHistory.count > 0) { - oldMessage = [self.messageHistory lastObject]; + oldMessage = [[self.messageHistory lastObject] objectForKey:@"Text"]; } [self.delegate statusBarOverlayDidSwitchFromOldMessage:oldMessage @@ -1341,37 +1687,16 @@ - (void)updateDetailTextViewHeight { } - (void)updateProgressViewSizeForLabel:(UILabel *)label { - if (self.progress < 1.) { - CGSize size = [label sizeThatFits:label.frame.size]; - CGFloat width = size.width * (float)(1. - self.progress); - CGFloat x = label.center.x + size.width/2.f - width; - - // if we werent able to determine a size, do nothing - if (size.width == 0.f) { - return; - } - - // progressView always covers only the visible portion of the text - // it "shrinks" to the right with increased progress to reveal more - // text under it - self.progressView.hidden = NO; - //[UIView animateWithDuration:self.progress > 0.0 ? kUpdateProgressViewDuration : 0.0 - // animations:^{ - self.progressView.frame = CGRectMake(x, self.progressView.frame.origin.y, - self.backgroundView.frame.size.width-x, self.progressView.frame.size.height); - // }]; - } else { - self.progressView.hidden = YES; - } -} - -- (CGRect)backgroundViewFrameForStatusBarInterfaceOrientation{ - - UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation]; - - return (UIInterfaceOrientationIsLandscape(interfaceOrientation) ? - CGRectMake(0, 0, kScreenHeight, kStatusBarHeight) : - CGRectMake(0, 0, kScreenWidth, kStatusBarHeight)); + [self.activityIndicator startAnimating]; + CGSize size = [label sizeThatFits:label.frame.size]; + CGFloat width = size.width; + CGFloat x = self.backgroundView.center.x + size.width/2.f - width; + [UIView animateWithDuration:self.mainProgress > 0.0 ? kUpdateProgressViewDuration : 0.0 delay:0 options:UIViewAnimationOptionAllowUserInteraction + animations:^{ + self.maskingProgressView.frame = CGRectMake(0, self.maskingProgressView.frame.origin.y, + width * self.mainProgress + x, + self.maskingProgressView.frame.size.height); + } completion:NULL]; } //////////////////////////////////////////////////////////////////////// @@ -1393,25 +1718,127 @@ - (void)setHistoryEnabled:(BOOL)historyEnabled { self.historyTableView.hidden = !historyEnabled; } -- (void)addMessageToHistory:(NSString *)message { - if (message != nil - && [message stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]].length > 0) { +- (void)addMessageToHistory:(NSString *)message key:(NSString *)key messageType:(MTMessageType)messageType { + if (message != nil) { // add message to history-array - [self.messageHistory addObject:message]; + if ([message stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]].length == 0) { + message = @"Remove all messages"; + key = @"Remove Messages"; + } + + NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:message, @"Text", @"Key", key, key, @"Key", [NSNumber numberWithInteger:messageType], @"MessageType", nil]; + [self.messageHistory insertObject:dictionary atIndex:0]; if (self.historyEnabled) { - NSIndexPath *newHistoryMessageIndexPath = [NSIndexPath indexPathForRow:self.messageHistory.count-1 inSection:0]; + NSIndexPath *newHistoryMessageIndexPath = [NSIndexPath indexPathForRow:0 inSection:0]; [self setDetailViewHidden:self.detailViewHidden animated:YES]; // update history table-view [self.historyTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newHistoryMessageIndexPath] withRowAnimation:UITableViewRowAnimationFade]; - [self.historyTableView scrollToRowAtIndexPath:newHistoryMessageIndexPath - atScrollPosition:UITableViewScrollPositionTop animated:YES]; + //[self.historyTableView scrollToRowAtIndexPath:newHistoryMessageIndexPath + //atScrollPosition:UITableViewScrollPositionTop animated:YES]; } } } +- (void)removeMessageAtIndexFromHistory:(NSUInteger)index { + if (self.historyEnabled && index < kCurrentMessage) { + NSIndexPath *newHistoryMessageIndexPath = [NSIndexPath indexPathForRow:index inSection:0]; + + [self.messageHistory removeObjectAtIndex:index]; + + [self setDetailViewHidden:self.detailViewHidden animated:YES]; + + // update history table-view + [self.historyTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:newHistoryMessageIndexPath] + withRowAnimation:UITableViewRowAnimationTop]; + } + else if ([self.messageHistory count] > 1) { + // set text of currently not visible label to new text + self.hiddenStatusLabel.text = [[self.messageHistory objectAtIndex:0] objectForKey:@"Text"]; + // update progressView to only cover displayed text + self.mainProgress = 0.0; + self.maskingLabel.text = self.hiddenStatusLabel.text; + [self updateProgressViewSizeForLabel:self.hiddenStatusLabel]; + + // position hidden status label under visible status label + self.hiddenStatusLabel.frame = CGRectMake(self.hiddenStatusLabel.frame.origin.x, + kStatusBarHeight, + self.hiddenStatusLabel.frame.size.width, + self.hiddenStatusLabel.frame.size.height); + + + // animate hidden label into user view and visible status label out of view + [UIView animateWithDuration:kNextStatusAnimationDuration + delay:0 + options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction + animations:^{ + // move both status labels up + self.statusLabel1.frame = CGRectMake(self.statusLabel1.frame.origin.x, + self.statusLabel1.frame.origin.y - kStatusBarHeight, + self.statusLabel1.frame.size.width, + self.statusLabel1.frame.size.height); + self.statusLabel2.frame = CGRectMake(self.statusLabel2.frame.origin.x, + self.statusLabel2.frame.origin.y - kStatusBarHeight, + self.statusLabel2.frame.size.width, + self.statusLabel2.frame.size.height); + + NSIndexPath *newHistoryMessageIndexPath = [NSIndexPath indexPathForRow:0 inSection:0]; + + [self.messageHistory removeObjectAtIndex:0]; + + [self setDetailViewHidden:self.detailViewHidden animated:YES]; + + [self.historyTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:newHistoryMessageIndexPath] + withRowAnimation:UITableViewRowAnimationTop]; + + /*self.detailView.frame = CGRectMake(self.detailView.frame.origin.x, + self.detailView.frame.origin.y - kStatusBarHeight, + self.detailView.frame.size.width, + self.detailView.frame.size.height);*/ + } + completion:^(BOOL finished) { + // add old message to history + //[self addMessageToHistory:self.visibleStatusLabel.text key:[[self.keyArray lastObject] objectForKey:@"key"] messageType:[[[self.keyArray lastObject] objectForKey:@"messageType"] integerValue]]; + + // after animation, set new hidden status label indicator + if (self.hiddenStatusLabel == self.statusLabel1) { + self.hiddenStatusLabel = self.statusLabel2; + } else { + self.hiddenStatusLabel = self.statusLabel1; + } + + // remove the message from the queue + /*@synchronized(self.messageQueue) { + if (self.messageQueue.count > 0) + [self.messageQueue removeLastObject]; + }*/ + + + // update history table-view + /*self.detailView.frame = CGRectMake(self.detailView.frame.origin.x, + self.detailView.frame.origin.y - kStatusBarHeight, + self.detailView.frame.size.width, + self.detailView.frame.size.height);*/ + + // inform delegate about message-switch + //[self callDelegateWithNewMessage:message]; + + + // show the next message + //[self performSelector:@selector(showNextMessage) withObject:nil afterDelay:kMinimumMessageVisibleTime]; + }]; + } + else { + [self clearHistory]; + [UIView animateWithDuration:self.shrinked ? 0 : kAppearAnimationDuration delay:0 options:UIViewAnimationOptionAllowUserInteraction + animations:^{ + [self setHidden:YES useAlpha:YES]; + } completion:NULL]; + } +} + - (void)clearHistory { [self.messageHistory removeAllObjects]; [self.historyTableView reloadData]; diff --git a/MTStatusBarTableViewCell.h b/MTStatusBarTableViewCell.h new file mode 100644 index 0000000..9b63edc --- /dev/null +++ b/MTStatusBarTableViewCell.h @@ -0,0 +1,22 @@ +// +// MTStatusBarTableViewCell.h +// +// Created by Riley Testut on 3/20/11. +// Copyright 2011 Riley Testut. All rights reserved. +// + +#import +#import "MTStatusBarOverlay.h" + +@interface MTStatusBarTableViewCell : UITableViewCell { + id __unsafe_unretained uuid; + NSInteger messageType; + UIActivityIndicatorView *activityIndicator; + UILabel *progressLabel; +} +@property (nonatomic, unsafe_unretained) id uuid; +@property (nonatomic, strong) UIActivityIndicatorView *activityIndicator; +@property (nonatomic, strong) UILabel *progressLabel; +@property (nonatomic) NSInteger messageType; + +@end diff --git a/MTStatusBarTableViewCell.m b/MTStatusBarTableViewCell.m new file mode 100644 index 0000000..3e828c1 --- /dev/null +++ b/MTStatusBarTableViewCell.m @@ -0,0 +1,59 @@ +// +// MTStatusBarTableViewCell.m +// +// Created by Riley Testut on 3/20/11. +// Copyright 2011 Riley Testut. All rights reserved. +// + +#import "MTStatusBarTableViewCell.h" + + +@implementation MTStatusBarTableViewCell +@synthesize uuid; +@synthesize activityIndicator; +@synthesize progressLabel; +@synthesize messageType; + +- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { + if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { + self.textLabel.adjustsFontSizeToFitWidth = YES; + self.selectionStyle = UITableViewCellSelectionStyleNone; + self.textLabel.lineBreakMode = UILineBreakModeTailTruncation; + self.progressLabel = [[UILabel alloc] initWithFrame:CGRectMake(226, 2, 44, 21)]; + [self.progressLabel setBackgroundColor:[UIColor clearColor]]; + self.progressLabel.lineBreakMode = UILineBreakModeTailTruncation; + self.progressLabel.adjustsFontSizeToFitWidth = YES; + [self.contentView addSubview:progressLabel]; + self.activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; + self.activityIndicator.hidesWhenStopped = YES; + [self.contentView addSubview:self.activityIndicator]; + } + return self; +} + +-(void)layoutSubviews { + [super layoutSubviews]; + self.textLabel.textAlignment = UITextAlignmentCenter; + self.progressLabel.textAlignment = UITextAlignmentCenter; + self.textLabel.frame = CGRectMake(35, self.textLabel.frame.origin.y, self.contentView.frame.size.width - 70, self.textLabel.frame.size.height); + self.activityIndicator.frame = CGRectMake(6.0f, 3.0f, self.contentView.frame.size.height - 6, self.contentView.frame.size.height - 6); + //self.titleLabel.adjustsFontSizeToFitWidth = YES; + //self.titleLabel.font = self.textLabel.font; + /*self.titleLabel.textAlignment = UITextAlignmentRight; + self.titleLabel.frame = self.textLabel.frame;*/ + //NSLog(@"%@: %f (out of %f)", self.textLabel.text, self.detailTextLabel.frame.size.width, self.contentView.frame.size.width); +} + +-(void)prepareForReuse { + [super prepareForReuse]; + self.textLabel.text = @""; + self.progressLabel.text = @""; +} +- (void)setSelected:(BOOL)selected animated:(BOOL)animated +{ + [super setSelected:selected animated:animated]; + + // Configure the view for the selected state +} + +@end