diff --git a/AlertsDemo/AlertsDemo.xcodeproj/project.pbxproj b/AlertsDemo/AlertsDemo.xcodeproj/project.pbxproj new file mode 100644 index 0000000..f2215fe --- /dev/null +++ b/AlertsDemo/AlertsDemo.xcodeproj/project.pbxproj @@ -0,0 +1,382 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 047F1BC016A5DC81008EA18D /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 047F1BBF16A5DC81008EA18D /* QuartzCore.framework */; }; + 047F1BCB16A5FB5F008EA18D /* image.png in Resources */ = {isa = PBXBuildFile; fileRef = 047F1BCA16A5FB5F008EA18D /* image.png */; }; + 047F1BE416A602EB008EA18D /* NSString+Trim.m in Sources */ = {isa = PBXBuildFile; fileRef = 047F1BCF16A602EB008EA18D /* NSString+Trim.m */; }; + 047F1BE516A602EB008EA18D /* UIFont+Alert.m in Sources */ = {isa = PBXBuildFile; fileRef = 047F1BD116A602EB008EA18D /* UIFont+Alert.m */; }; + 047F1BE616A602EB008EA18D /* UIView+Animations.m in Sources */ = {isa = PBXBuildFile; fileRef = 047F1BD316A602EB008EA18D /* UIView+Animations.m */; }; + 047F1BE716A602EB008EA18D /* MBAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = 047F1BD516A602EB008EA18D /* MBAlertView.m */; }; + 047F1BE816A602EB008EA18D /* MBHUDView.m in Sources */ = {isa = PBXBuildFile; fileRef = 047F1BD716A602EB008EA18D /* MBHUDView.m */; }; + 047F1BE916A602EB008EA18D /* MBAlertViewItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 047F1BDA16A602EB008EA18D /* MBAlertViewItem.m */; }; + 047F1BEA16A602EB008EA18D /* MBAlertViewButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 047F1BDF16A602EB008EA18D /* MBAlertViewButton.m */; }; + 047F1BEB16A602EB008EA18D /* MBCheckMarkView.m in Sources */ = {isa = PBXBuildFile; fileRef = 047F1BE116A602EB008EA18D /* MBCheckMarkView.m */; }; + 047F1BEC16A602EB008EA18D /* MBSpinningCircle.m in Sources */ = {isa = PBXBuildFile; fileRef = 047F1BE316A602EB008EA18D /* MBSpinningCircle.m */; }; + 04E09FA516A5D7B3008764C0 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04E09FA416A5D7B3008764C0 /* UIKit.framework */; }; + 04E09FA716A5D7B3008764C0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04E09FA616A5D7B3008764C0 /* Foundation.framework */; }; + 04E09FA916A5D7B3008764C0 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04E09FA816A5D7B3008764C0 /* CoreGraphics.framework */; }; + 04E09FAF16A5D7B3008764C0 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 04E09FAD16A5D7B3008764C0 /* InfoPlist.strings */; }; + 04E09FB116A5D7B3008764C0 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 04E09FB016A5D7B3008764C0 /* main.m */; }; + 04E09FB516A5D7B3008764C0 /* MBAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 04E09FB416A5D7B3008764C0 /* MBAppDelegate.m */; }; + 04E09FB716A5D7B3008764C0 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 04E09FB616A5D7B3008764C0 /* Default.png */; }; + 04E09FB916A5D7B3008764C0 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 04E09FB816A5D7B3008764C0 /* Default@2x.png */; }; + 04E09FBB16A5D7B3008764C0 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 04E09FBA16A5D7B3008764C0 /* Default-568h@2x.png */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 047F1BBF16A5DC81008EA18D /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 047F1BCA16A5FB5F008EA18D /* image.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = image.png; sourceTree = ""; }; + 047F1BCE16A602EB008EA18D /* NSString+Trim.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+Trim.h"; sourceTree = ""; }; + 047F1BCF16A602EB008EA18D /* NSString+Trim.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+Trim.m"; sourceTree = ""; }; + 047F1BD016A602EB008EA18D /* UIFont+Alert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIFont+Alert.h"; sourceTree = ""; }; + 047F1BD116A602EB008EA18D /* UIFont+Alert.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIFont+Alert.m"; sourceTree = ""; }; + 047F1BD216A602EB008EA18D /* UIView+Animations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+Animations.h"; sourceTree = ""; }; + 047F1BD316A602EB008EA18D /* UIView+Animations.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+Animations.m"; sourceTree = ""; }; + 047F1BD416A602EB008EA18D /* MBAlertView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBAlertView.h; sourceTree = ""; }; + 047F1BD516A602EB008EA18D /* MBAlertView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBAlertView.m; sourceTree = ""; }; + 047F1BD616A602EB008EA18D /* MBHUDView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBHUDView.h; sourceTree = ""; }; + 047F1BD716A602EB008EA18D /* MBHUDView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBHUDView.m; sourceTree = ""; }; + 047F1BD916A602EB008EA18D /* MBAlertViewItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBAlertViewItem.h; sourceTree = ""; }; + 047F1BDA16A602EB008EA18D /* MBAlertViewItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBAlertViewItem.m; sourceTree = ""; }; + 047F1BDB16A602EB008EA18D /* MBAlertViewSubclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBAlertViewSubclass.h; sourceTree = ""; }; + 047F1BDD16A602EB008EA18D /* AlertViewUI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AlertViewUI.h; sourceTree = ""; }; + 047F1BDE16A602EB008EA18D /* MBAlertViewButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBAlertViewButton.h; sourceTree = ""; }; + 047F1BDF16A602EB008EA18D /* MBAlertViewButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBAlertViewButton.m; sourceTree = ""; }; + 047F1BE016A602EB008EA18D /* MBCheckMarkView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBCheckMarkView.h; sourceTree = ""; }; + 047F1BE116A602EB008EA18D /* MBCheckMarkView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBCheckMarkView.m; sourceTree = ""; }; + 047F1BE216A602EB008EA18D /* MBSpinningCircle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBSpinningCircle.h; sourceTree = ""; }; + 047F1BE316A602EB008EA18D /* MBSpinningCircle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBSpinningCircle.m; sourceTree = ""; }; + 04E09FA016A5D7B3008764C0 /* AlertsDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AlertsDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 04E09FA416A5D7B3008764C0 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 04E09FA616A5D7B3008764C0 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 04E09FA816A5D7B3008764C0 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 04E09FAC16A5D7B3008764C0 /* AlertsDemo-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "AlertsDemo-Info.plist"; sourceTree = ""; }; + 04E09FAE16A5D7B3008764C0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + 04E09FB016A5D7B3008764C0 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 04E09FB216A5D7B3008764C0 /* AlertsDemo-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AlertsDemo-Prefix.pch"; sourceTree = ""; }; + 04E09FB316A5D7B3008764C0 /* MBAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MBAppDelegate.h; sourceTree = ""; }; + 04E09FB416A5D7B3008764C0 /* MBAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MBAppDelegate.m; sourceTree = ""; }; + 04E09FB616A5D7B3008764C0 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + 04E09FB816A5D7B3008764C0 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; + 04E09FBA16A5D7B3008764C0 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 04E09F9D16A5D7B3008764C0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 047F1BC016A5DC81008EA18D /* QuartzCore.framework in Frameworks */, + 04E09FA516A5D7B3008764C0 /* UIKit.framework in Frameworks */, + 04E09FA716A5D7B3008764C0 /* Foundation.framework in Frameworks */, + 04E09FA916A5D7B3008764C0 /* CoreGraphics.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 047F1BCC16A602EB008EA18D /* MBAlertView */ = { + isa = PBXGroup; + children = ( + 047F1BD416A602EB008EA18D /* MBAlertView.h */, + 047F1BD516A602EB008EA18D /* MBAlertView.m */, + 047F1BD616A602EB008EA18D /* MBHUDView.h */, + 047F1BD716A602EB008EA18D /* MBHUDView.m */, + 047F1BD816A602EB008EA18D /* Protected */, + 047F1BDC16A602EB008EA18D /* Views */, + 047F1BCD16A602EB008EA18D /* Categories */, + ); + name = MBAlertView; + path = ../../MBAlertView; + sourceTree = ""; + }; + 047F1BCD16A602EB008EA18D /* Categories */ = { + isa = PBXGroup; + children = ( + 047F1BCE16A602EB008EA18D /* NSString+Trim.h */, + 047F1BCF16A602EB008EA18D /* NSString+Trim.m */, + 047F1BD016A602EB008EA18D /* UIFont+Alert.h */, + 047F1BD116A602EB008EA18D /* UIFont+Alert.m */, + 047F1BD216A602EB008EA18D /* UIView+Animations.h */, + 047F1BD316A602EB008EA18D /* UIView+Animations.m */, + ); + path = Categories; + sourceTree = ""; + }; + 047F1BD816A602EB008EA18D /* Protected */ = { + isa = PBXGroup; + children = ( + 047F1BD916A602EB008EA18D /* MBAlertViewItem.h */, + 047F1BDA16A602EB008EA18D /* MBAlertViewItem.m */, + 047F1BDB16A602EB008EA18D /* MBAlertViewSubclass.h */, + ); + path = Protected; + sourceTree = ""; + }; + 047F1BDC16A602EB008EA18D /* Views */ = { + isa = PBXGroup; + children = ( + 047F1BDD16A602EB008EA18D /* AlertViewUI.h */, + 047F1BDE16A602EB008EA18D /* MBAlertViewButton.h */, + 047F1BDF16A602EB008EA18D /* MBAlertViewButton.m */, + 047F1BE016A602EB008EA18D /* MBCheckMarkView.h */, + 047F1BE116A602EB008EA18D /* MBCheckMarkView.m */, + 047F1BE216A602EB008EA18D /* MBSpinningCircle.h */, + 047F1BE316A602EB008EA18D /* MBSpinningCircle.m */, + ); + path = Views; + sourceTree = ""; + }; + 04E09F9516A5D7B3008764C0 = { + isa = PBXGroup; + children = ( + 04E09FAA16A5D7B3008764C0 /* AlertsDemo */, + 04E09FA316A5D7B3008764C0 /* Frameworks */, + 04E09FA116A5D7B3008764C0 /* Products */, + ); + sourceTree = ""; + }; + 04E09FA116A5D7B3008764C0 /* Products */ = { + isa = PBXGroup; + children = ( + 04E09FA016A5D7B3008764C0 /* AlertsDemo.app */, + ); + name = Products; + sourceTree = ""; + }; + 04E09FA316A5D7B3008764C0 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 047F1BBF16A5DC81008EA18D /* QuartzCore.framework */, + 04E09FA416A5D7B3008764C0 /* UIKit.framework */, + 04E09FA616A5D7B3008764C0 /* Foundation.framework */, + 04E09FA816A5D7B3008764C0 /* CoreGraphics.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 04E09FAA16A5D7B3008764C0 /* AlertsDemo */ = { + isa = PBXGroup; + children = ( + 04E09FB316A5D7B3008764C0 /* MBAppDelegate.h */, + 04E09FB416A5D7B3008764C0 /* MBAppDelegate.m */, + 047F1BCC16A602EB008EA18D /* MBAlertView */, + 04E09FAB16A5D7B3008764C0 /* Supporting Files */, + ); + path = AlertsDemo; + sourceTree = ""; + }; + 04E09FAB16A5D7B3008764C0 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 04E09FAC16A5D7B3008764C0 /* AlertsDemo-Info.plist */, + 047F1BCA16A5FB5F008EA18D /* image.png */, + 04E09FAD16A5D7B3008764C0 /* InfoPlist.strings */, + 04E09FB016A5D7B3008764C0 /* main.m */, + 04E09FB216A5D7B3008764C0 /* AlertsDemo-Prefix.pch */, + 04E09FB616A5D7B3008764C0 /* Default.png */, + 04E09FB816A5D7B3008764C0 /* Default@2x.png */, + 04E09FBA16A5D7B3008764C0 /* Default-568h@2x.png */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 04E09F9F16A5D7B3008764C0 /* AlertsDemo */ = { + isa = PBXNativeTarget; + buildConfigurationList = 04E09FBE16A5D7B3008764C0 /* Build configuration list for PBXNativeTarget "AlertsDemo" */; + buildPhases = ( + 04E09F9C16A5D7B3008764C0 /* Sources */, + 04E09F9D16A5D7B3008764C0 /* Frameworks */, + 04E09F9E16A5D7B3008764C0 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AlertsDemo; + productName = AlertsDemo; + productReference = 04E09FA016A5D7B3008764C0 /* AlertsDemo.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 04E09F9716A5D7B3008764C0 /* Project object */ = { + isa = PBXProject; + attributes = { + CLASSPREFIX = MB; + LastUpgradeCheck = 0450; + ORGANIZATIONNAME = "progenius, inc."; + }; + buildConfigurationList = 04E09F9A16A5D7B3008764C0 /* Build configuration list for PBXProject "AlertsDemo" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 04E09F9516A5D7B3008764C0; + productRefGroup = 04E09FA116A5D7B3008764C0 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 04E09F9F16A5D7B3008764C0 /* AlertsDemo */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 04E09F9E16A5D7B3008764C0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 04E09FAF16A5D7B3008764C0 /* InfoPlist.strings in Resources */, + 04E09FB716A5D7B3008764C0 /* Default.png in Resources */, + 04E09FB916A5D7B3008764C0 /* Default@2x.png in Resources */, + 04E09FBB16A5D7B3008764C0 /* Default-568h@2x.png in Resources */, + 047F1BCB16A5FB5F008EA18D /* image.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 04E09F9C16A5D7B3008764C0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 04E09FB116A5D7B3008764C0 /* main.m in Sources */, + 04E09FB516A5D7B3008764C0 /* MBAppDelegate.m in Sources */, + 047F1BE416A602EB008EA18D /* NSString+Trim.m in Sources */, + 047F1BE516A602EB008EA18D /* UIFont+Alert.m in Sources */, + 047F1BE616A602EB008EA18D /* UIView+Animations.m in Sources */, + 047F1BE716A602EB008EA18D /* MBAlertView.m in Sources */, + 047F1BE816A602EB008EA18D /* MBHUDView.m in Sources */, + 047F1BE916A602EB008EA18D /* MBAlertViewItem.m in Sources */, + 047F1BEA16A602EB008EA18D /* MBAlertViewButton.m in Sources */, + 047F1BEB16A602EB008EA18D /* MBCheckMarkView.m in Sources */, + 047F1BEC16A602EB008EA18D /* MBSpinningCircle.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 04E09FAD16A5D7B3008764C0 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 04E09FAE16A5D7B3008764C0 /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 04E09FBC16A5D7B3008764C0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = 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_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 04E09FBD16A5D7B3008764C0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 04E09FBF16A5D7B3008764C0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "AlertsDemo/AlertsDemo-Prefix.pch"; + INFOPLIST_FILE = "AlertsDemo/AlertsDemo-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Debug; + }; + 04E09FC016A5D7B3008764C0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "AlertsDemo/AlertsDemo-Prefix.pch"; + INFOPLIST_FILE = "AlertsDemo/AlertsDemo-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 04E09F9A16A5D7B3008764C0 /* Build configuration list for PBXProject "AlertsDemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 04E09FBC16A5D7B3008764C0 /* Debug */, + 04E09FBD16A5D7B3008764C0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 04E09FBE16A5D7B3008764C0 /* Build configuration list for PBXNativeTarget "AlertsDemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 04E09FBF16A5D7B3008764C0 /* Debug */, + 04E09FC016A5D7B3008764C0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 04E09F9716A5D7B3008764C0 /* Project object */; +} diff --git a/AlertsDemo/AlertsDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/AlertsDemo/AlertsDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..f2a6165 --- /dev/null +++ b/AlertsDemo/AlertsDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/AlertsDemo/AlertsDemo.xcodeproj/project.xcworkspace/xcuserdata/mohabitar.xcuserdatad/UserInterfaceState.xcuserstate b/AlertsDemo/AlertsDemo.xcodeproj/project.xcworkspace/xcuserdata/mohabitar.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..19dc01e Binary files /dev/null and b/AlertsDemo/AlertsDemo.xcodeproj/project.xcworkspace/xcuserdata/mohabitar.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/AlertsDemo/AlertsDemo.xcodeproj/project.xcworkspace/xcuserdata/mohabitar.xcuserdatad/WorkspaceSettings.xcsettings b/AlertsDemo/AlertsDemo.xcodeproj/project.xcworkspace/xcuserdata/mohabitar.xcuserdatad/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..659c876 --- /dev/null +++ b/AlertsDemo/AlertsDemo.xcodeproj/project.xcworkspace/xcuserdata/mohabitar.xcuserdatad/WorkspaceSettings.xcsettings @@ -0,0 +1,10 @@ + + + + + HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges + + SnapshotAutomaticallyBeforeSignificantChanges + + + diff --git a/AlertsDemo/AlertsDemo.xcodeproj/xcuserdata/mohabitar.xcuserdatad/xcschemes/AlertsDemo.xcscheme b/AlertsDemo/AlertsDemo.xcodeproj/xcuserdata/mohabitar.xcuserdatad/xcschemes/AlertsDemo.xcscheme new file mode 100644 index 0000000..e2bbbfa --- /dev/null +++ b/AlertsDemo/AlertsDemo.xcodeproj/xcuserdata/mohabitar.xcuserdatad/xcschemes/AlertsDemo.xcscheme @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AlertsDemo/AlertsDemo.xcodeproj/xcuserdata/mohabitar.xcuserdatad/xcschemes/xcschememanagement.plist b/AlertsDemo/AlertsDemo.xcodeproj/xcuserdata/mohabitar.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..97df699 --- /dev/null +++ b/AlertsDemo/AlertsDemo.xcodeproj/xcuserdata/mohabitar.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,22 @@ + + + + + SchemeUserState + + AlertsDemo.xcscheme + + orderHint + 0 + + + SuppressBuildableAutocreation + + 04E09F9F16A5D7B3008764C0 + + primary + + + + + diff --git a/AlertsDemo/AlertsDemo/AlertsDemo-Info.plist b/AlertsDemo/AlertsDemo/AlertsDemo-Info.plist new file mode 100644 index 0000000..cdd5cb1 --- /dev/null +++ b/AlertsDemo/AlertsDemo/AlertsDemo-Info.plist @@ -0,0 +1,38 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + com.progenius.${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 + + + diff --git a/AlertsDemo/AlertsDemo/AlertsDemo-Prefix.pch b/AlertsDemo/AlertsDemo/AlertsDemo-Prefix.pch new file mode 100644 index 0000000..1f1ed87 --- /dev/null +++ b/AlertsDemo/AlertsDemo/AlertsDemo-Prefix.pch @@ -0,0 +1,14 @@ +// +// Prefix header for all source files of the 'AlertsDemo' target in the 'AlertsDemo' project +// + +#import + +#ifndef __IPHONE_3_0 +#warning "This project uses features only available in iOS SDK 3.0 and later." +#endif + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/AlertsDemo/AlertsDemo/Default-568h@2x.png b/AlertsDemo/AlertsDemo/Default-568h@2x.png new file mode 100644 index 0000000..0891b7a Binary files /dev/null and b/AlertsDemo/AlertsDemo/Default-568h@2x.png differ diff --git a/AlertsDemo/AlertsDemo/Default.png b/AlertsDemo/AlertsDemo/Default.png new file mode 100644 index 0000000..4c8ca6f Binary files /dev/null and b/AlertsDemo/AlertsDemo/Default.png differ diff --git a/AlertsDemo/AlertsDemo/Default@2x.png b/AlertsDemo/AlertsDemo/Default@2x.png new file mode 100644 index 0000000..35b84cf Binary files /dev/null and b/AlertsDemo/AlertsDemo/Default@2x.png differ diff --git a/AlertsDemo/AlertsDemo/MBAppDelegate.h b/AlertsDemo/AlertsDemo/MBAppDelegate.h new file mode 100644 index 0000000..14f8689 --- /dev/null +++ b/AlertsDemo/AlertsDemo/MBAppDelegate.h @@ -0,0 +1,15 @@ +// +// MBAppDelegate.h +// AlertsDemo +// +// Created by M B. Bitar on 1/15/13. +// Copyright (c) 2013 progenius, inc. All rights reserved. +// + +#import + +@interface MBAppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + +@end diff --git a/AlertsDemo/AlertsDemo/MBAppDelegate.m b/AlertsDemo/AlertsDemo/MBAppDelegate.m new file mode 100644 index 0000000..ed8a6f1 --- /dev/null +++ b/AlertsDemo/AlertsDemo/MBAppDelegate.m @@ -0,0 +1,95 @@ +// +// MBAppDelegate.m +// AlertsDemo +// +// Created by M B. Bitar on 1/15/13. +// Copyright (c) 2013 progenius, inc. All rights reserved. +// + +#import "MBAppDelegate.h" +#import "MBHUDView.h" + +@implementation MBAppDelegate + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + self.window.backgroundColor = [UIColor whiteColor]; + [self.window makeKeyAndVisible]; + + UIViewController *controller = [UIViewController new]; + self.window.rootViewController = controller; + + [MBHUDView hudWithBody:@"Hello" type:MBAlertViewHUDTypeCheckmark hidesAfter:1.0 show:YES]; + MBAlertView *alert = [MBAlertView alertWithBody:@"Do you want to see more? (Note: you don't have a choice)" cancelTitle:nil cancelBlock:nil]; + [alert addButtonWithText:@"Yes" type:MBAlertViewItemTypePositive block:^{ + [MBHUDView hudWithBody:@"Say please" type:MBAlertViewHUDTypeExclamationMark hidesAfter:1.5 show:YES]; + MBAlertView *please = [MBAlertView alertWithBody:@"Did you say please?" cancelTitle:nil cancelBlock:nil]; + please.size = CGSizeMake(280, 180); + [please addButtonWithText:@"Yes" type:MBAlertViewItemTypePositive block:^{ + + [MBHUDView hudWithBody:@"Good boy." type:MBAlertViewHUDTypeCheckmark hidesAfter:1.0 show:YES]; + [MBHUDView hudWithBody:@"Wait." type:MBAlertViewHUDTypeActivityIndicator hidesAfter:4.0 show:YES]; + [MBHUDView hudWithBody:@"Ready?" type:MBAlertViewHUDTypeDefault hidesAfter:2.0 show:YES]; + + MBAlertView *destruct = [MBAlertView alertWithBody:@"Do you want your device to self-destruct?" cancelTitle:nil cancelBlock:nil]; + destruct.imageView.image = [UIImage imageNamed:@"image.png"]; + [destruct addButtonWithText:@"Yes please" type:MBAlertViewItemTypeDestructive block:^{ + [MBHUDView hudWithBody:@"Ok" type:MBAlertViewHUDTypeCheckmark hidesAfter:1.0 show:YES]; + [MBHUDView hudWithBody:@"5" type:MBAlertViewHUDTypeDefault hidesAfter:1.0 show:YES]; + [MBHUDView hudWithBody:@"4" type:MBAlertViewHUDTypeDefault hidesAfter:1.0 show:YES]; + [MBHUDView hudWithBody:@"3" type:MBAlertViewHUDTypeDefault hidesAfter:1.0 show:YES]; + [MBHUDView hudWithBody:@"2" type:MBAlertViewHUDTypeDefault hidesAfter:1.0 show:YES]; + [MBHUDView hudWithBody:@"1" type:MBAlertViewHUDTypeDefault hidesAfter:2.0 show:YES]; + [self doSomething:^{ + MBHUDView *hud = [MBHUDView hudWithBody:@"Goodbye" type:MBAlertViewHUDTypeExclamationMark hidesAfter:2.0 show:YES]; + hud.uponDismissalBlock = ^{ + [UIView animateWithDuration:0.5 animations:^{ [controller.view setBackgroundColor:[UIColor blackColor]]; }]; + }; + } afterDelay:2.0]; + }]; + [destruct addToDisplayQueue]; + + }]; + [please addToDisplayQueue]; + }]; + [alert addToDisplayQueue]; + return YES; +} + +-(void)doSomething:(id)block afterDelay:(float)delay +{ + dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delay * NSEC_PER_SEC); + dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ + ((void (^)())block)(); + }); +} + +- (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/AlertsDemo/AlertsDemo/en.lproj/InfoPlist.strings b/AlertsDemo/AlertsDemo/en.lproj/InfoPlist.strings new file mode 100644 index 0000000..477b28f --- /dev/null +++ b/AlertsDemo/AlertsDemo/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/AlertsDemo/AlertsDemo/image.png b/AlertsDemo/AlertsDemo/image.png new file mode 100644 index 0000000..98f329f Binary files /dev/null and b/AlertsDemo/AlertsDemo/image.png differ diff --git a/AlertsDemo/AlertsDemo/main.m b/AlertsDemo/AlertsDemo/main.m new file mode 100644 index 0000000..77a6b2a --- /dev/null +++ b/AlertsDemo/AlertsDemo/main.m @@ -0,0 +1,18 @@ +// +// main.m +// AlertsDemo +// +// Created by M B. Bitar on 1/15/13. +// Copyright (c) 2013 progenius, inc. All rights reserved. +// + +#import + +#import "MBAppDelegate.h" + +int main(int argc, char *argv[]) +{ + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([MBAppDelegate class])); + } +} diff --git a/MBAlertView/Categories/NSString+Trim.h b/MBAlertView/Categories/NSString+Trim.h new file mode 100644 index 0000000..35dd09b --- /dev/null +++ b/MBAlertView/Categories/NSString+Trim.h @@ -0,0 +1,13 @@ +// +// NSString+Trim.h +// AlertsDemo +// +// Created by M B. Bitar on 1/15/13. +// Copyright (c) 2013 progenius, inc. All rights reserved. +// + +#import + +@interface NSString (Trim) +-(NSString*)stringByTruncatingToSize:(CGSize)size withFont:(UIFont*)font addQuotes:(BOOL)addQuotes; +@end diff --git a/MBAlertView/Categories/NSString+Trim.m b/MBAlertView/Categories/NSString+Trim.m new file mode 100644 index 0000000..f7b001c --- /dev/null +++ b/MBAlertView/Categories/NSString+Trim.m @@ -0,0 +1,42 @@ +// +// NSString+Trim.m +// AlertsDemo +// +// Created by M B. Bitar on 1/15/13. +// Copyright (c) 2013 progenius, inc. All rights reserved. +// + +#import "NSString+Trim.h" + +@implementation NSString (Trim) + +-(NSString*)stringByTruncatingToSize:(CGSize)size withFont:(UIFont*)font addQuotes:(BOOL)addQuotes +{ + int min = 0, max = self.length, mid; + while (min < max) { + mid = (min+max)/2; + + NSString *currentString = [self substringWithRange:[self rangeOfComposedCharacterSequencesForRange:NSMakeRange(0, mid)]]; + CGSize currentSize = [currentString sizeWithFont:font constrainedToSize:CGSizeMake(size.width, MAXFLOAT)]; + currentString = nil; + + if (currentSize.height < size.height){ + min = mid + 1; + } else if (currentSize.height > size.height) { + max = mid - 1; + } else { + min = mid; + break; + } + } + /* handle emoji */ + NSMutableString *finalString = [[self substringWithRange:[self rangeOfComposedCharacterSequencesForRange:NSMakeRange(0, min)]] mutableCopy]; + int length = addQuotes ? 4 : 3; + NSString *appendString = addQuotes ? @"...\"" : @"..."; + if(finalString.length < self.length && finalString.length > length) { + [finalString replaceCharactersInRange:[finalString rangeOfComposedCharacterSequencesForRange:NSMakeRange(finalString.length - length, length)] withString:appendString]; + } + return finalString; +} + +@end diff --git a/MBAlertView/Categories/UIFont+Alert.h b/MBAlertView/Categories/UIFont+Alert.h new file mode 100644 index 0000000..3e543ec --- /dev/null +++ b/MBAlertView/Categories/UIFont+Alert.h @@ -0,0 +1,13 @@ +// +// UIFont+Alert.h +// AlertsDemo +// +// Created by M B. Bitar on 1/15/13. +// Copyright (c) 2013 progenius, inc. All rights reserved. +// + +#import + +@interface UIFont (Alert) ++(UIFont*)boldSystemFontThatFitsSize:(CGSize)size maxFontSize:(int)max minSize:(int)min text:(NSString*)text; +@end diff --git a/MBAlertView/Categories/UIFont+Alert.m b/MBAlertView/Categories/UIFont+Alert.m new file mode 100644 index 0000000..b1cba97 --- /dev/null +++ b/MBAlertView/Categories/UIFont+Alert.m @@ -0,0 +1,24 @@ +// +// UIFont+Alert.m +// AlertsDemo +// +// Created by M B. Bitar on 1/15/13. +// Copyright (c) 2013 progenius, inc. All rights reserved. +// + +#import "UIFont+Alert.h" + +@implementation UIFont (Alert) + ++(UIFont*)boldSystemFontThatFitsSize:(CGSize)size maxFontSize:(int)max minSize:(int)min text:(NSString*)text +{ + for(int i = max; i > min; i--) { + UIFont *font = [UIFont boldSystemFontOfSize:i]; + CGSize _size = [text sizeWithFont:font constrainedToSize:CGSizeMake(size.width, MAXFLOAT) lineBreakMode:NSLineBreakByWordWrapping]; + if(_size.height <= size.height) + return font; + } + return [UIFont boldSystemFontOfSize:min]; +} + +@end diff --git a/MBAlertView/Categories/UIView+Animations.h b/MBAlertView/Categories/UIView+Animations.h new file mode 100644 index 0000000..3f289ce --- /dev/null +++ b/MBAlertView/Categories/UIView+Animations.h @@ -0,0 +1,22 @@ +// +// UIView+Animations.h +// TwoTask +// +// Created by M B. Bitar on 12/21/12. +// Copyright (c) 2012 progenius, inc. All rights reserved. +// + +#import + +@interface UIView (Animations) +-(void)animationPop; +-(void)addFadingAnimation; +-(void)removePulseAnimation; +-(BOOL)hasPulseAnimation; +-(void)addPulsingAnimation; +-(void)addFadingAnimationWithDuration:(CGFloat)duration; + +// other +-(void)centerViewsVerticallyWithin:(NSArray*)views; +-(void)resignFirstRespondersForSubviews; +@end diff --git a/MBAlertView/Categories/UIView+Animations.m b/MBAlertView/Categories/UIView+Animations.m new file mode 100644 index 0000000..4b1d122 --- /dev/null +++ b/MBAlertView/Categories/UIView+Animations.m @@ -0,0 +1,157 @@ +// +// UIView+Animations.m +// TwoTask +// +// Created by M B. Bitar on 12/21/12. +// Copyright (c) 2012 progenius, inc. All rights reserved. +// + +#import "UIView+Animations.h" +#import + +@implementation UIView (Animations) +-(void)animationPop; +{ + CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"]; + + CATransform3D scale1 = CATransform3DMakeScale(1.0, 1.0, 1.0); + CATransform3D scale2 = CATransform3DMakeScale(1.35, 1.35, 1); + CATransform3D scale3 = CATransform3DMakeScale(0.8, 0.8, 1); + CATransform3D scale4 = CATransform3DMakeScale(1.0, 1.0, 1); + + NSArray *frameValues = [NSArray arrayWithObjects: + [NSValue valueWithCATransform3D:scale1], + [NSValue valueWithCATransform3D:scale2], + [NSValue valueWithCATransform3D:scale3], + [NSValue valueWithCATransform3D:scale4], + nil]; + [animation setValues:frameValues]; + + NSArray *frameTimes = [NSArray arrayWithObjects: + [NSNumber numberWithFloat:0.0], + [NSNumber numberWithFloat:0.5], + [NSNumber numberWithFloat:0.9], + [NSNumber numberWithFloat:1.0], + nil]; + [animation setKeyTimes:frameTimes]; + + animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; + animation.fillMode = kCAFillModeForwards; + animation.removedOnCompletion = YES; + animation.duration = 0.4; + + [self.layer addAnimation:animation forKey:@"popup"]; +} + +-(void)addPulsingAnimation; +{ + CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"]; + + CATransform3D scale1 = CATransform3DMakeScale(1.0, 1.0, 1.0); + CATransform3D scale2 = CATransform3DMakeScale(1.15, 1.15, 1); + CATransform3D scale3 = CATransform3DMakeScale(0.8, 0.8, 1); + CATransform3D scale4 = CATransform3DMakeScale(1.0, 1.0, 1); + + NSArray *frameValues = [NSArray arrayWithObjects: + [NSValue valueWithCATransform3D:scale1], + [NSValue valueWithCATransform3D:scale2], + [NSValue valueWithCATransform3D:scale3], + [NSValue valueWithCATransform3D:scale4], + nil]; + [animation setValues:frameValues]; + + NSArray *frameTimes = [NSArray arrayWithObjects: + [NSNumber numberWithFloat:0.0], + [NSNumber numberWithFloat:0.5], + [NSNumber numberWithFloat:0.9], + [NSNumber numberWithFloat:1.0], + nil]; + [animation setKeyTimes:frameTimes]; + + animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; + animation.fillMode = kCAFillModeForwards; + animation.removedOnCompletion = YES; + animation.autoreverses = YES; + animation.repeatCount = MAXFLOAT; + animation.duration = 0.6; + + [self.layer addAnimation:animation forKey:@"pulse"]; +} + +-(BOOL)hasPulseAnimation +{ + if([self.layer.animationKeys containsObject:@"pulse"]) + return YES; + return NO; +} + +-(void)removePulseAnimation +{ + [self.layer removeAnimationForKey:@"pulse"]; +} + +-(void)addFadingAnimationWithDuration:(CGFloat)duration +{ + CATransition *animation = [CATransition animation]; + animation.type = kCATransitionFade; + animation.subtype = kCATransitionFromBottom; + animation.duration = duration; + animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; + animation.fillMode = @"extended"; + animation.removedOnCompletion = YES; + [self.layer addAnimation:animation forKey:@"reloadAnimation"]; +} + +-(void)addFadingAnimation +{ + [self addFadingAnimationWithDuration:0.5]; +} + +#pragma mark -- +#pragma mark Other + +/* centers the views in the array with respect to self and given offset */ +/* views is an array of dictionarys with keys "view" "offset" */ +-(void)centerViewsVerticallyWithin:(NSArray*)views +{ + /* calculate y origin of first view */ + float heightOfAllViews = 0; + + for(NSDictionary *dic in views) { + UIView *view = [dic objectForKey:@"view"]; + + heightOfAllViews += view.bounds.size.height; + } + + float yOriginOfFirstView = self.bounds.size.height/2.0 - heightOfAllViews/2.0 + self.frame.origin.y; + float currentYOrigin = yOriginOfFirstView; + + for(NSDictionary *dic in views) { + UIView *view = [dic objectForKey:@"view"]; + float offset = [[dic objectForKey:@"offset"] floatValue]; + CGRect rect = view.frame; + rect.origin = CGPointMake(rect.origin.x, currentYOrigin + offset); + view.frame = rect; + currentYOrigin += rect.size.height + offset; + } +} + +// wrapper +-(void)resignFirstRespondersForSubviews +{ + [self resignFirstRespondersForView:self]; +} + +// helper +-(void)resignFirstRespondersForView:(UIView*)view +{ + for (UIView *subview in [view subviews]) + { + if ([subview isKindOfClass:[UITextField class]] || [subview isKindOfClass:[UITextView class]]) { + [(id)subview resignFirstResponder]; + } + [self resignFirstRespondersForView:subview]; + } +} + +@end diff --git a/MBAlertView/MBAlertView.h b/MBAlertView/MBAlertView.h new file mode 100644 index 0000000..5b7e031 --- /dev/null +++ b/MBAlertView/MBAlertView.h @@ -0,0 +1,81 @@ +// +// MBAlertView.h +// Notestand +// +// Created by M B. Bitar on 9/8/12. +// Copyright (c) 2012 progenius, inc. All rights reserved. +// + +// 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 +#import "MBAlertViewItem.h" + +// notifications called when an alert/hud appears/disappears +extern NSString *const MBAlertViewDidAppearNotification; +extern NSString *const MBAlertViewDidDismissNotification; + +// use these as needed +extern CGFloat MBAlertViewMaxHUDDisplayTime; +extern CGFloat MBAlertViewDefaultHUDHideDelay; + +@interface MBAlertView : UIViewController +// if yes, will wait until alert has disappeared before performing any button blocks +@property (nonatomic, assign) BOOL shouldPerformBlockAfterDismissal; + +// perform something after the alert dismisses +@property (nonatomic, copy) id uponDismissalBlock; + +// huds by default are put on super view controller. however sometimes a hud appears right before a modal disappears. in that case we'll add the hud to the window +@property (nonatomic, assign) BOOL addsToWindow; + +// offset for HUD icons, or image offset if supplied +@property (nonatomic, assign) CGSize iconOffset; + +// body is the main text of the alert +@property (nonatomic, copy) NSString *bodyText; +@property (nonatomic, copy) UIFont *bodyFont; + +// just set the imageView's image to activate +@property (nonatomic, strong) UIImageView *imageView; + +// if not assigned, will be full screen +@property (nonatomic, assign) CGSize size; + +// the opacity of the background +@property (nonatomic, assign) float backgroundAlpha; + +-(void)dismiss; +-(void)addToDisplayQueue; +-(void)addButtonWithText:(NSString*)text type:(MBAlertViewItemType)type block:(id)block; + +#pragma mark Class methods +// factory method ++(MBAlertView*)alertWithBody:(NSString*)body cancelTitle:(NSString*)cancelTitle cancelBlock:(id)cancelBlock; + +// yes if there is currently an alert or hud on screen ++(BOOL)alertIsVisible; + +// dismisses current hud in queue, whether or not its visible ++(void)dismissCurrentHUD; ++(void)dismissCurrentHUDAfterDelay:(float)delay; + +// a helper method that returns a size ++(CGSize)halfScreenSize; +@end diff --git a/MBAlertView/MBAlertView.m b/MBAlertView/MBAlertView.m new file mode 100644 index 0000000..ae2bee7 --- /dev/null +++ b/MBAlertView/MBAlertView.m @@ -0,0 +1,497 @@ +// +// MBAlertView.m +// Notestand +// +// Created by M B. Bitar on 9/8/12. +// Copyright (c) 2012 progenius, inc. All rights reserved. +// + +#import "MBAlertView.h" +#import "MBHUDView.h" +#import + +#import "MBAlertViewButton.h" +#import "MBSpinningCircle.h" +#import "MBCheckMarkView.h" + +#import "UIView+Animations.h" +#import "NSString+Trim.h" +#import "UIFont+Alert.h" + +#import "MBAlertViewSubclass.h" + +NSString *const MBAlertViewDidAppearNotification = @"MBAlertViewDidAppearNotification"; +NSString *const MBAlertViewDidDismissNotification = @"MBAlertViewDidDismissNotification"; + +CGFloat MBAlertViewMaxHUDDisplayTime = 10.0; +CGFloat MBAlertViewDefaultHUDHideDelay = 0.65; + +@interface MBAlertView () +@property (nonatomic, strong) NSMutableArray *items; +@end + +@implementation MBAlertView +{ + NSMutableArray *_buttons; + BOOL isPendingDismissal; + UIButton *_backgroundButton; + +} +// when dismiss is called, it takes about 0.5 seconds to complete animations. you want to remove it from the queue in the beginning, but want something to hold on to it. this is what retain queue is for + +static NSMutableArray *retainQueue; +static NSMutableArray *displayQueue; +static NSMutableArray *dismissQueue; +static MBAlertView *currentAlert; + ++(BOOL)alertIsVisible +{ + if(currentAlert) + return YES; + return NO; +} + ++(CGSize)halfScreenSize +{ + return CGSizeMake(280, 240); +} + ++(MBAlertView*)alertWithBody:(NSString*)body cancelTitle:(NSString*)cancelTitle cancelBlock:(id)cancelBlock +{ + MBAlertView *alert = [[MBAlertView alloc] init]; + alert.bodyText = body; + if(cancelTitle) + [alert addButtonWithText:cancelTitle type:MBAlertViewItemTypeDefault block:cancelBlock]; + return alert; +} + +-(void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +-(id)init +{ + if(self = [super init]) + { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(setRotation:)name:UIApplicationDidChangeStatusBarOrientationNotification object:nil]; + } + + return self; +} + +-(void)addToDisplayQueue +{ + if(!displayQueue) + displayQueue = [[NSMutableArray alloc] init]; + if(!dismissQueue) + dismissQueue = [[NSMutableArray alloc] init]; + + [displayQueue addObject:self]; + [dismissQueue addObject:self]; + + if(retainQueue.count == 0 && !currentAlert) + { + // show now + currentAlert = self; + [self addToWindow]; + if([self isMemberOfClass:[MBAlertView class]]) + { + [[NSNotificationCenter defaultCenter] postNotificationName:MBAlertViewDidAppearNotification object:nil]; + } + } +} + +-(void)addToWindow +{ + UIWindow * window = [UIApplication sharedApplication].keyWindow; + if (!window) + window = [[UIApplication sharedApplication].windows objectAtIndex:0]; + + if(self.addsToWindow) + [window addSubview:self.view]; + else [[[window subviews] objectAtIndex:0] addSubview:self.view]; + + [self performLayoutOfButtons]; + [self centerViews]; + + [window resignFirstRespondersForSubviews]; + + [self addBounceAnimationToLayer:self.view.layer]; + [displayQueue removeObject:self]; + +} + +// calling this removes the last queued alert, whether it has been displayed or not ++(void)dismissCurrentHUD +{ + if(dismissQueue.count > 0) + { + MBAlertView *current = [dismissQueue lastObject]; + [displayQueue removeObject:current]; + [current dismiss]; + [dismissQueue removeLastObject]; + } +} + ++(void)dismissCurrentHUDAfterDelay:(float)delay +{ + [[MBAlertView class] performSelector:@selector(dismissCurrentHUD) withObject:nil afterDelay:delay]; +} + +-(void)dismiss +{ + if(isPendingDismissal) + return; + isPendingDismissal = YES; + + if(!retainQueue) + retainQueue = [[NSMutableArray alloc] init]; + + [self.hideTimer invalidate]; + [retainQueue addObject:self]; + [dismissQueue removeObject:self]; + + currentAlert = nil; + [self addDismissAnimation]; +} + +-(void)removeAlertFromView +{ + id block = self.uponDismissalBlock; + if (![block isEqual:[NSNull null]] && block) + { + ((void (^)())block)(); + } + + [self.view removeFromSuperview]; + [retainQueue removeObject:self]; + + if(displayQueue.count > 0) + { + MBAlertView *alert = [displayQueue objectAtIndex:0]; + currentAlert = alert; + [currentAlert addToWindow]; + } +} + +-(void)didSelectButton:(MBAlertViewButton*)button +{ + if(button.tag >= _items.count) + return; + MBAlertViewItem *item = [_items objectAtIndex:button.tag]; + if(!item) + return; + + id block = item.block; + if (![block isEqual:[NSNull null]] && block) + { + if(self.shouldPerformBlockAfterDismissal && block) + self.uponDismissalBlock = block; + else ((void (^)())block)(); + [[NSNotificationCenter defaultCenter] postNotificationName:MBAlertViewDidDismissNotification object:nil]; + } + else + { + [[NSNotificationCenter defaultCenter] postNotificationName:MBAlertViewDidDismissNotification object:nil]; + } + + [self performSelector:@selector(dismiss) withObject:nil afterDelay:0.12]; +} + + +// if there is only one button on the alert, we're going to assume its just an OK option, so we'll let the user tap anywhere to dismiss the alert +-(void)didSelectBackgroundButton:(UIButton*)button +{ + if(_buttons.count == 1) + { + MBAlertViewButton *alertButton = [_buttons objectAtIndex:0]; + [self didSelectButton:alertButton]; + } +} + +-(NSMutableArray*)items +{ + if(_items) + return _items; + _items = [[NSMutableArray alloc] init]; + return _items; +} + +-(void)addButtonWithText:(NSString*)text type:(MBAlertViewItemType)type block:(id)block +{ + MBAlertViewItem *item = [[MBAlertViewItem alloc] initWithTitle:text type:type block:block]; + [self.items addObject:item]; +} + +-(int)defaultAutoResizingMask +{ + return UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin; +} + +#define kBodyFont [UIFont boldSystemFontOfSize:20] +#define kSpaceBetweenButtons 30 + +-(BOOL)isFullScreen +{ + return CGSizeEqualToSize(self.size, CGSizeZero); +} + +-(void)loadView +{ + CGRect bounds = [[UIScreen mainScreen] bounds]; + self.view = [[UIView alloc] initWithFrame:bounds]; + [self.view setBackgroundColor:[UIColor clearColor]]; + self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleTopMargin; + + BOOL isFullScreen = [self isFullScreen]; + if(isFullScreen) + { + _contentRect = CGRectMake(0, 0, bounds.size.width, bounds.size.height); + _backgroundButton = [[UIButton alloc] initWithFrame:CGRectMake(-100, -100, bounds.size.width + 200, bounds.size.height + 200)]; + self.size = _contentRect.size; + } + else + { + _backgroundButton = [[UIButton alloc] initWithFrame:CGRectMake(self.view.bounds.size.width/2.0 - self.size.width/2.0 , self.view.bounds.size.height/2.0 - self.size.height/2.0, self.size.width, self.size.height)]; + _backgroundButton.layer.cornerRadius = 8; + _contentRect = _backgroundButton.frame; + } + + [_backgroundButton setBackgroundColor:[UIColor blackColor]]; + _backgroundButton.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth; + _backgroundButton.alpha = _backgroundAlpha > 0 ? _backgroundAlpha : 0.85; + [_backgroundButton addTarget:self action:@selector(didSelectBackgroundButton:) forControlEvents:UIControlEventTouchUpInside]; + [self.view addSubview:_backgroundButton]; +} + +-(UIFont*)bodyFont +{ + if(_bodyFont) + return _bodyFont; + _bodyFont = [UIFont boldSystemFontThatFitsSize:[self labelConstraint] maxFontSize:22 minSize:20 text:self.bodyText]; + return _bodyFont; +} + +-(CGSize)labelConstraint +{ + return CGSizeMake(self.contentRect.size.width - 40, self.contentRect.size.height - 100); +} + +-(UIButton*)bodyLabelButton +{ + if(_bodyLabelButton) + return _bodyLabelButton; + + CGSize size = [_bodyText sizeWithFont:self.bodyFont constrainedToSize:[self labelConstraint]]; + NSString *txt = [_bodyText stringByTruncatingToSize:size withFont:self.bodyFont addQuotes:NO]; + _bodyLabelButton = [[UIButton alloc] initWithFrame:CGRectMake(_contentRect.origin.x + _contentRect.size.width/2.0 - size.width/2.0, _contentRect.origin.y + _contentRect.size.height/2.0 - size.height/2.0 - 8 + _imageView.frame.size.height, size.width, size.height)]; + _bodyLabelButton.autoresizingMask = [self defaultAutoResizingMask]; + [_bodyLabelButton addTarget:self action:@selector(didSelectBodyLabel:) forControlEvents:UIControlEventTouchUpInside]; + [_bodyLabelButton setTitle:_bodyText forState:UIControlStateNormal]; + + _bodyLabelButton.titleLabel.text = txt; + _bodyLabelButton.titleLabel.font = self.bodyFont; + _bodyLabelButton.titleLabel.numberOfLines = 0; + _bodyLabelButton.titleLabel.textAlignment = NSTextAlignmentCenter; + [self.view addSubview:_bodyLabelButton]; + return _bodyLabelButton; +} + +-(UIImageView*)imageView +{ + if(_imageView) + return _imageView; + _imageView = [[UIImageView alloc] init]; + return _imageView; +} + +-(void)layoutView +{ + if(_imageView) + { + [_imageView sizeToFit]; + CGRect rect = self.imageView.frame; + rect.origin = CGPointMake(self.contentRect.origin.x + (self.contentRect.size.width/2.0 - rect.size.width/2.0), 0); + _imageView.frame = rect; + [self.view addSubview:self.imageView]; + } + + UIColor *titleColor = [UIColor whiteColor]; + [self.bodyLabelButton setTitleColor:titleColor forState:UIControlStateNormal]; + + [_bodyLabelButton setBackgroundColor:[UIColor clearColor]]; + [self.view addSubview:_bodyLabelButton]; + _buttons = [[NSMutableArray alloc] init]; + + [self.items enumerateObjectsUsingBlock:^(MBAlertViewItem *item, NSUInteger index, BOOL *stop) + { + MBAlertViewButton *buttonLabel = [[MBAlertViewButton alloc] initWithTitle:item.title]; + [buttonLabel addTarget:self action:@selector(didSelectButton:) forControlEvents:UIControlEventTouchUpInside]; + [buttonLabel addTarget:self action:@selector(didHighlightButton:) forControlEvents:UIControlEventTouchDown]; + [buttonLabel addTarget:self action:@selector(didRemoveHighlightFromButton:) forControlEvents:UIControlEventTouchUpOutside | UIControlEventTouchDragExit | UIControlEventTouchCancel]; + buttonLabel.tag = index; + [_buttons addObject:buttonLabel]; + }]; + +} + +-(void)centerViews +{ + [_buttons enumerateObjectsUsingBlock:^(MBAlertViewButton *button, NSUInteger idx, BOOL *stop) + { + if(_imageView) + { + [_backgroundButton centerViewsVerticallyWithin:@[@{@"view" : _imageView, @"offset" : [NSNumber numberWithFloat:0]}, @{@"view" : self.bodyLabelButton, @"offset" : [NSNumber numberWithFloat:20]}, @{@"view" : button, @"offset" : [NSNumber numberWithFloat:20]}]]; + } + else + { + [_backgroundButton centerViewsVerticallyWithin:@[@{@"view" : self.bodyLabelButton, @"offset" : [NSNumber numberWithFloat:0]}, @{@"view" : button, @"offset" : [NSNumber numberWithFloat:20]}]]; + } + }]; +} + +// lays out button on rotation +-(void)layoutButtonsWrapper +{ + [UIView animateWithDuration:0.3 animations:^{ + [self performLayoutOfButtons]; + }]; + [self centerViews]; +} + +-(void)performLayoutOfButtons +{ + CGRect bounds = self.view.bounds; + float totalWidth = 0; + for(MBAlertViewButton *item in _buttons) { + CGSize size = item.frame.size; + totalWidth += size.width + kSpaceBetweenButtons; + } + + totalWidth -= kSpaceBetweenButtons; + + float xOrigOfFirstItem = bounds.size.width/2.0 - totalWidth/2.0; + __block float currentXOrigin = xOrigOfFirstItem; + + [self.items enumerateObjectsUsingBlock:^(MBAlertViewItem *item, NSUInteger index, BOOL *stop) + { + MBAlertViewButton *buttonLabel = [_buttons objectAtIndex:index]; + float origin = 0; + if(index == 0) + origin = currentXOrigin; + else origin = currentXOrigin + kSpaceBetweenButtons; + + currentXOrigin = origin + buttonLabel.bounds.size.width; + float yOrigin = _bodyLabelButton.frame.origin.y + _bodyLabelButton.frame.size.height ; + + CGRect rect = buttonLabel.frame; + rect.origin = CGPointMake(origin, yOrigin); + buttonLabel.frame = rect; + buttonLabel.alertButtonType = item.type; + + if(!buttonLabel.superview) + [self.view addSubview:buttonLabel]; + }]; +} + + +#define kDismissDuration 0.25 + +-(void)hideWithFade +{ + self.view.alpha = 0.0; + [self.view addFadingAnimationWithDuration:[self isMemberOfClass:[MBHUDView class]] ? 0.25 : 0.20]; + [self performSelector:@selector(removeAlertFromView) withObject:nil afterDelay:kDismissDuration]; +} + +-(void)didRemoveHighlightFromButton:(MBAlertViewButton*)button +{ + [button.layer removeAllAnimations]; +} + +-(void)addDismissAnimation +{ + NSArray *frameValues = @[[NSValue valueWithCATransform3D:CATransform3DMakeScale(1.0, 1.0, 1)], + [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.95, 0.95, 1)], + [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.15, 1.15, 1)], + [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.01, 0.01, 1.0)]]; + + NSArray *frameTimes = @[@(0.0), @(0.1), @(0.5), @(1.0)]; + CAKeyframeAnimation *animation = [self animationWithValues:frameValues times:frameTimes duration:kDismissDuration]; + animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; + + [self.view.layer addAnimation:animation forKey:@"popup"]; + + [self performSelector:@selector(hideWithFade) withObject:nil afterDelay:0.15]; +} + +-(void)addBounceAnimationToLayer:(CALayer*)layer +{ + NSArray *frameValues = @[[NSValue valueWithCATransform3D:CATransform3DMakeScale(0.1, 0.1, 1)], + [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.35, 1.35, 1)], + [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.8, 0.8, 1)], + [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.0, 1.0, 1)]]; + NSArray *frameTimes = @[@(0.0), @(0.5), @(0.9), @(1.0)]; + [layer addAnimation:[self animationWithValues:frameValues times:frameTimes duration:0.4] forKey:@"popup"]; +} + +-(void)didSelectBodyLabel:(UIButton*)bodyLabelButton +{ + NSArray *frameValues = @[[NSValue valueWithCATransform3D:CATransform3DMakeScale(1.0, 1.0, 1)], + [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.08, 1.08, 1)], + [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.95, 0.95, 1)], + [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.02, 1.02, 1)], + [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.0, 1.0, 1)]]; + NSArray *frameTimes = @[@(0.0), @(0.1), @(0.7), @(0.9), @(1.0)]; + [bodyLabelButton.layer addAnimation:[self animationWithValues:frameValues times:frameTimes duration:0.3] forKey:@"popup"]; +} + +-(void)didHighlightButton:(MBAlertViewButton*)button +{ + NSArray *frameValues = @[[NSValue valueWithCATransform3D:CATransform3DMakeScale(1.0, 1.0, 1)], + [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.25, 1.25, 1.0)]]; + NSArray *frameTimes = @[@(0.0), @(0.5)]; + [button.layer addAnimation:[self animationWithValues:frameValues times:frameTimes duration:0.25] forKey:@"popup"]; +} + +-(CAKeyframeAnimation*)animationWithValues:(NSArray*)values times:(NSArray*)times duration:(CGFloat)duration +{ + CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"]; + animation.values = values; + animation.keyTimes = times; + animation.fillMode = kCAFillModeForwards; + animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; + animation.removedOnCompletion = NO; + animation.duration = duration; + return animation; +} + +- (void)setRotation:(NSNotification*)notification +{ + [self performSelector:@selector(layoutButtonsWrapper) withObject:nil afterDelay:0.01]; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + [self layoutView]; +} + +- (void)viewDidUnload +{ + [super viewDidUnload]; + // Release any retained subviews of the main view. +} + +-(BOOL)shouldAutorotate +{ + return YES; +} + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +{ + return (interfaceOrientation == UIInterfaceOrientationPortrait); +} + +@end \ No newline at end of file diff --git a/MBAlertView/MBHUDView.h b/MBAlertView/MBHUDView.h new file mode 100644 index 0000000..d5fbf8a --- /dev/null +++ b/MBAlertView/MBHUDView.h @@ -0,0 +1,30 @@ +// +// MBHUDView.h +// Notestand +// +// Created by M B. Bitar on 9/30/12. +// Copyright (c) 2012 progenius, inc. All rights reserved. +// + +#import "MBAlertView.h" + +typedef enum { + MBAlertViewHUDTypeDefault, + MBAlertViewHUDTypeActivityIndicator, + MBAlertViewHUDTypeCheckmark, + MBAlertViewHUDTypeExclamationMark, + MBAlertViewHUDTypeLabelIcon, + MBAlertViewHUDTypeImage, + MBAlertViewHUDTypeImagePositive +} MBAlertViewHUDType; + +@interface MBHUDView : MBAlertView +@property (nonatomic, assign) MBAlertViewHUDType hudType; +@property (nonatomic, assign) float hudHideDelay; +@property (nonatomic, assign) CGSize bodyOffset; +@property (nonatomic, strong) UILabel *iconLabel; +@property (nonatomic, copy) UIColor *backgroundColor; + +// if you want to customize the HUD before showing, set show to NO, else setting to YES displays it right away ++(MBHUDView*)hudWithBody:(NSString*)body type:(MBAlertViewHUDType)type hidesAfter:(float)delay show:(BOOL)show; +@end diff --git a/MBAlertView/MBHUDView.m b/MBAlertView/MBHUDView.m new file mode 100644 index 0000000..fe0062a --- /dev/null +++ b/MBAlertView/MBHUDView.m @@ -0,0 +1,233 @@ +// +// MBHUDView.m +// Notestand +// +// Created by M B. Bitar on 9/30/12. +// Copyright (c) 2012 progenius, inc. All rights reserved. +// + +#import "MBHUDView.h" +#import "MBSpinningCircle.h" +#import +#import "MBCheckmarkView.h" +#import "UIView+Animations.h" +#import "MBAlertViewSubclass.h" + +@interface MBHUDView () +{ + UIButton *_backgroundButton; + MBCheckMarkView *_checkMark; + MBSpinningCircle *_activityIndicator; +} +@end + +@implementation MBHUDView +@synthesize bodyLabelButton = _bodyLabelButton, imageView = _imageView, bodyFont = _bodyFont; + ++(MBHUDView*)hudWithBody:(NSString*)body type:(MBAlertViewHUDType)type hidesAfter:(float)delay show:(BOOL)show +{ + MBHUDView *alert = [[MBHUDView alloc] init]; + alert.bodyText = body; + alert.hudType = type; + alert.hudHideDelay = delay; + alert.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.9]; + + if(type == MBAlertViewHUDTypeExclamationMark) + { + alert.hudType = MBAlertViewHUDTypeLabelIcon; + alert.iconLabel.textColor = [UIColor whiteColor]; + alert.iconLabel.text = @"!"; + alert.iconLabel.font = [UIFont boldSystemFontOfSize:60]; + alert.bodyOffset = CGSizeMake(0, 0); + } + + if(show) + [alert addToDisplayQueue]; + return alert; +} + +-(CGSize)hudSize +{ + if(CGSizeEqualToSize(self.size, CGSizeZero)) + return CGSizeMake(125, 125); + return self.size; +} + +-(UILabel*)iconLabel +{ + if(_iconLabel) + return _iconLabel; + _iconLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 50, 50)]; + _iconLabel.backgroundColor = [UIColor clearColor]; + _iconLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; + return _iconLabel; +} + +-(UIFont*)bodyFont +{ + if(_bodyFont) + return _bodyFont; + float size = 0; + [self.bodyText sizeWithFont:[UIFont boldSystemFontOfSize:26] minFontSize:6 actualFontSize:&size forWidth:self.contentRect.size.width / 1.3 lineBreakMode:NSLineBreakByTruncatingTail]; + _bodyFont = [UIFont boldSystemFontOfSize:size]; + return _bodyFont; +} + +-(UIButton*)bodyLabelButton +{ + if(_bodyLabelButton) + return _bodyLabelButton; + + UIFont *font = self.bodyFont; + CGRect bounds = self.contentRect; + CGSize size = [self.bodyText sizeWithFont:font]; + _bodyLabelButton = [[UIButton alloc] initWithFrame:CGRectMake(bounds.origin.x + bounds.size.width/2.0 - size.width/2.0, bounds.size.height/2.0 - size.height/2.0 - 8, size.width, size.height)]; + + [_bodyLabelButton setTitle:self.bodyText forState:UIControlStateNormal]; + _bodyLabelButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; + + _bodyLabelButton.titleLabel.text = self.bodyText; + _bodyLabelButton.titleLabel.font = font; + _bodyLabelButton.titleLabel.numberOfLines = 0; + + _bodyLabelButton.titleLabel.textAlignment = NSTextAlignmentCenter; + [self.view addSubview:_bodyLabelButton]; + return _bodyLabelButton; +} + + +-(UIImageView*)imageView +{ + if(_imageView) + return _imageView; + _imageView = [[UIImageView alloc] init]; + _imageView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; + return _imageView; +} + +-(void)loadView +{ + CGRect bounds = [[UIScreen mainScreen] bounds]; + self.view = [[UIView alloc] initWithFrame:bounds]; + [self.view setBackgroundColor:[UIColor clearColor]]; + self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleTopMargin; + + CGRect rect; + rect.size = self.hudSize; + rect.origin = CGPointMake(self.view.bounds.size.width/2.0 - rect.size.width/2.0, self.view.bounds.size.height/2.0 - rect.size.height/2.0); + self.contentRect = rect; + + _backgroundButton = [[UIButton alloc] initWithFrame:self.contentRect]; + [_backgroundButton setBackgroundColor:self.backgroundColor]; + _backgroundButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleTopMargin; + _backgroundButton.alpha = 0.85; + [_backgroundButton addTarget:self action:@selector(didSelectBackgroundButton:) forControlEvents:UIControlEventTouchUpInside]; + [self.view addSubview:_backgroundButton]; + + _backgroundButton.layer.cornerRadius = 8; +} + +-(void)addToWindow +{ + [super addToWindow]; + if(self.hudHideDelay > 0) + self.hideTimer = [NSTimer scheduledTimerWithTimeInterval:self.hudHideDelay target:self selector:@selector(dismiss) userInfo:nil repeats:NO]; +} + +-(void)layoutView +{ + CGRect bodyRect = self.bodyLabelButton.frame; + + if(_imageView) + { + [_imageView sizeToFit]; + CGRect rect = self.imageView.frame; + rect.origin = CGPointMake(self.contentRect.origin.x + (self.contentRect.size.width/2.0 - rect.size.width/2.0), 0); + self.imageView.frame = rect; + [self.view addSubview:self.imageView]; + } + + else if(_hudType == MBAlertViewHUDTypeActivityIndicator) + { + _activityIndicator = [MBSpinningCircle circleWithSize:NSSpinningCircleSizeLarge color:[UIColor colorWithRed:50.0/255.0 green:155.0/255.0 blue:255.0/255.0 alpha:1.0]]; + CGRect circleRect = _activityIndicator.frame; + circleRect.origin = CGPointMake(self.view.bounds.size.width/2.0 - circleRect.size.width/2.0, -5); + _activityIndicator.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin; + _activityIndicator.frame = circleRect; + _activityIndicator.circleSize = NSSpinningCircleSizeLarge; + _activityIndicator.hasGlow = YES; + _activityIndicator.isAnimating = YES; + _activityIndicator.speed = 0.55; + [self.view addSubview:_activityIndicator]; + } + + else if(_hudType == MBAlertViewHUDTypeCheckmark) + { + _checkMark = [MBCheckMarkView checkMarkWithSize:MBCheckmarkSizeLarge color:[UIColor whiteColor]]; + _checkMark.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; + CGRect rect = _checkMark.frame; + rect.origin = CGPointMake(self.view.bounds.size.width/2.0 - rect.size.width/2.0, 50); + _checkMark.frame = rect; + [self.view addSubview:_checkMark]; + + float height = _backgroundButton.frame.size.height; + float totalHeight = _checkMark.frame.size.height + _bodyLabelButton.frame.size.height; + rect.origin = CGPointMake(rect.origin.x, self.contentRect.origin.y + (height/2.0 - totalHeight/2.0)); + _checkMark.frame = rect; + + rect = _bodyLabelButton.frame; + rect.origin = CGPointMake(rect.origin.x, _checkMark.frame.origin.y + _checkMark.frame.size.height); + _bodyLabelButton.frame = rect; + } + else if(_hudType == MBAlertViewHUDTypeLabelIcon || self.iconLabel.text) + { + [self.iconLabel sizeToFit]; + CGRect rect = self.iconLabel.frame; + rect.origin = CGPointMake(self.view.bounds.size.width/2.0 - rect.size.width/2.0 + self.iconOffset.width, bodyRect.origin.y - rect.size.height - 30 + self.iconOffset.height); + self.iconLabel.frame = rect; + [self.view addSubview:self.iconLabel]; + + } + + + CALayer *layer = _bodyLabelButton.layer; + layer.shadowColor = [UIColor whiteColor].CGColor; + layer.shadowOffset = CGSizeMake(0, 0); + layer.shadowOpacity = 0.1; + layer.shadowPath = [UIBezierPath bezierPathWithRect:_bodyLabelButton.bounds].CGPath; + layer.shadowRadius = 10.0; + +} + +-(void)centerViews +{ + if(_imageView) + { + [_backgroundButton centerViewsVerticallyWithin:@[@{@"view" : self.imageView, @"offset" : [NSNumber numberWithFloat:self.iconOffset.height]}, @{@"view" : self.bodyLabelButton, @"offset" : [NSNumber numberWithFloat:10 + _bodyOffset.height]}]]; + } + else if(_hudType == MBAlertViewHUDTypeActivityIndicator) + { + [_backgroundButton centerViewsVerticallyWithin:@[@{@"view" : _activityIndicator, @"offset" : [NSNumber numberWithFloat:self.iconOffset.height]}, @{@"view" : self.bodyLabelButton, @"offset" : [NSNumber numberWithFloat:0]}]]; + } + else if(_hudType == MBAlertViewHUDTypeCheckmark) + { + [_backgroundButton centerViewsVerticallyWithin:@[@{@"view" : _checkMark, @"offset" : [NSNumber numberWithFloat:self.iconOffset.height]}, @{@"view" : self.bodyLabelButton, @"offset" : [NSNumber numberWithFloat:10]}]]; + } + else if(_hudType == MBAlertViewHUDTypeLabelIcon || self.iconLabel.text) + { + [_backgroundButton centerViewsVerticallyWithin:@[@{@"view" : self.iconLabel, @"offset" : [NSNumber numberWithFloat:self.iconOffset.height]}, @{@"view" : self.bodyLabelButton, @"offset" : [NSNumber numberWithFloat:self.bodyOffset.height]}]]; + } + else + { + [_backgroundButton centerViewsVerticallyWithin:@[@{@"view" : _bodyLabelButton, @"offset" : [NSNumber numberWithFloat:self.bodyOffset.height]}]]; + } + +} + +- (void)viewDidLoad +{ + [self layoutView]; + // Do any additional setup after loading the view. +} + +@end diff --git a/MBAlertView/Protected/MBAlertViewItem.h b/MBAlertView/Protected/MBAlertViewItem.h new file mode 100644 index 0000000..cce6327 --- /dev/null +++ b/MBAlertView/Protected/MBAlertViewItem.h @@ -0,0 +1,22 @@ +// +// MBAlertViewItem.h +// AlertsDemo +// +// Created by M B. Bitar on 1/15/13. +// Copyright (c) 2013 progenius, inc. All rights reserved. +// + +#import + +typedef enum { + MBAlertViewItemTypeDefault, + MBAlertViewItemTypeDestructive, + MBAlertViewItemTypePositive, +}MBAlertViewItemType; + +@interface MBAlertViewItem : NSObject +@property (nonatomic, strong) id block; +@property (nonatomic, copy) NSString *title; +@property (nonatomic, assign) MBAlertViewItemType type; +-(id)initWithTitle:(NSString*)text type:(MBAlertViewItemType)type block:(id)block; +@end diff --git a/MBAlertView/Protected/MBAlertViewItem.m b/MBAlertView/Protected/MBAlertViewItem.m new file mode 100644 index 0000000..0a6ca5f --- /dev/null +++ b/MBAlertView/Protected/MBAlertViewItem.m @@ -0,0 +1,23 @@ +// +// MBAlertViewItem.m +// AlertsDemo +// +// Created by M B. Bitar on 1/15/13. +// Copyright (c) 2013 progenius, inc. All rights reserved. +// + +#import "MBAlertViewItem.h" + +@implementation MBAlertViewItem + +-(id)initWithTitle:(NSString*)text type:(MBAlertViewItemType)type block:(id)block +{ + if(self = [super init]) { + _title = text; + _type = type; + _block = block; + } + return self; +} + +@end diff --git a/MBAlertView/Protected/MBAlertViewSubclass.h b/MBAlertView/Protected/MBAlertViewSubclass.h new file mode 100644 index 0000000..01589c5 --- /dev/null +++ b/MBAlertView/Protected/MBAlertViewSubclass.h @@ -0,0 +1,16 @@ +// +// MBAlertViewSubclass.h +// AlertsDemo +// +// Created by M B. Bitar on 1/15/13. +// Copyright (c) 2013 progenius, inc. All rights reserved. +// + +#import "MBAlertView.h" + +@interface MBAlertView () +@property (nonatomic, strong) UIButton *bodyLabelButton; +@property (nonatomic, assign) CGRect contentRect; +@property (nonatomic, strong) NSTimer *hideTimer; +-(void)addToWindow; +@end diff --git a/MBAlertView/Views/AlertViewUI.h b/MBAlertView/Views/AlertViewUI.h new file mode 100644 index 0000000..890f142 --- /dev/null +++ b/MBAlertView/Views/AlertViewUI.h @@ -0,0 +1,14 @@ +// +// AlertViewUI.h +// TwoTask +// +// Created by M B. Bitar on 12/25/12. +// Copyright (c) 2012 progenius, inc. All rights reserved. +// + +#ifndef TwoTask_AlertViewUI_h +#define TwoTask_AlertViewUI_h + +#define BLUE_GLOW_COLOR [UIColor colorWithRed:50.0/255.0 green:155.0/255.0 blue:255.0/255.0 alpha:1.0] + +#endif diff --git a/MBAlertView/Views/MBAlertViewButton.h b/MBAlertView/Views/MBAlertViewButton.h new file mode 100644 index 0000000..c061a33 --- /dev/null +++ b/MBAlertView/Views/MBAlertViewButton.h @@ -0,0 +1,16 @@ +// +// MBAlertViewButton.h +// Notestand +// +// Created by M B. Bitar on 9/8/12. +// Copyright (c) 2012 progenius, inc. All rights reserved. +// + +#import +#import "MBAlertView.h" + +@interface MBAlertViewButton : UIButton +@property (nonatomic, copy) NSString *title; +@property (nonatomic, assign) MBAlertViewItemType alertButtonType; +- (id)initWithTitle:(NSString*)title; +@end diff --git a/MBAlertView/Views/MBAlertViewButton.m b/MBAlertView/Views/MBAlertViewButton.m new file mode 100644 index 0000000..7511d46 --- /dev/null +++ b/MBAlertView/Views/MBAlertViewButton.m @@ -0,0 +1,70 @@ +// +// MBAlertViewButton.m +// Notestand +// +// Created by M B. Bitar on 9/8/12. +// Copyright (c) 2012 progenius, inc. All rights reserved. +// + +#import "MBAlertViewButton.h" +#import +#import "AlertViewUI.h" + +@implementation MBAlertViewButton + +#define kShadowSize 8 +#define kButtonFont [UIFont boldSystemFontOfSize:18] +- (id)initWithTitle:(NSString*)title +{ + self = [super initWithFrame:CGRectMake(0, 0, 100, 40)]; + if (self) { + [self setBackgroundColor:[UIColor clearColor]]; + _title = title; + } + return self; +} + +-(UIColor*)colorForButtonStyle +{ + if(_alertButtonType == MBAlertViewItemTypeDefault) { + return [UIColor whiteColor]; + } else if(_alertButtonType == MBAlertViewItemTypeDestructive) { + return [UIColor redColor]; + } else if(_alertButtonType == MBAlertViewItemTypePositive) { + return BLUE_GLOW_COLOR; + } + + return [UIColor whiteColor]; +} + +-(UIColor*)textColor +{ + if(_alertButtonType == MBAlertViewItemTypeDefault) { + return [UIColor colorWithWhite:0.2 alpha:1.0]; + } else if(_alertButtonType == MBAlertViewItemTypeDestructive) { + return [UIColor whiteColor]; + } else if(_alertButtonType == MBAlertViewItemTypePositive) { + return [UIColor whiteColor]; + } + + return [UIColor whiteColor]; +} + +- (void)drawRect:(CGRect)rect +{ + UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:2.0]; + [[self colorForButtonStyle] setFill]; + [path fill]; + + float actualSize = 0; + [_title sizeWithFont:kButtonFont minFontSize:8 actualFontSize:&actualSize forWidth:self.bounds.size.width - 20 lineBreakMode:NSLineBreakByClipping]; + CGSize otherSize = [_title sizeWithFont:[UIFont boldSystemFontOfSize:actualSize]]; + + CGPoint origin = CGPointMake(self.bounds.size.width/2.0 - otherSize.width/2.0, self.bounds.size.height/2.0 - otherSize.height/2.0); + CGRect frame = CGRectMake(origin.x, origin.y, otherSize.width, otherSize.height); + + [[self textColor] set]; + [_title drawInRect:frame withFont:[UIFont boldSystemFontOfSize:actualSize] lineBreakMode:NSLineBreakByClipping]; +} + +@end diff --git a/MBAlertView/Views/MBCheckMarkView.h b/MBAlertView/Views/MBCheckMarkView.h new file mode 100644 index 0000000..aa274e0 --- /dev/null +++ b/MBAlertView/Views/MBCheckMarkView.h @@ -0,0 +1,23 @@ +// +// NSCheckmarkView.h +// Notestand +// +// Created by M B. Bitar on 9/24/12. +// Copyright (c) 2012 progenius, inc. All rights reserved. +// + +#import + +typedef enum { + MBCheckmarkSizeVerySmall, + MBCheckmarkSizeSmall, + MBCheckmarkSizeMedium, + MBCheckmarkSizeLarge +}MBCheckmarkSize; + +@interface MBCheckMarkView : UIView +@property (nonatomic, strong) UIColor *color; +@property (nonatomic, assign) MBCheckmarkSize size; + ++(MBCheckMarkView*)checkMarkWithSize:(MBCheckmarkSize)size color:(UIColor*)color; +@end diff --git a/MBAlertView/Views/MBCheckMarkView.m b/MBAlertView/Views/MBCheckMarkView.m new file mode 100644 index 0000000..9892068 --- /dev/null +++ b/MBAlertView/Views/MBCheckMarkView.m @@ -0,0 +1,104 @@ +// +// NSCheckmarkView.m +// Notestand +// +// Created by M B. Bitar on 9/24/12. +// Copyright (c) 2012 progenius, inc. All rights reserved. +// + +#import "MBCheckMarkView.h" +#import + +static CGFloat largeSize = 50; +static CGFloat mediumSize = 30; +static CGFloat smallSize = 14; +static CGFloat xSmallSize = 8; + +@implementation MBCheckMarkView + ++(MBCheckMarkView*)checkMarkWithSize:(MBCheckmarkSize)size color:(UIColor*)color +{ + CGSize xySize; + switch (size) { + case MBCheckmarkSizeLarge: + xySize = CGSizeMake(largeSize, largeSize); + break; + case MBCheckmarkSizeMedium: + xySize = CGSizeMake(mediumSize, mediumSize); + break; + case MBCheckmarkSizeSmall: + xySize = CGSizeMake(smallSize, smallSize); + break; + case MBCheckmarkSizeVerySmall: + xySize = CGSizeMake(xSmallSize, xSmallSize); + break; + } + + CGRect rect = CGRectMake(0, 0, xySize.width, xySize.height); + MBCheckMarkView *checkMark = [[MBCheckMarkView alloc] initWithFrame:rect]; + checkMark.size = size; + checkMark.opaque = NO; + checkMark.color = color; + return checkMark; +} + +-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event +{ + return NO; +} + + +UIBezierPath *CheckMarkPath(CGRect frame) +{ + float p = CGRectGetHeight(frame) / 90; + UIBezierPath* bezierPath = [UIBezierPath bezierPath]; + [bezierPath moveToPoint: CGPointMake(0*p, 42*p)]; + [bezierPath addLineToPoint: CGPointMake(16*p, 26*p)]; + [bezierPath addLineToPoint: CGPointMake(32*p, 42*p)]; + [bezierPath addLineToPoint: CGPointMake(74*p, 0*p)]; + [bezierPath addLineToPoint: CGPointMake(90*p, 16*p)]; + [bezierPath addLineToPoint: CGPointMake(32*p, 74*p)]; + [bezierPath addLineToPoint: CGPointMake(0*p, 42*p)]; + [bezierPath closePath]; + return bezierPath; +} + +-(void)drawLarge +{ + UIBezierPath* bezierPath = CheckMarkPath(CGRectMake(0, 0, 0, largeSize)); + [bezierPath fill]; +} + +-(void)drawMedium +{ + UIBezierPath* bezierPath = CheckMarkPath(CGRectMake(0, 0, 0, mediumSize)); + [bezierPath fill]; +} + +-(void)drawSmall +{ + UIBezierPath* bezierPath = CheckMarkPath(CGRectMake(0, 0, 0, smallSize)); + [bezierPath fill]; +} + +-(void)drawVerySmall +{ + UIBezierPath* bezierPath = CheckMarkPath(CGRectMake(0, 0, 0, xSmallSize)); + [bezierPath fill]; +} + +- (void)drawRect:(CGRect)rect +{ + [_color setFill]; + if(_size == MBCheckmarkSizeVerySmall) + [self drawVerySmall]; + else if(_size == MBCheckmarkSizeSmall) + [self drawSmall]; + else if(_size == MBCheckmarkSizeMedium) + [self drawMedium]; + else if(_size == MBCheckmarkSizeLarge) + [self drawLarge]; +} + + +@end diff --git a/MBAlertView/Views/MBSpinningCircle.h b/MBAlertView/Views/MBSpinningCircle.h new file mode 100644 index 0000000..edf41b6 --- /dev/null +++ b/MBAlertView/Views/MBSpinningCircle.h @@ -0,0 +1,27 @@ +// +// NSSpinningCircle.h +// Notestand +// +// Created by M B. Bitar on 9/11/12. +// Copyright (c) 2012 progenius, inc. All rights reserved. +// + +#import + +typedef enum { + NSSpinningCircleSizeDefault, + NSSpinningCircleSizeLarge, + NSSpinningCircleSizeSmall +}NSSpinningCircleSize; + +@interface MBSpinningCircle : UIView + +@property (nonatomic, assign) BOOL isAnimating; +@property (nonatomic, strong) UIColor *color; +@property (nonatomic, assign) BOOL hasGlow; +@property (nonatomic, assign) float speed; +@property (nonatomic, assign) NSSpinningCircleSize circleSize; + ++(MBSpinningCircle*)circleWithSize:(NSSpinningCircleSize)size color:(UIColor*)color; + +@end diff --git a/MBAlertView/Views/MBSpinningCircle.m b/MBAlertView/Views/MBSpinningCircle.m new file mode 100644 index 0000000..de9edf8 --- /dev/null +++ b/MBAlertView/Views/MBSpinningCircle.m @@ -0,0 +1,145 @@ +// +// NSSpinningCircle.m +// Notestand +// +// Created by M B. Bitar on 9/11/12. +// Copyright (c) 2012 progenius, inc. All rights reserved. +// + +#import "MBSpinningCircle.h" +#import + +@implementation MBSpinningCircle +{ + float progress; +} + ++(MBSpinningCircle*)circleWithSize:(NSSpinningCircleSize)size color:(UIColor*)color +{ + float width; + switch (size) + { + case NSSpinningCircleSizeDefault: + width = 40; + break; + case NSSpinningCircleSizeLarge: + width = 50; + break; + case NSSpinningCircleSizeSmall: + width = 10; + break; + } + + MBSpinningCircle *circle = [[MBSpinningCircle alloc] initWithFrame:CGRectMake(0, 0, width, width)]; + circle.color = color; + return circle; +} + +- (id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) + { + self.opaque = NO; + self.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin; + } + return self; +} + +-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { + for (UIView *view in self.subviews) + { + if ([view pointInside:[self convertPoint:point toView:view] withEvent:event]) + return YES; + } + return NO; +} + +-(void)setIsAnimating:(BOOL)animating +{ + _isAnimating = animating; + if(animating) + { + [UIView animateWithDuration:0.9 animations:^{ self.alpha = 1.0; }]; + [self addRotationAnimation]; + } + else + { + [self hide]; + } +} + +-(void)hide +{ + [UIView animateWithDuration:0.45 animations:^{ + self.alpha = 0.0; + } completion:^(BOOL fin) { + [self.layer removeAllAnimations]; + }]; +} + +-(CGGradientRef)gradient +{ + + UIColor *sideColor = [UIColor redColor]; + UIColor *midColor = [UIColor lightGrayColor]; + NSArray* gradientColors = @[(id)sideColor.CGColor, + (id)midColor.CGColor, + (id)sideColor.CGColor]; + CGFloat gradientLocations[] = {0, 0.5, 1}; + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + return CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)gradientColors, gradientLocations); +} + +-(void)drawAnnular +{ + progress += 0.05; + if(progress > M_PI) progress = 0; + CGFloat lineWidth = 3.25f; + if(_circleSize == NSSpinningCircleSizeDefault) + lineWidth = 2.0f; + UIBezierPath *processBackgroundPath = [UIBezierPath bezierPath]; + processBackgroundPath.lineWidth = lineWidth; + processBackgroundPath.lineCapStyle = kCGLineCapRound; + + CGPoint center = CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2); + CGFloat radius = (self.bounds.size.width - 16 - lineWidth)/2; + CGFloat startAngle = - ((float)M_PI / 2 - progress*2); + + [[UIColor colorWithRed:1 green:1 blue:1 alpha:0.1] set]; + + UIBezierPath *processPath = [UIBezierPath bezierPath]; + processPath.lineCapStyle = kCGLineCapSquare; + processPath.lineWidth = lineWidth; + CGFloat endAngle = ((float)M_PI + startAngle); + [processPath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES]; + + CGContextRef context = UIGraphicsGetCurrentContext(); + CGContextSaveGState(context); + if(_hasGlow) + CGContextSetShadowWithColor(UIGraphicsGetCurrentContext(), CGSizeMake(0, 0), 6, _color.CGColor); + [_color set]; + [processPath stroke]; + CGContextRestoreGState(context); + + if(_isAnimating) + [self addRotationAnimation]; +} + +-(void)addRotationAnimation +{ + CABasicAnimation *rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; + rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI]; + rotationAnimation.duration = _speed; + rotationAnimation.repeatCount = MAXFLOAT; + rotationAnimation.cumulative = YES; + [self.layer addAnimation:rotationAnimation forKey:@"rotationAnimation1"]; +} + +-(void)drawRect:(CGRect)rect +{ + [self drawAnnular]; +} + + +@end diff --git a/README b/README deleted file mode 100644 index e69de29..0000000 diff --git a/README.md b/README.md index dc4f924..2155c0f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,33 @@ ## MBAlertView =================== -MBAlertView is a fun and simple block-based alert and HUD library for iOS. \ No newline at end of file +MBAlertView is a fun and simple block-based alert and HUD library for iOS. + +### Features +
    +
  • Nested alerts and HUDs
  • +
  • Block based
  • +
  • Images
  • +
  • Nice animations
  • +
  • Doesn't use any PNG files. Everything is drawn with code.
  • +
+ +## Usage + +There are two factory methods to get you started: + +### Alerts + +``` objective-c +MBAlertView *alert = [MBAlertView alertWithBody:@"Are you sure you want to delete this note? You cannot undo this." cancelTitle:@"Cancel" cancelBlock:nil]; + [alert addButtonWithText:@"Delete" type:MBAlertViewItemTypeDestructive block:^{ // delete }]; +[alert addToDisplayQueue]; +``` + +### HUDs +``` objective-c +[MBHUDView hudWithBody:@"Wait." type:MBAlertViewHUDTypeActivityIndicator hidesAfter:4.0 show:YES]; +``` + +## License +MBAlertView is available under the MIT license. \ No newline at end of file