diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c29c702 --- /dev/null +++ b/.gitignore @@ -0,0 +1,31 @@ +# Xcode +# +build/ +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata +*.xccheckout +*.moved-aside +DerivedData +*.hmap +*.ipa +*.xcuserstate + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control +# +Pods/ + +### +._* + +.hgignore diff --git a/Demo/LGAlertViewDemo.xcodeproj/project.pbxproj b/Demo/LGAlertViewDemo.xcodeproj/project.pbxproj new file mode 100644 index 0000000..f15634b --- /dev/null +++ b/Demo/LGAlertViewDemo.xcodeproj/project.pbxproj @@ -0,0 +1,344 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 4A3B78661AD2A28200DB8642 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 4A3B78651AD2A28200DB8642 /* main.m */; }; + 4A3B78691AD2A28200DB8642 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4A3B78681AD2A28200DB8642 /* AppDelegate.m */; }; + 4A3B78711AD2A28300DB8642 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4A3B78701AD2A28300DB8642 /* Images.xcassets */; }; + 4A3B788B1AD2A93D00DB8642 /* TableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4A3B788A1AD2A93D00DB8642 /* TableViewController.m */; }; + 4A3B788E1AD2B29F00DB8642 /* NavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4A3B788D1AD2B29F00DB8642 /* NavigationController.m */; }; + 92E830BBF9A0E9733AA1BC7E /* libPods-LGAlertViewDemo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 623B5C352E52555F577FBF72 /* libPods-LGAlertViewDemo.a */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 4A3B78601AD2A28200DB8642 /* LGAlertViewDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LGAlertViewDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4A3B78641AD2A28200DB8642 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 4A3B78651AD2A28200DB8642 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 4A3B78671AD2A28200DB8642 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 4A3B78681AD2A28200DB8642 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 4A3B78701AD2A28300DB8642 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 4A3B78891AD2A93D00DB8642 /* TableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TableViewController.h; sourceTree = ""; }; + 4A3B788A1AD2A93D00DB8642 /* TableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TableViewController.m; sourceTree = ""; }; + 4A3B788C1AD2B29F00DB8642 /* NavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NavigationController.h; sourceTree = ""; }; + 4A3B788D1AD2B29F00DB8642 /* NavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NavigationController.m; sourceTree = ""; }; + 623B5C352E52555F577FBF72 /* libPods-LGAlertViewDemo.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-LGAlertViewDemo.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 637E642E08EC55B4AF82AB1E /* Pods-LGAlertViewDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LGAlertViewDemo.debug.xcconfig"; path = "Pods/Target Support Files/Pods-LGAlertViewDemo/Pods-LGAlertViewDemo.debug.xcconfig"; sourceTree = ""; }; + 75F4867B7B8225C0410A3B3A /* Pods-LGAlertViewDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LGAlertViewDemo.release.xcconfig"; path = "Pods/Target Support Files/Pods-LGAlertViewDemo/Pods-LGAlertViewDemo.release.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 4A3B785D1AD2A28200DB8642 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 92E830BBF9A0E9733AA1BC7E /* libPods-LGAlertViewDemo.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 4A3B78571AD2A28200DB8642 = { + isa = PBXGroup; + children = ( + 4A3B78621AD2A28200DB8642 /* LGAlertViewDemo */, + 4A3B78611AD2A28200DB8642 /* Products */, + A97F0E110AD1D1F440968EB0 /* Pods */, + 72646D99469FDAC04E185CBA /* Frameworks */, + ); + sourceTree = ""; + }; + 4A3B78611AD2A28200DB8642 /* Products */ = { + isa = PBXGroup; + children = ( + 4A3B78601AD2A28200DB8642 /* LGAlertViewDemo.app */, + ); + name = Products; + sourceTree = ""; + }; + 4A3B78621AD2A28200DB8642 /* LGAlertViewDemo */ = { + isa = PBXGroup; + children = ( + 4A3B78671AD2A28200DB8642 /* AppDelegate.h */, + 4A3B78681AD2A28200DB8642 /* AppDelegate.m */, + 4A3B788C1AD2B29F00DB8642 /* NavigationController.h */, + 4A3B788D1AD2B29F00DB8642 /* NavigationController.m */, + 4A3B78891AD2A93D00DB8642 /* TableViewController.h */, + 4A3B788A1AD2A93D00DB8642 /* TableViewController.m */, + 4A3B78701AD2A28300DB8642 /* Images.xcassets */, + 4A3B78631AD2A28200DB8642 /* Supporting Files */, + ); + path = LGAlertViewDemo; + sourceTree = ""; + }; + 4A3B78631AD2A28200DB8642 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 4A3B78641AD2A28200DB8642 /* Info.plist */, + 4A3B78651AD2A28200DB8642 /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 72646D99469FDAC04E185CBA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 623B5C352E52555F577FBF72 /* libPods-LGAlertViewDemo.a */, + ); + name = Frameworks; + sourceTree = ""; + }; + A97F0E110AD1D1F440968EB0 /* Pods */ = { + isa = PBXGroup; + children = ( + 637E642E08EC55B4AF82AB1E /* Pods-LGAlertViewDemo.debug.xcconfig */, + 75F4867B7B8225C0410A3B3A /* Pods-LGAlertViewDemo.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 4A3B785F1AD2A28200DB8642 /* LGAlertViewDemo */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4A3B78831AD2A28300DB8642 /* Build configuration list for PBXNativeTarget "LGAlertViewDemo" */; + buildPhases = ( + 4F6C50315945C908415D4792 /* Check Pods Manifest.lock */, + 4A3B785C1AD2A28200DB8642 /* Sources */, + 4A3B785D1AD2A28200DB8642 /* Frameworks */, + 4A3B785E1AD2A28200DB8642 /* Resources */, + 29113AC9920AC8E38789F323 /* Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = LGAlertViewDemo; + productName = LGAlertViewDemo; + productReference = 4A3B78601AD2A28200DB8642 /* LGAlertViewDemo.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 4A3B78581AD2A28200DB8642 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0620; + ORGANIZATIONNAME = "Grigory Lutkov"; + TargetAttributes = { + 4A3B785F1AD2A28200DB8642 = { + CreatedOnToolsVersion = 6.2; + }; + }; + }; + buildConfigurationList = 4A3B785B1AD2A28200DB8642 /* Build configuration list for PBXProject "LGAlertViewDemo" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 4A3B78571AD2A28200DB8642; + productRefGroup = 4A3B78611AD2A28200DB8642 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 4A3B785F1AD2A28200DB8642 /* LGAlertViewDemo */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 4A3B785E1AD2A28200DB8642 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4A3B78711AD2A28300DB8642 /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 29113AC9920AC8E38789F323 /* Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-LGAlertViewDemo/Pods-LGAlertViewDemo-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 4F6C50315945C908415D4792 /* Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 4A3B785C1AD2A28200DB8642 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4A3B78691AD2A28200DB8642 /* AppDelegate.m in Sources */, + 4A3B788E1AD2B29F00DB8642 /* NavigationController.m in Sources */, + 4A3B78661AD2A28200DB8642 /* main.m in Sources */, + 4A3B788B1AD2A93D00DB8642 /* TableViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 4A3B78811AD2A28300DB8642 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + 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_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 4A3B78821AD2A28300DB8642 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 4A3B78841AD2A28300DB8642 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 637E642E08EC55B4AF82AB1E /* Pods-LGAlertViewDemo.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + INFOPLIST_FILE = LGAlertViewDemo/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 4A3B78851AD2A28300DB8642 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 75F4867B7B8225C0410A3B3A /* Pods-LGAlertViewDemo.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + INFOPLIST_FILE = LGAlertViewDemo/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 4A3B785B1AD2A28200DB8642 /* Build configuration list for PBXProject "LGAlertViewDemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4A3B78811AD2A28300DB8642 /* Debug */, + 4A3B78821AD2A28300DB8642 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4A3B78831AD2A28300DB8642 /* Build configuration list for PBXNativeTarget "LGAlertViewDemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4A3B78841AD2A28300DB8642 /* Debug */, + 4A3B78851AD2A28300DB8642 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 4A3B78581AD2A28200DB8642 /* Project object */; +} diff --git a/Demo/LGAlertViewDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Demo/LGAlertViewDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..22e3633 --- /dev/null +++ b/Demo/LGAlertViewDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Demo/LGAlertViewDemo.xcworkspace/contents.xcworkspacedata b/Demo/LGAlertViewDemo.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..e0193e3 --- /dev/null +++ b/Demo/LGAlertViewDemo.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Demo/LGAlertViewDemo/AppDelegate.h b/Demo/LGAlertViewDemo/AppDelegate.h new file mode 100644 index 0000000..1564a2f --- /dev/null +++ b/Demo/LGAlertViewDemo/AppDelegate.h @@ -0,0 +1,17 @@ +// +// AppDelegate.h +// LGAlertViewDemo +// +// Created by Grigory Lutkov on 18.02.15. +// Copyright (c) 2015 Grigory Lutkov. All rights reserved. +// + +#import +#import "NavigationController.h" + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; +@property (strong, nonatomic) UINavigationController *navigationController; + +@end diff --git a/Demo/LGAlertViewDemo/AppDelegate.m b/Demo/LGAlertViewDemo/AppDelegate.m new file mode 100644 index 0000000..0e54c71 --- /dev/null +++ b/Demo/LGAlertViewDemo/AppDelegate.m @@ -0,0 +1,52 @@ +// +// AppDelegate.m +// LGAlertViewDemo +// +// Created by Grigory Lutkov on 18.02.15. +// Copyright (c) 2015 Grigory Lutkov. All rights reserved. +// + +#import "AppDelegate.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + self.navigationController = [NavigationController new]; + + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + self.window.rootViewController = self.navigationController; + self.window.backgroundColor = [UIColor whiteColor]; + [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/Demo/LGAlertViewDemo/Images.xcassets/AppIcon.appiconset/Contents.json b/Demo/LGAlertViewDemo/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..c5fda8e --- /dev/null +++ b/Demo/LGAlertViewDemo/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,9 @@ +{ + "images" : [ + + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Demo/LGAlertViewDemo/Images.xcassets/Filter.imageset/Contents.json b/Demo/LGAlertViewDemo/Images.xcassets/Filter.imageset/Contents.json new file mode 100644 index 0000000..5b83e18 --- /dev/null +++ b/Demo/LGAlertViewDemo/Images.xcassets/Filter.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x", + "filename" : "Filter@1x.png" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "Filter@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x", + "filename" : "Filter@3x.png" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Demo/LGAlertViewDemo/Images.xcassets/Filter.imageset/Filter@1x.png b/Demo/LGAlertViewDemo/Images.xcassets/Filter.imageset/Filter@1x.png new file mode 100644 index 0000000..44f5780 Binary files /dev/null and b/Demo/LGAlertViewDemo/Images.xcassets/Filter.imageset/Filter@1x.png differ diff --git a/Demo/LGAlertViewDemo/Images.xcassets/Filter.imageset/Filter@2x.png b/Demo/LGAlertViewDemo/Images.xcassets/Filter.imageset/Filter@2x.png new file mode 100644 index 0000000..7cff606 Binary files /dev/null and b/Demo/LGAlertViewDemo/Images.xcassets/Filter.imageset/Filter@2x.png differ diff --git a/Demo/LGAlertViewDemo/Images.xcassets/Filter.imageset/Filter@3x.png b/Demo/LGAlertViewDemo/Images.xcassets/Filter.imageset/Filter@3x.png new file mode 100644 index 0000000..937a35f Binary files /dev/null and b/Demo/LGAlertViewDemo/Images.xcassets/Filter.imageset/Filter@3x.png differ diff --git a/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Contents.json b/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Contents.json new file mode 100644 index 0000000..9da5e8e --- /dev/null +++ b/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Contents.json @@ -0,0 +1,134 @@ +{ + "images" : [ + { + "extent" : "full-screen", + "idiom" : "iphone", + "subtype" : "736h", + "filename" : "Launch-Phone-55-P@3x.png", + "minimum-system-version" : "8.0", + "orientation" : "portrait", + "scale" : "3x" + }, + { + "extent" : "full-screen", + "idiom" : "iphone", + "subtype" : "736h", + "filename" : "Launch-Phone-55-L@3x.png", + "minimum-system-version" : "8.0", + "orientation" : "landscape", + "scale" : "3x" + }, + { + "extent" : "full-screen", + "idiom" : "iphone", + "subtype" : "667h", + "filename" : "Launch-Phone-47-P@2x.png", + "minimum-system-version" : "8.0", + "orientation" : "portrait", + "scale" : "2x" + }, + { + "orientation" : "portrait", + "idiom" : "iphone", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "filename" : "Launch-Phone-35-P@2x.png", + "scale" : "2x" + }, + { + "extent" : "full-screen", + "idiom" : "iphone", + "subtype" : "retina4", + "filename" : "Launch-Phone-40-P@2x.png", + "minimum-system-version" : "7.0", + "orientation" : "portrait", + "scale" : "2x" + }, + { + "orientation" : "portrait", + "idiom" : "ipad", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "filename" : "Launch-Pad-P@1x.png", + "scale" : "1x" + }, + { + "orientation" : "landscape", + "idiom" : "ipad", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "filename" : "Launch-Pad-L@1x.png", + "scale" : "1x" + }, + { + "orientation" : "portrait", + "idiom" : "ipad", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "filename" : "Launch-Pad-P@2x.png", + "scale" : "2x" + }, + { + "orientation" : "landscape", + "idiom" : "ipad", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "filename" : "Launch-Pad-L@2x.png", + "scale" : "2x" + }, + { + "orientation" : "portrait", + "idiom" : "iphone", + "extent" : "full-screen", + "filename" : "Launch-Phone-35-P@1x.png", + "scale" : "1x" + }, + { + "orientation" : "portrait", + "idiom" : "iphone", + "extent" : "full-screen", + "filename" : "Launch-Phone-35-P@2x.png", + "scale" : "2x" + }, + { + "orientation" : "portrait", + "idiom" : "iphone", + "extent" : "full-screen", + "filename" : "Launch-Phone-40-P@2x.png", + "subtype" : "retina4", + "scale" : "2x" + }, + { + "orientation" : "portrait", + "idiom" : "ipad", + "extent" : "full-screen", + "filename" : "Launch-Pad-P@1x.png", + "scale" : "1x" + }, + { + "orientation" : "landscape", + "idiom" : "ipad", + "extent" : "full-screen", + "filename" : "Launch-Pad-L@1x.png", + "scale" : "1x" + }, + { + "orientation" : "portrait", + "idiom" : "ipad", + "extent" : "full-screen", + "filename" : "Launch-Pad-P@2x.png", + "scale" : "2x" + }, + { + "orientation" : "landscape", + "idiom" : "ipad", + "extent" : "full-screen", + "filename" : "Launch-Pad-L@2x.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-L@1x.png b/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-L@1x.png new file mode 100644 index 0000000..67c9e1d Binary files /dev/null and b/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-L@1x.png differ diff --git a/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-L@2x.png b/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-L@2x.png new file mode 100644 index 0000000..2ce1e95 Binary files /dev/null and b/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-L@2x.png differ diff --git a/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-P@1x.png b/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-P@1x.png new file mode 100644 index 0000000..369ade2 Binary files /dev/null and b/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-P@1x.png differ diff --git a/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-P@2x.png b/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-P@2x.png new file mode 100644 index 0000000..d379a54 Binary files /dev/null and b/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-P@2x.png differ diff --git a/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-35-P@1x.png b/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-35-P@1x.png new file mode 100644 index 0000000..107999c Binary files /dev/null and b/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-35-P@1x.png differ diff --git a/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-35-P@2x.png b/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-35-P@2x.png new file mode 100644 index 0000000..b69f17f Binary files /dev/null and b/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-35-P@2x.png differ diff --git a/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-40-P@2x.png b/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-40-P@2x.png new file mode 100644 index 0000000..6258ece Binary files /dev/null and b/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-40-P@2x.png differ diff --git a/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-47-P@2x.png b/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-47-P@2x.png new file mode 100644 index 0000000..c257d16 Binary files /dev/null and b/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-47-P@2x.png differ diff --git a/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-55-L@3x.png b/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-55-L@3x.png new file mode 100644 index 0000000..34ec1ed Binary files /dev/null and b/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-55-L@3x.png differ diff --git a/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-55-P@3x.png b/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-55-P@3x.png new file mode 100644 index 0000000..1b08e31 Binary files /dev/null and b/Demo/LGAlertViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-55-P@3x.png differ diff --git a/Demo/LGAlertViewDemo/Info.plist b/Demo/LGAlertViewDemo/Info.plist new file mode 100644 index 0000000..493646a --- /dev/null +++ b/Demo/LGAlertViewDemo/Info.plist @@ -0,0 +1,43 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + com.test.$(PRODUCT_NAME) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Demo/LGAlertViewDemo/NavigationController.h b/Demo/LGAlertViewDemo/NavigationController.h new file mode 100644 index 0000000..cc0c247 --- /dev/null +++ b/Demo/LGAlertViewDemo/NavigationController.h @@ -0,0 +1,13 @@ +// +// NavigationController.h +// LGAlertViewDemo +// +// Created by Grigory Lutkov on 18.02.15. +// Copyright (c) 2015 Grigory Lutkov. All rights reserved. +// + +#import + +@interface NavigationController : UINavigationController + +@end diff --git a/Demo/LGAlertViewDemo/NavigationController.m b/Demo/LGAlertViewDemo/NavigationController.m new file mode 100644 index 0000000..7f1d21d --- /dev/null +++ b/Demo/LGAlertViewDemo/NavigationController.m @@ -0,0 +1,36 @@ +// +// NavigationController.m +// LGAlertViewDemo +// +// Created by Grigory Lutkov on 18.02.15. +// Copyright (c) 2015 Grigory Lutkov. All rights reserved. +// + +#import "NavigationController.h" +#import "TableViewController.h" + +@interface NavigationController () + +@property (strong, nonatomic) TableViewController *tableViewController; + +@end + +@implementation NavigationController + +- (id)init +{ + self = [super init]; + if (self) + { + self.tableViewController = [TableViewController new]; + [self setViewControllers:@[self.tableViewController]]; + } + return self; +} + +- (BOOL)shouldAutorotate +{ + return self.topViewController.shouldAutorotate; +} + +@end diff --git a/Demo/LGAlertViewDemo/TableViewController.h b/Demo/LGAlertViewDemo/TableViewController.h new file mode 100644 index 0000000..887824c --- /dev/null +++ b/Demo/LGAlertViewDemo/TableViewController.h @@ -0,0 +1,13 @@ +// +// TableViewController.h +// LGAlertViewDemo +// +// Created by Grigory Lutkov on 18.02.15. +// Copyright (c) 2015 Grigory Lutkov. All rights reserved. +// + +#import + +@interface TableViewController : UITableViewController + +@end diff --git a/Demo/LGAlertViewDemo/TableViewController.m b/Demo/LGAlertViewDemo/TableViewController.m new file mode 100644 index 0000000..7c438f6 --- /dev/null +++ b/Demo/LGAlertViewDemo/TableViewController.m @@ -0,0 +1,343 @@ +// +// TableViewController.m +// LGAlertViewDemo +// +// Created by Grigory Lutkov on 18.02.15. +// Copyright (c) 2015 Grigory Lutkov. All rights reserved. +// + +#import "TableViewController.h" +#import "LGAlertView.h" + +@interface TableViewController () + +@property (strong, nonatomic) NSArray *titlesArray; + +@end + +@implementation TableViewController + +- (id)init +{ + self = [super initWithStyle:UITableViewStylePlain]; + if (self) + { + self.title = @"LGAlertView"; + + _titlesArray = @[@"UIAlertView", + @"LGAlertView + UIView", + @"LGAlertView + Buttons Short", + @"LGAlertView + Buttons Long", + @"LGAlertView + Buttons Multiline", + @"LGAlertView + Buttons (a lot of) 1", + @"LGAlertView + Buttons (a lot of) 2", + @"LGAlertView + No cancel gesture", + @"LGAlertView + TextFiled", + @"LGAlertView + TextFiled (a lot of)", + @"LGAlertView + ActivityIndicator", + @"LGAlertView + ProgressView", + @"LGAlertView + Crazy style"]; + + [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"]; + } + return self; +} + +#pragma mark - UITableView DataSource + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return _titlesArray.count; +} + +#pragma mark - UITableView Delegate + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; + + cell.textLabel.font = [UIFont systemFontOfSize:16.f]; + cell.textLabel.text = _titlesArray[indexPath.row]; + + return cell; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath +{ + return 44.f; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + if (indexPath.row == 0) + { + [[[UIAlertView alloc] initWithTitle:@"Title" + message:@"Message" + delegate:nil + cancelButtonTitle:@"Cancel" + otherButtonTitles:@"Other 1", @"Other 2", @"Destructive", nil] show]; + } + else if (indexPath.row == 1) + { + UIDatePicker *datePicker = [UIDatePicker new]; + datePicker.frame = CGRectMake(0.f, 0.f, datePicker.frame.size.width, 100.f); + + [[[LGAlertView alloc] initWithViewStyleWithTitle:@"WOW, it's DatePicker here" + message:@"Choose any date, please" + view:datePicker + buttonTitles:@[@"Done"] + cancelButtonTitle:@"Cancel" + destructiveButtonTitle:nil + actionHandler:nil + cancelHandler:nil + destructiveHandler:nil] showAnimated:YES completionHandler:nil]; + } + else if (indexPath.row == 2) + { + [[[LGAlertView alloc] initWithTitle:@"Just title" + message:@"2 buttons in a row" + buttonTitles:nil + cancelButtonTitle:@"Cancel" + destructiveButtonTitle:@"Destructive" + actionHandler:nil + cancelHandler:nil + destructiveHandler:nil] showAnimated:YES completionHandler:nil]; + } + else if (indexPath.row == 3) + { + [[[LGAlertView alloc] initWithTitle:@"Some long title text, for iPhone 6 Plus even bigger." + message:@"Some really unbelievable long message text. And for iPhone 6 Plus it needs to be even bigger." + buttonTitles:@[@"Other button 1 with longest title text, for iPhone 6 Plus even bigger.", + @"Other button 2 with longest title text, for iPhone 6 Plus even bigger."] + cancelButtonTitle:@"Cancel" + destructiveButtonTitle:@"Destructive" + actionHandler:nil + cancelHandler:nil + destructiveHandler:nil] showAnimated:YES completionHandler:nil]; + } + else if (indexPath.row == 4) + { + LGAlertView *alertView = [[LGAlertView alloc] initWithTitle:@"Some long title text, for iPhone 6 Plus even bigger." + message:@"Some really unbelievable long message text. And for iPhone 6 Plus it needs to be even bigger." + buttonTitles:@[@"Other button 1 with longest title text, for iPhone 6 Plus even bigger.", + @"Other button 2 with longest title text, for iPhone 6 Plus even bigger."] + cancelButtonTitle:@"Cancel" + destructiveButtonTitle:@"Destructive" + actionHandler:nil + cancelHandler:nil + destructiveHandler:nil]; + alertView.buttonsNumberOfLines = 0; + [alertView showAnimated:YES completionHandler:nil]; + } + else if (indexPath.row == 5) + { + [[[LGAlertView alloc] initWithTitle:@"So many buttons..." + message:@"Scroll it, if you can" + buttonTitles:@[@"Other 1", + @"Other 2", + @"Other 3", + @"Other 4", + @"Other 5", + @"Other 6", + @"Other 7", + @"Other 8", + @"Other 9", + @"Other 10", + @"Other 12", + @"Other 13", + @"Other 14", + @"Other 15"] + cancelButtonTitle:@"Cancel" + destructiveButtonTitle:@"Destructive" + actionHandler:nil + cancelHandler:nil + destructiveHandler:nil] showAnimated:YES completionHandler:nil]; + } + else if (indexPath.row == 6) + { + LGAlertView *alertView = [[LGAlertView alloc] initWithTitle:@"So many buttons..." + message:@"On iPad width will be full screen size. And buttons highlighted colors are grey." + buttonTitles:@[@"Other 1", + @"Other 2", + @"Other 3", + @"Other 4", + @"Other 5", + @"Other 6", + @"Other 7", + @"Other 8", + @"Other 9", + @"Other 10", + @"Other 12", + @"Other 13", + @"Other 14", + @"Other 15"] + cancelButtonTitle:@"Cancel" + destructiveButtonTitle:@"Destructive" + actionHandler:nil + cancelHandler:nil + destructiveHandler:nil]; + alertView.heightMax = 200.f; + alertView.widthMax = CGFLOAT_MAX; + alertView.colorful = NO; + [alertView showAnimated:YES completionHandler:nil]; + } + else if (indexPath.row == 7) + { + LGAlertView *alertView = [[LGAlertView alloc] initWithTitle:@"No cancel here" + message:@"You need to make a decision" + buttonTitles:@[@"Blue pill"] + cancelButtonTitle:nil + destructiveButtonTitle:@"Red pill" + actionHandler:nil + cancelHandler:nil + destructiveHandler:nil]; + alertView.cancelOnTouch = NO; + [alertView showAnimated:YES completionHandler:nil]; + } + else if (indexPath.row == 8) + { + LGAlertView *alertView = [[LGAlertView alloc] initWithTextFieldsStyleWithTitle:@"Security" + message:@"Enter your login and password" + numberOfTextFields:2 + textFieldsSetupHandler:^(UITextField *textField, NSUInteger index) + { + if (index == 0) + textField.placeholder = @"Login"; + else if (index == 1) + { + textField.placeholder = @"Password"; + textField.secureTextEntry = YES; + } + } + buttonTitles:@[@"Done"] + cancelButtonTitle:@"Cancel" + destructiveButtonTitle:nil + actionHandler:nil + cancelHandler:nil + destructiveHandler:nil]; + + alertView.cancelOnTouch = NO; + [alertView showAnimated:YES completionHandler:nil]; + } + else if (indexPath.row == 9) + { + LGAlertView *alertView = [[LGAlertView alloc] initWithTextFieldsStyleWithTitle:@"So many textFields..." + message:@"When you select some, alertView will change size" + numberOfTextFields:15 + textFieldsSetupHandler:^(UITextField *textField, NSUInteger index) + { + textField.placeholder = [NSString stringWithFormat:@"Beautiful placeholder %i", (int)index]; + } + buttonTitles:@[@"Done"] + cancelButtonTitle:@"Cancel" + destructiveButtonTitle:nil + actionHandler:nil + cancelHandler:nil + destructiveHandler:nil]; + + alertView.cancelOnTouch = NO; + [alertView showAnimated:YES completionHandler:nil]; + } + else if (indexPath.row == 10) + { + LGAlertView *alertView = [[LGAlertView alloc] initWithActivityIndicatorStyleWithTitle:@"Loading" + message:@"Waiting please" + buttonTitles:nil + cancelButtonTitle:@"I'm hurry" + destructiveButtonTitle:nil + actionHandler:nil + cancelHandler:nil + destructiveHandler:nil]; + alertView.cancelOnTouch = NO; + [alertView showAnimated:YES completionHandler:nil]; + } + else if (indexPath.row == 11) + { + LGAlertView *alertView = [[LGAlertView alloc] initWithProgressViewStyleWithTitle:@"Loading" + message:@"Waiting please" + progressLabelText:@"0 %" + buttonTitles:nil + cancelButtonTitle:@"I'm hurry" + destructiveButtonTitle:nil + actionHandler:nil + cancelHandler:nil + destructiveHandler:nil]; + alertView.cancelOnTouch = NO; + [alertView showAnimated:YES completionHandler:nil]; + + [self updateProgressWithAlertView:alertView]; + } + else if (indexPath.row == 12) + { + LGAlertView *alertView = [[LGAlertView alloc] initWithTitle:@"CRAZY STYLE" + message:@"May be someone like it?" + buttonTitles:@[@"Awesome Button"] + cancelButtonTitle:@"Cancel" + destructiveButtonTitle:@"Destructive" + actionHandler:nil + cancelHandler:nil + destructiveHandler:nil]; + + alertView.backgroundColor = [UIColor colorWithWhite:1.f alpha:0.8]; + + alertView.backgroundColor = [UIColor colorWithWhite:0.3 alpha:0.8]; + alertView.layerBorderWidth = 1.f; + alertView.layerBorderColor = [UIColor redColor]; + alertView.layerCornerRadius = 0.f; + alertView.layerShadowColor = [UIColor colorWithWhite:0.f alpha:0.5]; + alertView.layerShadowRadius = 5.f; + + alertView.titleTextAlignment = NSTextAlignmentRight; + alertView.titleTextColor = [UIColor whiteColor]; + + alertView.messageTextAlignment = NSTextAlignmentLeft; + alertView.messageTextColor = [UIColor whiteColor]; + + alertView.separatorsColor = [UIColor colorWithWhite:0.6 alpha:1.f]; + + alertView.tintColor = [UIColor greenColor]; + + alertView.buttonsTitleColorHighlighted = [UIColor blackColor]; + + alertView.cancelButtonTitleColor = [UIColor cyanColor]; + alertView.cancelButtonTitleColorHighlighted = [UIColor blackColor]; + alertView.cancelButtonBackgroundColorHighlighted = [UIColor cyanColor]; + + alertView.destructiveButtonTitleColor = [UIColor yellowColor]; + alertView.destructiveButtonTitleColorHighlighted = [UIColor blackColor]; + alertView.destructiveButtonBackgroundColorHighlighted = [UIColor yellowColor]; + + // And much more settings you can apply, check it in LGAlertView class + + [alertView showAnimated:YES completionHandler:nil]; + } + + [tableView deselectRowAtIndexPath:indexPath animated:YES]; +} + +- (void)updateProgressWithAlertView:(LGAlertView *)alertView +{ + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^(void) + { + if (alertView.progress >= 1.f) + [alertView dismissAnimated:YES completionHandler:nil]; + else + { + float progress = alertView.progress+0.0025; + + if (progress > 1.f) + progress = 1.f; + + [alertView setProgress:progress progressLabelText:[NSString stringWithFormat:@"%.0f %%", progress*100]]; + + [self updateProgressWithAlertView:alertView]; + } + }); +} + +@end diff --git a/Demo/LGAlertViewDemo/main.m b/Demo/LGAlertViewDemo/main.m new file mode 100644 index 0000000..94dc0f5 --- /dev/null +++ b/Demo/LGAlertViewDemo/main.m @@ -0,0 +1,16 @@ +// +// main.m +// LGAlertViewDemo +// +// Created by Friend_LGA on 06.04.15. +// Copyright (c) 2015 Grigory Lutkov. 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/Demo/Podfile b/Demo/Podfile new file mode 100644 index 0000000..608bfa7 --- /dev/null +++ b/Demo/Podfile @@ -0,0 +1,10 @@ +source 'https://github.com/CocoaPods/Specs.git' + +platform :ios, '6.0' +inhibit_all_warnings! + +xcodeproj 'LGAlertViewDemo' + +target 'LGAlertViewDemo' do + pod 'LGAlertView', :path => '../' +end diff --git a/Demo/Podfile.lock b/Demo/Podfile.lock new file mode 100644 index 0000000..7fedba9 --- /dev/null +++ b/Demo/Podfile.lock @@ -0,0 +1,14 @@ +PODS: + - LGAlertView (1.0.0) + +DEPENDENCIES: + - LGAlertView (from `../`) + +EXTERNAL SOURCES: + LGAlertView: + :path: ../ + +SPEC CHECKSUMS: + LGAlertView: d7580a71fd5cf7546c723f69e50a0af892c04036 + +COCOAPODS: 0.37.2 diff --git a/Demo/podsInstall.command b/Demo/podsInstall.command new file mode 100644 index 0000000..3c76888 --- /dev/null +++ b/Demo/podsInstall.command @@ -0,0 +1,5 @@ +#!/bin/sh + +cd "$(dirname "$0")" + +pod install diff --git a/Demo/podsUpdate.command b/Demo/podsUpdate.command new file mode 100644 index 0000000..f48a821 --- /dev/null +++ b/Demo/podsUpdate.command @@ -0,0 +1,5 @@ +#!/bin/sh + +cd "$(dirname "$0")" + +pod update diff --git a/LGAlertView.podspec b/LGAlertView.podspec new file mode 100644 index 0000000..c1941b5 --- /dev/null +++ b/LGAlertView.podspec @@ -0,0 +1,16 @@ +Pod::Spec.new do |s| + + s.name = 'LGAlertView' + s.version = '1.0.0' + s.platform = :ios, '6.0' + s.license = 'MIT' + s.homepage = 'https://github.com/Friend-LGA/LGAlertView' + s.author = { 'Grigory Lutkov' => 'Friend.LGA@gmail.com' } + s.source = { :git => 'https://github.com/Friend-LGA/LGAlertView.git', :tag => s.version } + s.summary = 'Customizable implementation of UIAlertView' + + s.requires_arc = true + + s.source_files = 'LGAlertView/*.{h,m}' + +end diff --git a/LGAlertView/LGAlertView.h b/LGAlertView/LGAlertView.h new file mode 100644 index 0000000..4917e66 --- /dev/null +++ b/LGAlertView/LGAlertView.h @@ -0,0 +1,437 @@ +// +// LGActionView.h +// LGAlertView +// +// +// The MIT License (MIT) +// +// Copyright (c) 2015 Grigory Lutkov +// (https://github.com/Friend-LGA/LGAlertView) +// +// 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 + +@class LGAlertView; + +static NSString *const kLGAlertViewWillShowNotification = @"LGAlertViewWillShowNotification"; +static NSString *const kLGAlertViewWillDismissNotification = @"LGAlertViewWillDismissNotification"; +static NSString *const kLGAlertViewDidShowNotification = @"LGAlertViewDidShowNotification"; +static NSString *const kLGAlertViewDidDismissNotification = @"LGAlertViewDidDismissNotification"; + +static CGFloat const kLGAlertViewMargin = 16.f; +static CGFloat const kLGAlertViewWidth = 320.f-kLGAlertViewMargin*2; + +@protocol LGAlertViewDelegate + +@optional + +- (void)alertViewWillShow:(LGAlertView *)alertView; +- (void)alertViewWillDismiss:(LGAlertView *)alertView; +- (void)alertViewDidShow:(LGAlertView *)alertView; +- (void)alertViewDidDismiss:(LGAlertView *)alertView; +- (void)alertView:(LGAlertView *)alertView buttonPressedWithTitle:(NSString *)title index:(NSUInteger)index; +- (void)alertViewCancelled:(LGAlertView *)alertView; +- (void)alertViewDestructiveButtonPressed:(LGAlertView *)alertView; + +@end + +@interface LGAlertView : NSObject + +@property (assign, nonatomic, getter=isShowing) BOOL showing; + +/** Default is YES */ +@property (assign, nonatomic, getter=isCancelOnTouch) BOOL cancelOnTouch; +/** Set highlighted buttons background color to blue, and set highlighted destructive button background color to red. Default is YES */ +@property (assign, nonatomic, getter=isColorful) BOOL colorful; + +@property (strong, nonatomic) UIColor *tintColor; +@property (strong, nonatomic) UIColor *coverColor; +@property (strong, nonatomic) UIColor *backgroundColor; +@property (assign, nonatomic) CGFloat layerCornerRadius; +@property (strong, nonatomic) UIColor *layerBorderColor; +@property (assign, nonatomic) CGFloat layerBorderWidth; +@property (strong, nonatomic) UIColor *layerShadowColor; +@property (assign, nonatomic) CGFloat layerShadowRadius; + +@property (assign, nonatomic) CGFloat heightMax; +@property (assign, nonatomic) CGFloat widthMax; + +@property (strong, nonatomic) UIColor *titleTextColor; +@property (assign, nonatomic) NSTextAlignment titleTextAlignment; +@property (strong, nonatomic) UIFont *titleFont; + +@property (strong, nonatomic) UIColor *messageTextColor; +@property (assign, nonatomic) NSTextAlignment messageTextAlignment; +@property (strong, nonatomic) UIFont *messageFont; + +@property (strong, nonatomic) UIColor *buttonsTitleColor; +@property (strong, nonatomic) UIColor *buttonsTitleColorHighlighted; +@property (assign, nonatomic) NSTextAlignment buttonsTextAlignment; +@property (strong, nonatomic) UIFont *buttonsFont; +@property (strong, nonatomic) UIColor *buttonsBackgroundColorHighlighted; +@property (assign, nonatomic) NSUInteger buttonsNumberOfLines; +@property (assign, nonatomic) NSLineBreakMode buttonsLineBreakMode; +@property (assign, nonatomic) BOOL buttonsAdjustsFontSizeToFitWidth; +@property (assign, nonatomic) CGFloat buttonsMinimumScaleFactor; + +@property (strong, nonatomic) UIColor *cancelButtonTitleColor; +@property (strong, nonatomic) UIColor *cancelButtonTitleColorHighlighted; +@property (assign, nonatomic) NSTextAlignment cancelButtonTextAlignment; +@property (strong, nonatomic) UIFont *cancelButtonFont; +@property (strong, nonatomic) UIColor *cancelButtonBackgroundColorHighlighted; +@property (assign, nonatomic) NSUInteger cancelButtonNumberOfLines; +@property (assign, nonatomic) NSLineBreakMode cancelButtonLineBreakMode; +@property (assign, nonatomic) BOOL cancelButtonAdjustsFontSizeToFitWidth; +@property (assign, nonatomic) CGFloat cancelButtonMinimumScaleFactor; + +@property (strong, nonatomic) UIColor *destructiveButtonTitleColor; +@property (strong, nonatomic) UIColor *destructiveButtonTitleColorHighlighted; +@property (assign, nonatomic) NSTextAlignment destructiveButtonTextAlignment; +@property (strong, nonatomic) UIFont *destructiveButtonFont; +@property (strong, nonatomic) UIColor *destructiveButtonBackgroundColorHighlighted; +@property (assign, nonatomic) NSUInteger destructiveButtonNumberOfLines; +@property (assign, nonatomic) NSLineBreakMode destructiveButtonLineBreakMode; +@property (assign, nonatomic) BOOL destructiveButtonAdjustsFontSizeToFitWidth; +@property (assign, nonatomic) CGFloat destructiveButtonMinimumScaleFactor; + +@property (assign, nonatomic) UIActivityIndicatorViewStyle activityIndicatorViewStyle; +@property (strong, nonatomic) UIColor *activityIndicatorViewColor; + +@property (strong, nonatomic) UIColor *progressViewProgressTintColor; +@property (strong, nonatomic) UIColor *progressViewTrackTintColor; +@property (strong, nonatomic) UIImage *progressViewProgressImage; +@property (strong, nonatomic) UIImage *progressViewTrackImage; + +@property (assign, nonatomic, readonly) float progress; + +@property (strong, nonatomic) UIColor *progressLabelTextColor; +@property (assign, nonatomic) NSTextAlignment progressLabelTextAlignment; +@property (strong, nonatomic) UIFont *progressLabelFont; + +@property (strong, nonatomic) UIColor *separatorsColor; + +@property (assign, nonatomic) UIScrollViewIndicatorStyle indicatorStyle; + +@property (strong, nonatomic, readonly) NSMutableArray *textFieldsArray; + +/** Do not forget about weak referens to self */ +@property (strong, nonatomic) void (^willShowHandler)(LGAlertView *alertView); +/** Do not forget about weak referens to self */ +@property (strong, nonatomic) void (^willDismissHandler)(LGAlertView *alertView); +/** Do not forget about weak referens to self */ +@property (strong, nonatomic) void (^didShowHandler)(LGAlertView *alertView); +/** Do not forget about weak referens to self */ +@property (strong, nonatomic) void (^didDismissHandler)(LGAlertView *alertView); + +/** Do not forget about weak referens to self */ +@property (strong, nonatomic) void (^actionHandler)(LGAlertView *alertView, NSString *title, NSUInteger index); +/** Do not forget about weak referens to self */ +@property (strong, nonatomic) void (^cancelHandler)(LGAlertView *alertView, BOOL onButton); +/** Do not forget about weak referens to self */ +@property (strong, nonatomic) void (^destructiveHandler)(LGAlertView *alertView); + +@property (assign, nonatomic) id delegate; + +- (instancetype)initWithTitle:(NSString *)title + message:(NSString *)message + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle; + +/** View can not be subclass of UIScrollView */ +- (instancetype)initWithViewStyleWithTitle:(NSString *)title + message:(NSString *)message + view:(UIView *)view + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle; + +- (instancetype)initWithActivityIndicatorStyleWithTitle:(NSString *)title + message:(NSString *)message + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle; + +- (instancetype)initWithProgressViewStyleWithTitle:(NSString *)title + message:(NSString *)message + progressLabelText:(NSString *)progressLabelText + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle; + +- (instancetype)initWithTextFieldsStyleWithTitle:(NSString *)title + message:(NSString *)message + numberOfTextFields:(NSUInteger)numberOfTextFields + textFieldsSetupHandler:(void(^)(UITextField *textField, NSUInteger index))textFieldsSetupHandler + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle; + ++ (instancetype)alertViewWithTitle:(NSString *)title + message:(NSString *)message + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle; + +/** View can not be subclass of UIScrollView */ ++ (instancetype)alertViewWithViewStyleWithTitle:(NSString *)title + message:(NSString *)message + view:(UIView *)view + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle; + ++ (instancetype)alertViewWithActivityIndicatorStyleWithTitle:(NSString *)title + message:(NSString *)message + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle; + ++ (instancetype)alertViewWithProgressViewStyleWithTitle:(NSString *)title + message:(NSString *)message + progressLabelText:(NSString *)progressLabelText + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle; + ++ (instancetype)alertViewWithTextFieldsStyleWithTitle:(NSString *)title + message:(NSString *)message + numberOfTextFields:(NSUInteger)numberOfTextFields + textFieldsSetupHandler:(void(^)(UITextField *textField, NSUInteger index))textFieldsSetupHandler + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle; + +#pragma mark - + +/** Do not forget about weak referens to self for actionHandler, cancelHandler and destructiveHandler blocks */ +- (instancetype)initWithTitle:(NSString *)title + message:(NSString *)message + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle + actionHandler:(void(^)(LGAlertView *alertView, NSString *title, NSUInteger index))actionHandler + cancelHandler:(void(^)(LGAlertView *alertView, BOOL onButton))cancelHandler + destructiveHandler:(void(^)(LGAlertView *alertView))destructiveHandler; + +/** + View can not be subclass of UIScrollView. + Do not forget about weak referens to self for actionHandler, cancelHandler and destructiveHandler blocks. + */ +- (instancetype)initWithViewStyleWithTitle:(NSString *)title + message:(NSString *)message + view:(UIView *)view + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle + actionHandler:(void(^)(LGAlertView *alertView, NSString *title, NSUInteger index))actionHandler + cancelHandler:(void(^)(LGAlertView *alertView, BOOL onButton))cancelHandler + destructiveHandler:(void(^)(LGAlertView *alertView))destructiveHandler; + +/** Do not forget about weak referens to self for actionHandler, cancelHandler and destructiveHandler blocks */ +- (instancetype)initWithActivityIndicatorStyleWithTitle:(NSString *)title + message:(NSString *)message + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle + actionHandler:(void(^)(LGAlertView *alertView, NSString *title, NSUInteger index))actionHandler + cancelHandler:(void(^)(LGAlertView *alertView, BOOL onButton))cancelHandler + destructiveHandler:(void(^)(LGAlertView *alertView))destructiveHandler; + +/** Do not forget about weak referens to self for actionHandler, cancelHandler and destructiveHandler blocks */ +- (instancetype)initWithProgressViewStyleWithTitle:(NSString *)title + message:(NSString *)message + progressLabelText:(NSString *)progressLabelText + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle + actionHandler:(void(^)(LGAlertView *alertView, NSString *title, NSUInteger index))actionHandler + cancelHandler:(void(^)(LGAlertView *alertView, BOOL onButton))cancelHandler + destructiveHandler:(void(^)(LGAlertView *alertView))destructiveHandler; + +/** Do not forget about weak referens to self for actionHandler, cancelHandler and destructiveHandler blocks */ +- (instancetype)initWithTextFieldsStyleWithTitle:(NSString *)title + message:(NSString *)message + numberOfTextFields:(NSUInteger)numberOfTextFields + textFieldsSetupHandler:(void(^)(UITextField *textField, NSUInteger index))textFieldsSetupHandler + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle + actionHandler:(void(^)(LGAlertView *alertView, NSString *title, NSUInteger index))actionHandler + cancelHandler:(void(^)(LGAlertView *alertView, BOOL onButton))cancelHandler + destructiveHandler:(void(^)(LGAlertView *alertView))destructiveHandler; + +/** Do not forget about weak referens to self for actionHandler, cancelHandler and destructiveHandler blocks */ ++ (instancetype)alertViewWithTitle:(NSString *)title + message:(NSString *)message + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle + actionHandler:(void(^)(LGAlertView *alertView, NSString *title, NSUInteger index))actionHandler + cancelHandler:(void(^)(LGAlertView *alertView, BOOL onButton))cancelHandler + destructiveHandler:(void(^)(LGAlertView *alertView))destructiveHandler; + +/** + View can not be subclass of UIScrollView. + Do not forget about weak referens to self for actionHandler, cancelHandler and destructiveHandler blocks. + */ ++ (instancetype)alertViewWithViewStyleWithTitle:(NSString *)title + message:(NSString *)message + view:(UIView *)view + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle + actionHandler:(void(^)(LGAlertView *alertView, NSString *title, NSUInteger index))actionHandler + cancelHandler:(void(^)(LGAlertView *alertView, BOOL onButton))cancelHandler + destructiveHandler:(void(^)(LGAlertView *alertView))destructiveHandler; + +/** Do not forget about weak referens to self for actionHandler, cancelHandler and destructiveHandler blocks */ ++ (instancetype)alertViewWithActivityIndicatorStyleWithTitle:(NSString *)title + message:(NSString *)message + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle + actionHandler:(void(^)(LGAlertView *alertView, NSString *title, NSUInteger index))actionHandler + cancelHandler:(void(^)(LGAlertView *alertView, BOOL onButton))cancelHandler + destructiveHandler:(void(^)(LGAlertView *alertView))destructiveHandler; + +/** Do not forget about weak referens to self for actionHandler, cancelHandler and destructiveHandler blocks */ ++ (instancetype)alertViewWithProgressViewStyleWithTitle:(NSString *)title + message:(NSString *)message + progressLabelText:(NSString *)progressLabelText + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle + actionHandler:(void(^)(LGAlertView *alertView, NSString *title, NSUInteger index))actionHandler + cancelHandler:(void(^)(LGAlertView *alertView, BOOL onButton))cancelHandler + destructiveHandler:(void(^)(LGAlertView *alertView))destructiveHandler; + +/** Do not forget about weak referens to self for actionHandler, cancelHandler and destructiveHandler blocks */ ++ (instancetype)alertViewWithTextFieldsStyleWithTitle:(NSString *)title + message:(NSString *)message + numberOfTextFields:(NSUInteger)numberOfTextFields + textFieldsSetupHandler:(void(^)(UITextField *textField, NSUInteger index))textFieldsSetupHandler + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle + actionHandler:(void(^)(LGAlertView *alertView, NSString *title, NSUInteger index))actionHandler + cancelHandler:(void(^)(LGAlertView *alertView, BOOL onButton))cancelHandler + destructiveHandler:(void(^)(LGAlertView *alertView))destructiveHandler; + +#pragma mark - + +- (instancetype)initWithTitle:(NSString *)title + message:(NSString *)message + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle + delegate:(id)delegate; + +/** View can not be subclass of UIScrollView */ +- (instancetype)initWithViewStyleWithTitle:(NSString *)title + message:(NSString *)message + view:(UIView *)view + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle + delegate:(id)delegate; + +- (instancetype)initWithActivityIndicatorStyleWithTitle:(NSString *)title + message:(NSString *)message + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle + delegate:(id)delegate; + +- (instancetype)initWithProgressViewStyleWithTitle:(NSString *)title + message:(NSString *)message + progressLabelText:(NSString *)progressLabelText + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle + delegate:(id)delegate; + +- (instancetype)initWithTextFieldsStyleWithTitle:(NSString *)title + message:(NSString *)message + numberOfTextFields:(NSUInteger)numberOfTextFields + textFieldsSetupHandler:(void(^)(UITextField *textField, NSUInteger index))textFieldsSetupHandler + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle + delegate:(id)delegate; + ++ (instancetype)alertViewWithTitle:(NSString *)title + message:(NSString *)message + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle + delegate:(id)delegate; + +/** View can not be subclass of UIScrollView */ ++ (instancetype)alertViewWithViewStyleWithTitle:(NSString *)title + message:(NSString *)message + view:(UIView *)view + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle + delegate:(id)delegate; + ++ (instancetype)alertViewWithActivityIndicatorStyleWithTitle:(NSString *)title + message:(NSString *)message + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle + delegate:(id)delegate; + ++ (instancetype)alertViewWithProgressViewStyleWithTitle:(NSString *)title + message:(NSString *)message + progressLabelText:(NSString *)progressLabelText + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle + delegate:(id)delegate; + ++ (instancetype)alertViewWithTextFieldsStyleWithTitle:(NSString *)title + message:(NSString *)message + numberOfTextFields:(NSUInteger)numberOfTextFields + textFieldsSetupHandler:(void(^)(UITextField *textField, NSUInteger index))textFieldsSetupHandler + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle + delegate:(id)delegate; + +#pragma mark - + +- (void)showAnimated:(BOOL)animated completionHandler:(void(^)())completionHandler; +- (void)dismissAnimated:(BOOL)animated completionHandler:(void(^)())completionHandler; + +- (void)setProgress:(float)progress progressLabelText:(NSString *)progressLabelText; + +#pragma mark - + +/** Unavailable, use +alertViewWithTitle... instead */ ++ (instancetype)new __attribute__((unavailable("use +alertViewWithTitle... instead"))); +/** Unavailable, use -initWithTitle... instead */ +- (instancetype)init __attribute__((unavailable("use -initWithTitle... instead"))); +/** Unavailable, use -initWithTitle... instead */ +- (instancetype)initWithFrame:(CGRect)frame __attribute__((unavailable("use -initWithTitle... instead"))); + +@end diff --git a/LGAlertView/LGAlertView.m b/LGAlertView/LGAlertView.m new file mode 100644 index 0000000..64cdc3a --- /dev/null +++ b/LGAlertView/LGAlertView.m @@ -0,0 +1,2124 @@ +// +// LGAlertView.m +// LGAlertView +// +// +// The MIT License (MIT) +// +// Copyright (c) 2015 Grigory Lutkov +// (https://github.com/Friend-LGA/LGAlertView) +// +// 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 "LGAlertView.h" +#import "LGAlertViewCell.h" +#import "LGAlertViewTextField.h" +#import "LGAlertViewShared.h" + +#define kLGAlertViewSeparatorHeight ([UIScreen mainScreen].scale == 1.f || [UIDevice currentDevice].systemVersion.floatValue < 7.0 ? 1.f : 0.5) + +static CGFloat const kLGAlertViewInnerMarginH = 10.f; +static CGFloat const kLGAlertViewButtonTitleMarginH = 5.f; +static CGFloat const kLGAlertViewButtonHeight = 44.f; +static CGFloat const kLGAlertViewTextFieldHeight = 44.f; + +@interface UIWindow (LGAlertView) + +- (UIViewController *)currentViewController; + +@end + +@interface LGAlertViewViewController : UIViewController + +@property (strong, nonatomic) LGAlertView *alertView; + +@end + +@interface LGAlertView () + +typedef enum +{ + LGAlertViewStyleNone = 0, + LGAlertViewStyleActivityIndicator = 1, + LGAlertViewStyleProgressView = 2, + LGAlertViewStyleTextFields = 3 +} +LGAlertViewStyle; + +@property (assign, nonatomic, getter=isExists) BOOL exists; + +@property (strong, nonatomic) UIWindow *window; +@property (assign, nonatomic) UIWindow *windowPrevious; +@property (assign, nonatomic) UIWindow *windowNotice; + +@property (strong, nonatomic) UIView *view; + +@property (strong, nonatomic) LGAlertViewViewController *viewController; + +@property (strong, nonatomic) UIView *backgroundView; + +@property (strong, nonatomic) UIView *styleView; +@property (strong, nonatomic) UIScrollView *scrollView; +@property (strong, nonatomic) UITableView *tableView; + +@property (strong, nonatomic) NSString *title; +@property (strong, nonatomic) NSString *message; +@property (strong, nonatomic) UIView *innerView; +@property (strong, nonatomic) NSMutableArray *buttonTitles; +@property (strong, nonatomic) NSString *cancelButtonTitle; +@property (strong, nonatomic) NSString *destructiveButtonTitle; + +@property (strong, nonatomic) UILabel *titleLabel; +@property (strong, nonatomic) UILabel *messageLabel; +@property (strong, nonatomic) UIButton *destructiveButton; +@property (strong, nonatomic) UIButton *cancelButton; +@property (strong, nonatomic) UIButton *firstButton; +@property (strong, nonatomic) UIButton *secondButton; + +@property (strong, nonatomic) NSMutableArray *textFieldSeparatorsArray; + +@property (strong, nonatomic) UIView *separatorHorizontalView; +@property (strong, nonatomic) UIView *separatorVerticalView; + +@property (assign, nonatomic) CGPoint scrollViewCenterShowed; +@property (assign, nonatomic) CGPoint scrollViewCenterHidden; + +@property (assign, nonatomic) CGPoint cancelButtonCenterShowed; +@property (assign, nonatomic) CGPoint cancelButtonCenterHidden; + +@property (strong, nonatomic) UIActivityIndicatorView *activityIndicator; + +@property (strong, nonatomic) UIProgressView *progressView; +@property (strong, nonatomic) UILabel *progressLabel; + +@property (strong, nonatomic) NSString *progressLabelText; + +@property (assign, nonatomic) LGAlertViewStyle style; + +@property (assign, nonatomic) CGFloat keyboardHeight; + +- (void)layoutInvalidateWithSize:(CGSize)size; + +@end + +#pragma mark - + +@implementation UIWindow (LGAlertView) + +- (NSString *)className +{ + return NSStringFromClass([self class]); +} + +- (UIViewController *)currentViewController +{ + UIViewController *viewController = self.rootViewController; + + if (viewController.presentedViewController) + viewController = viewController.presentedViewController; + + return viewController; +} + +@end + +@implementation LGAlertViewViewController + +- (instancetype)initWithAlertView:(LGAlertView *)alertView +{ + self = [super init]; + if (self) + { + if ([UIDevice currentDevice].systemVersion.floatValue < 7.0) + self.wantsFullScreenLayout = YES; + + _alertView = alertView; + + self.view.backgroundColor = [UIColor clearColor]; + [self.view addSubview:_alertView.view]; + } + return self; +} + +- (BOOL)shouldAutorotate +{ + UIWindow *window = [UIApplication sharedApplication].delegate.window; + + return window.currentViewController.shouldAutorotate; +} + +- (NSUInteger)supportedInterfaceOrientations +{ + UIWindow *window = [UIApplication sharedApplication].delegate.window; + + return window.currentViewController.supportedInterfaceOrientations; +} + +#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_6_0 + +#pragma mark iOS <= 7 + +- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration +{ + [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; + + CGSize size = self.view.frame.size; + + if (UIInterfaceOrientationIsPortrait(toInterfaceOrientation)) + size = CGSizeMake(MIN(size.width, size.height), MAX(size.width, size.height)); + else + size = CGSizeMake(MAX(size.width, size.height), MIN(size.width, size.height)); + + [_alertView layoutInvalidateWithSize:size]; +} + +#endif + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_0 + +#pragma mark iOS == 8 + +- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator +{ + [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; + + [coordinator animateAlongsideTransition:^(id context) + { + [_alertView layoutInvalidateWithSize:size]; + } + completion:nil]; +} + +#endif + +@end + +@implementation LGAlertView + +- (instancetype)initWithTitle:(NSString *)title + message:(NSString *)message + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle +{ + self = [super init]; + if (self) + { + _title = title; + _message = message; + _buttonTitles = buttonTitles.mutableCopy; + _cancelButtonTitle = cancelButtonTitle; + _destructiveButtonTitle = destructiveButtonTitle; + + [self setupDefaults]; + } + return self; +} + +- (instancetype)initWithViewStyleWithTitle:(NSString *)title + message:(NSString *)message + view:(UIView *)view + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle +{ + self = [super init]; + if (self) + { + if ([view isKindOfClass:[UIScrollView class]]) + NSLog(@"LGFilterView: WARNING !!! view can not be subclass of UIScrollView !!!"); + + // ----- + + _title = title; + _message = message; + _innerView = view; + _buttonTitles = buttonTitles.mutableCopy; + _cancelButtonTitle = cancelButtonTitle; + _destructiveButtonTitle = destructiveButtonTitle; + + [self setupDefaults]; + } + return self; +} + +- (instancetype)initWithActivityIndicatorStyleWithTitle:(NSString *)title + message:(NSString *)message + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle +{ + self = [super init]; + if (self) + { + _title = title; + _message = message; + _buttonTitles = buttonTitles.mutableCopy; + _cancelButtonTitle = cancelButtonTitle; + _destructiveButtonTitle = destructiveButtonTitle; + + _style = LGAlertViewStyleActivityIndicator; + + [self setupDefaults]; + } + return self; +} + +- (instancetype)initWithProgressViewStyleWithTitle:(NSString *)title + message:(NSString *)message + progressLabelText:(NSString *)progressLabelText + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle +{ + self = [super init]; + if (self) + { + _title = title; + _message = message; + _buttonTitles = buttonTitles.mutableCopy; + _cancelButtonTitle = cancelButtonTitle; + _destructiveButtonTitle = destructiveButtonTitle; + _progressLabelText = progressLabelText; + + _style = LGAlertViewStyleProgressView; + + [self setupDefaults]; + } + return self; +} + +- (instancetype)initWithTextFieldsStyleWithTitle:(NSString *)title + message:(NSString *)message + numberOfTextFields:(NSUInteger)numberOfTextFields + textFieldsSetupHandler:(void(^)(UITextField *textField, NSUInteger index))textFieldsSetupHandler + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle +{ + self = [super init]; + if (self) + { + _title = title; + _message = message; + _buttonTitles = buttonTitles.mutableCopy; + _cancelButtonTitle = cancelButtonTitle; + _destructiveButtonTitle = destructiveButtonTitle; + + _style = LGAlertViewStyleTextFields; + + _textFieldsArray = [NSMutableArray new]; + _textFieldSeparatorsArray = [NSMutableArray new]; + + for (NSUInteger i=0; i)delegate +{ + self = [self initWithTitle:title + message:message + buttonTitles:buttonTitles + cancelButtonTitle:cancelButtonTitle + destructiveButtonTitle:destructiveButtonTitle]; + if (self) + { + _delegate = delegate; + } + return self; +} + +- (instancetype)initWithViewStyleWithTitle:(NSString *)title + message:(NSString *)message + view:(UIView *)view + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle + delegate:(id)delegate +{ + self = [self initWithViewStyleWithTitle:title + message:message + view:view + buttonTitles:buttonTitles + cancelButtonTitle:cancelButtonTitle + destructiveButtonTitle:destructiveButtonTitle]; + if (self) + { + _delegate = delegate; + } + return self; +} + +- (instancetype)initWithActivityIndicatorStyleWithTitle:(NSString *)title + message:(NSString *)message + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle + delegate:(id)delegate +{ + self = [self initWithActivityIndicatorStyleWithTitle:title + message:message + buttonTitles:buttonTitles + cancelButtonTitle:cancelButtonTitle + destructiveButtonTitle:destructiveButtonTitle]; + if (self) + { + _delegate = delegate; + } + return self; +} + +- (instancetype)initWithProgressViewStyleWithTitle:(NSString *)title + message:(NSString *)message + progressLabelText:(NSString *)progressLabelText + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle + delegate:(id)delegate +{ + self = [self initWithProgressViewStyleWithTitle:title + message:message + progressLabelText:progressLabelText + buttonTitles:buttonTitles + cancelButtonTitle:cancelButtonTitle + destructiveButtonTitle:destructiveButtonTitle]; + if (self) + { + _delegate = delegate; + } + return self; +} + +- (instancetype)initWithTextFieldsStyleWithTitle:(NSString *)title + message:(NSString *)message + numberOfTextFields:(NSUInteger)numberOfTextFields + textFieldsSetupHandler:(void(^)(UITextField *textField, NSUInteger index))textFieldsSetupHandler + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle + delegate:(id)delegate +{ + self = [self initWithTextFieldsStyleWithTitle:title + message:message + numberOfTextFields:numberOfTextFields + textFieldsSetupHandler:textFieldsSetupHandler + buttonTitles:buttonTitles + cancelButtonTitle:cancelButtonTitle + destructiveButtonTitle:destructiveButtonTitle]; + if (self) + { + _delegate = delegate; + } + return self; +} + ++ (instancetype)alertViewWithTitle:(NSString *)title + message:(NSString *)message + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle + delegate:(id)delegate +{ + return [[self alloc] initWithTitle:title + message:message + buttonTitles:buttonTitles + cancelButtonTitle:cancelButtonTitle + destructiveButtonTitle:destructiveButtonTitle + delegate:delegate]; +} + ++ (instancetype)alertViewWithViewStyleWithTitle:(NSString *)title + message:(NSString *)message + view:(UIView *)view + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle + delegate:(id)delegate +{ + return [[self alloc] initWithViewStyleWithTitle:title + message:message + view:view + buttonTitles:buttonTitles + cancelButtonTitle:cancelButtonTitle + destructiveButtonTitle:destructiveButtonTitle + delegate:delegate]; +} + ++ (instancetype)alertViewWithActivityIndicatorStyleWithTitle:(NSString *)title + message:(NSString *)message + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle + delegate:(id)delegate +{ + return [[self alloc] initWithActivityIndicatorStyleWithTitle:title + message:message + buttonTitles:buttonTitles + cancelButtonTitle:cancelButtonTitle + destructiveButtonTitle:destructiveButtonTitle + delegate:delegate]; +} + ++ (instancetype)alertViewWithProgressViewStyleWithTitle:(NSString *)title + message:(NSString *)message + progressLabelText:(NSString *)progressLabelText + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle + delegate:(id)delegate +{ + return [[self alloc] initWithProgressViewStyleWithTitle:title + message:message + progressLabelText:progressLabelText + buttonTitles:buttonTitles + cancelButtonTitle:cancelButtonTitle + destructiveButtonTitle:destructiveButtonTitle + delegate:delegate]; +} + ++ (instancetype)alertViewWithTextFieldsStyleWithTitle:(NSString *)title + message:(NSString *)message + numberOfTextFields:(NSUInteger)numberOfTextFields + textFieldsSetupHandler:(void(^)(UITextField *textField, NSUInteger index))textFieldsSetupHandler + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle + delegate:(id)delegate +{ + return [[self alloc] alertViewWithTextFieldsStyleWithTitle:title + message:message + numberOfTextFields:numberOfTextFields + textFieldsSetupHandler:textFieldsSetupHandler + buttonTitles:buttonTitles + cancelButtonTitle:cancelButtonTitle + destructiveButtonTitle:destructiveButtonTitle + delegate:delegate]; +} + +#pragma mark - + +- (void)setupDefaults +{ + _cancelOnTouch = YES; + + self.tintColor = [UIColor colorWithRed:0.f green:0.5 blue:1.f alpha:1.f]; + + _coverColor = [UIColor colorWithWhite:0.f alpha:0.5]; + + _backgroundColor = [UIColor whiteColor]; + _layerCornerRadius = 8.f; + _layerBorderColor = nil; + _layerBorderWidth = 0.f; + _layerShadowColor = nil; + _layerShadowRadius = 0.f; + + _titleTextColor = [UIColor blackColor]; + _titleTextAlignment = NSTextAlignmentCenter; + _titleFont = [UIFont boldSystemFontOfSize:18.f]; + + _messageTextColor = [UIColor blackColor]; + _messageTextAlignment = NSTextAlignmentCenter; + _messageFont = [UIFont systemFontOfSize:14.f]; + + _buttonsTitleColor = _tintColor; + _buttonsTitleColorHighlighted = [UIColor whiteColor]; + _buttonsTextAlignment = NSTextAlignmentCenter; + _buttonsFont = [UIFont systemFontOfSize:18.f]; + _buttonsNumberOfLines = 1; + _buttonsLineBreakMode = NSLineBreakByTruncatingMiddle; + _buttonsAdjustsFontSizeToFitWidth = YES; + _buttonsMinimumScaleFactor = 14.f/18.f; + _buttonsBackgroundColorHighlighted = _tintColor; + + _cancelButtonTitleColor = _tintColor; + _cancelButtonTitleColorHighlighted = [UIColor whiteColor]; + _cancelButtonTextAlignment = NSTextAlignmentCenter; + _cancelButtonFont = [UIFont boldSystemFontOfSize:18.f]; + _cancelButtonNumberOfLines = 1; + _cancelButtonLineBreakMode = NSLineBreakByTruncatingMiddle; + _cancelButtonAdjustsFontSizeToFitWidth = YES; + _cancelButtonMinimumScaleFactor = 14.f/18.f; + _cancelButtonBackgroundColorHighlighted = _tintColor; + + _destructiveButtonTitleColor = [UIColor redColor]; + _destructiveButtonTitleColorHighlighted = [UIColor whiteColor]; + _destructiveButtonTextAlignment = NSTextAlignmentCenter; + _destructiveButtonFont = [UIFont systemFontOfSize:18.f]; + _destructiveButtonNumberOfLines = 1; + _destructiveButtonLineBreakMode = NSLineBreakByTruncatingMiddle; + _destructiveButtonAdjustsFontSizeToFitWidth = YES; + _destructiveButtonMinimumScaleFactor = 14.f/18.f; + _destructiveButtonBackgroundColorHighlighted = [UIColor redColor]; + + _activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge; + _activityIndicatorViewColor = _tintColor; + + _progressViewProgressTintColor = _tintColor; + _progressViewTrackTintColor = [UIColor colorWithRed:0.8 green:0.8 blue:0.8 alpha:1.f]; + _progressViewProgressImage = nil; + _progressViewTrackImage = nil; + + _progressLabelTextColor = [UIColor blackColor]; + _progressLabelTextAlignment = NSTextAlignmentCenter; + _progressLabelFont = [UIFont systemFontOfSize:14.f]; + + self.colorful = YES; + + _separatorsColor = [UIColor colorWithRed:0.85 green:0.85 blue:0.85 alpha:1.f]; + + _indicatorStyle = UIScrollViewIndicatorStyleBlack; + + // ----- + + _view = [UIView new]; + _view.backgroundColor = [UIColor clearColor]; + _view.userInteractionEnabled = YES; + _view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + + _backgroundView = [UIView new]; + _backgroundView.alpha = 0.f; + _backgroundView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + [_view addSubview:_backgroundView]; + + // ----- + + UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(cancelAction:)]; + tapGesture.delegate = self; + [_backgroundView addGestureRecognizer:tapGesture]; + + // ----- + + _viewController = [[LGAlertViewViewController alloc] initWithAlertView:self]; + + _window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; + _window.hidden = YES; + _window.windowLevel = UIWindowLevelStatusBar+1; + _window.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + _window.opaque = NO; + _window.backgroundColor = [UIColor clearColor]; + _window.rootViewController = _viewController; +} + +#pragma mark - Dealloc + +- (void)dealloc +{ +#if DEBUG + NSLog(@"%s [Line %d]", __PRETTY_FUNCTION__, __LINE__); +#endif + + [self removeObservers]; +} + +#pragma mark - Observers + +- (void)addObservers +{ + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowVisibleChanged:) name:UIWindowDidBecomeVisibleNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowVisibleChanged:) name:UIWindowDidBecomeHiddenNotification object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardVisibleChanged:) name:UIKeyboardWillShowNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardVisibleChanged:) name:UIKeyboardWillHideNotification object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardFrameChanged:) name:UIKeyboardWillChangeFrameNotification object:nil]; +} + +- (void)removeObservers +{ + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIWindowDidBecomeVisibleNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIWindowDidBecomeHiddenNotification object:nil]; + + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil]; + + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillChangeFrameNotification object:nil]; +} + +#pragma mark - Window notifications + +- (void)windowVisibleChanged:(NSNotification *)notification +{ + //NSLog(@"windowVisibleChanged: %@", notification); + + UIWindow *window = notification.object; + + if ([NSStringFromClass([window class]) isEqualToString:@"UITextEffectsWindow"]) return; + + if (notification.name == UIWindowDidBecomeVisibleNotification) + { + if ([window isEqual:_windowPrevious]) + { + window.hidden = YES; + } + else if (![window isEqual:_window] && !_windowNotice) + { + _windowNotice = window; + + _window.hidden = YES; + } + } + else if (notification.name == UIWindowDidBecomeHiddenNotification) + { + __weak UIView *view = window.subviews.lastObject; + + if (![window isEqual:_window] && [window isEqual:_windowNotice]) + { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^(void) + { + if (!view) + { + _windowNotice = nil; + + [_window makeKeyAndVisible]; + } + }); + } + } +} + +#pragma mark - Keyboard notifications + +- (void)keyboardVisibleChanged:(NSNotification *)notification +{ + [LGAlertView keyboardAnimateWithNotificationUserInfo:notification.userInfo + animations:^(CGFloat keyboardHeight) + { + if ([notification.name isEqualToString:UIKeyboardWillShowNotification]) + _keyboardHeight = keyboardHeight; + else + _keyboardHeight = 0.f; + + [self layoutInvalidateWithSize:_view.frame.size]; + }]; +} + +- (void)keyboardFrameChanged:(NSNotification *)notification +{ + //NSLog(@"%@", notification); + + if ([notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue] == 0.f) + _keyboardHeight = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height; +} + +#pragma mark - UITextField Delegate + +- (BOOL)textFieldShouldReturn:(LGAlertViewTextField *)textField +{ + if (textField.returnKeyType == UIReturnKeyNext) + { + if (_textFieldsArray.count > textField.tag+1) + { + LGAlertViewTextField *nextTextField = _textFieldsArray[textField.tag+1]; + [nextTextField becomeFirstResponder]; + } + } + else if (textField.returnKeyType == UIReturnKeyDone) + { + [textField resignFirstResponder]; + } + + return YES; +} + +#pragma mark - Setters and Getters + +- (void)setColorful:(BOOL)colorful +{ + _colorful = colorful; + + if (_colorful) + { + _buttonsTitleColorHighlighted = [UIColor whiteColor]; + _buttonsBackgroundColorHighlighted = _tintColor; + + _cancelButtonTitleColorHighlighted = [UIColor whiteColor]; + _cancelButtonBackgroundColorHighlighted = _tintColor; + + _destructiveButtonTitleColorHighlighted = [UIColor whiteColor]; + _destructiveButtonBackgroundColorHighlighted = [UIColor redColor]; + } + else + { + _buttonsTitleColorHighlighted = _buttonsTitleColor; + _buttonsBackgroundColorHighlighted = [UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:1.f]; + + _cancelButtonTitleColorHighlighted = _cancelButtonTitleColor; + _cancelButtonBackgroundColorHighlighted = [UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:1.f]; + + _destructiveButtonTitleColorHighlighted = _destructiveButtonTitleColor; + _destructiveButtonBackgroundColorHighlighted = [UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:1.f]; + } +} + +- (void)setTintColor:(UIColor *)tintColor +{ + _tintColor = tintColor; + + _buttonsBackgroundColorHighlighted = _tintColor; + _cancelButtonBackgroundColorHighlighted = _tintColor; + + _buttonsTitleColor = _tintColor; + _cancelButtonTitleColor = _tintColor; + + if (!self.isColorful) + { + _buttonsTitleColorHighlighted = _tintColor; + _cancelButtonTitleColorHighlighted = _tintColor; + } + + _activityIndicatorViewColor = _tintColor; + _progressViewProgressTintColor = _tintColor; +} + +- (void)setProgress:(float)progress progressLabelText:(NSString *)progressLabelText +{ + if (_style == LGAlertViewStyleProgressView) + { + [_progressView setProgress:progress animated:YES]; + + _progressLabel.text = progressLabelText; + } +} + +- (float)progress +{ + float progress = 0.f; + + if (_style == LGAlertViewStyleProgressView) + progress = _progressView.progress; + + return progress; +} + +#pragma mark - Table View Data Source + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return _buttonTitles.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + LGAlertViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; + + cell.title = _buttonTitles[indexPath.row]; + + if (_destructiveButtonTitle.length && indexPath.row == 0) + { + cell.titleColor = _destructiveButtonTitleColor; + cell.titleColorHighlighted = _destructiveButtonTitleColorHighlighted; + cell.backgroundColorHighlighted = _destructiveButtonBackgroundColorHighlighted; + cell.separatorVisible = (indexPath.row != _buttonTitles.count-1); + cell.separatorColor_ = _separatorsColor; + cell.textAlignment = _destructiveButtonTextAlignment; + cell.font = _destructiveButtonFont; + cell.numberOfLines = _destructiveButtonNumberOfLines; + cell.lineBreakMode = _destructiveButtonLineBreakMode; + cell.adjustsFontSizeToFitWidth = _destructiveButtonAdjustsFontSizeToFitWidth; + cell.minimumScaleFactor = _destructiveButtonMinimumScaleFactor; + } + else if (_cancelButtonTitle.length && indexPath.row == _buttonTitles.count-1) + { + cell.titleColor = _cancelButtonTitleColor; + cell.titleColorHighlighted = _cancelButtonTitleColorHighlighted; + cell.backgroundColorHighlighted = _cancelButtonBackgroundColorHighlighted; + cell.separatorVisible = NO; + cell.separatorColor_ = _separatorsColor; + cell.textAlignment = _cancelButtonTextAlignment; + cell.font = _cancelButtonFont; + cell.numberOfLines = _cancelButtonNumberOfLines; + cell.lineBreakMode = _cancelButtonLineBreakMode; + cell.adjustsFontSizeToFitWidth = _cancelButtonAdjustsFontSizeToFitWidth; + cell.minimumScaleFactor = _cancelButtonMinimumScaleFactor; + } + else + { + cell.titleColor = _buttonsTitleColor; + cell.titleColorHighlighted = _buttonsTitleColorHighlighted; + cell.backgroundColorHighlighted = _buttonsBackgroundColorHighlighted; + cell.separatorVisible = (indexPath.row != _buttonTitles.count-1); + cell.separatorColor_ = _separatorsColor; + cell.textAlignment = _buttonsTextAlignment; + cell.font = _buttonsFont; + cell.numberOfLines = _buttonsNumberOfLines; + cell.lineBreakMode = _buttonsLineBreakMode; + cell.adjustsFontSizeToFitWidth = _buttonsAdjustsFontSizeToFitWidth; + cell.minimumScaleFactor = _buttonsMinimumScaleFactor; + } + + return cell; +} + +#pragma mark - Table View Delegate + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath +{ + if (_destructiveButtonTitle.length && indexPath.row == 0 && _destructiveButtonNumberOfLines != 1) + { + NSString *title = _buttonTitles[indexPath.row]; + + UILabel *label = [UILabel new]; + label.text = title; + label.textAlignment = _destructiveButtonTextAlignment; + label.font = _destructiveButtonFont; + label.numberOfLines = _destructiveButtonNumberOfLines; + label.lineBreakMode = _destructiveButtonLineBreakMode; + label.adjustsFontSizeToFitWidth = _destructiveButtonAdjustsFontSizeToFitWidth; + label.minimumScaleFactor = _destructiveButtonMinimumScaleFactor; + + CGSize size = [label sizeThatFits:CGSizeMake(tableView.frame.size.width-kLGAlertViewInnerMarginW*2, CGFLOAT_MAX)]; + size.height += kLGAlertViewButtonTitleMarginH*2; + + if (size.height < kLGAlertViewButtonHeight) + size.height = kLGAlertViewButtonHeight; + + return size.height; + } + else if (_cancelButtonTitle.length && indexPath.row == _buttonTitles.count-1 && _cancelButtonNumberOfLines != 1) + { + NSString *title = _buttonTitles[indexPath.row]; + + UILabel *label = [UILabel new]; + label.text = title; + label.textAlignment = _cancelButtonTextAlignment; + label.font = _cancelButtonFont; + label.numberOfLines = _cancelButtonNumberOfLines; + label.lineBreakMode = _cancelButtonLineBreakMode; + label.adjustsFontSizeToFitWidth = _cancelButtonAdjustsFontSizeToFitWidth; + label.minimumScaleFactor = _cancelButtonMinimumScaleFactor; + + CGSize size = [label sizeThatFits:CGSizeMake(tableView.frame.size.width-kLGAlertViewInnerMarginW*2, CGFLOAT_MAX)]; + size.height += kLGAlertViewButtonTitleMarginH*2; + + if (size.height < kLGAlertViewButtonHeight) + size.height = kLGAlertViewButtonHeight; + + return size.height; + } + else if (_buttonsNumberOfLines != 1) + { + NSString *title = _buttonTitles[indexPath.row]; + + UILabel *label = [UILabel new]; + label.text = title; + label.textAlignment = _buttonsTextAlignment; + label.font = _buttonsFont; + label.numberOfLines = _buttonsNumberOfLines; + label.lineBreakMode = _buttonsLineBreakMode; + label.adjustsFontSizeToFitWidth = _buttonsAdjustsFontSizeToFitWidth; + label.minimumScaleFactor = _buttonsMinimumScaleFactor; + + CGSize size = [label sizeThatFits:CGSizeMake(tableView.frame.size.width-kLGAlertViewInnerMarginW*2, CGFLOAT_MAX)]; + size.height += kLGAlertViewButtonTitleMarginH*2; + + if (size.height < kLGAlertViewButtonHeight) + size.height = kLGAlertViewButtonHeight; + + return size.height; + } + else return kLGAlertViewButtonHeight; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + if (_destructiveButtonTitle.length && indexPath.row == 0) + { + [self destructiveAction:nil]; + } + else if (_cancelButtonTitle.length && indexPath.row == _buttonTitles.count-1) + { + [self cancelAction:nil]; + } + else + { + [self dismissAnimated:YES completionHandler:nil]; + + NSUInteger index = indexPath.row; + if (_destructiveButtonTitle.length) index--; + + NSString *title = _buttonTitles[indexPath.row]; + + if (_actionHandler) _actionHandler(self, title, index); + + if (_delegate && [_delegate respondsToSelector:@selector(alertView:buttonPressedWithTitle:index:)]) + [_delegate alertView:self buttonPressedWithTitle:title index:index]; + } +} + +#pragma mark - + +- (void)showAnimated:(BOOL)animated completionHandler:(void(^)())completionHandler +{ + if (self.isShowing) return; + + CGSize size = _viewController.view.frame.size; + + if (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation)) + size = CGSizeMake(MIN(size.width, size.height), MAX(size.width, size.height)); + else + size = CGSizeMake(MAX(size.width, size.height), MIN(size.width, size.height)); + + [self subviewsInvalidateWithSize:size]; + [self layoutInvalidateWithSize:size]; + + _showing = YES; + + // ----- + + [self addObservers]; + + // ----- + + UIWindow *windowApp = [UIApplication sharedApplication].delegate.window; + _windowPrevious = [UIApplication sharedApplication].keyWindow; + + if (![windowApp isEqual:_windowPrevious]) + _windowPrevious.hidden = YES; + + [_window makeKeyAndVisible]; + + // ----- + + [[NSNotificationCenter defaultCenter] postNotificationName:kLGAlertViewWillShowNotification object:self userInfo:nil]; + + if (_willShowHandler) _willShowHandler(self); + + if (_delegate && [_delegate respondsToSelector:@selector(alertViewWillShow:)]) + [_delegate alertViewWillShow:self]; + + // ----- + + if (animated) + { + [LGAlertView animateStandartWithAnimations:^(void) + { + [self showAnimations]; + } + completion:^(BOOL finished) + { + [self showComplete]; + + if (completionHandler) completionHandler(); + }]; + } + else + { + [self showAnimations]; + + [self showComplete]; + + if (completionHandler) completionHandler(); + } +} + +- (void)showAnimations +{ + _backgroundView.alpha = 1.f; + + _scrollView.transform = CGAffineTransformIdentity; + _scrollView.alpha = 1.f; + + _styleView.transform = CGAffineTransformIdentity; + _styleView.alpha = 1.f; +} + +- (void)showComplete +{ + [[NSNotificationCenter defaultCenter] postNotificationName:kLGAlertViewDidShowNotification object:self userInfo:nil]; + + if (_didShowHandler) _didShowHandler(self); + + if (_delegate && [_delegate respondsToSelector:@selector(alertViewDidShow:)]) + [_delegate alertViewDidShow:self]; +} + +- (void)dismissAnimated:(BOOL)animated completionHandler:(void (^)())completionHandler +{ + if (!self.isShowing) return; + + _showing = NO; + + [self removeObservers]; + + [_view endEditing:YES]; + + // ----- + + [[NSNotificationCenter defaultCenter] postNotificationName:kLGAlertViewWillDismissNotification object:self userInfo:nil]; + + if (_willDismissHandler) _willDismissHandler(self); + + if (_delegate && [_delegate respondsToSelector:@selector(alertViewWillDismiss:)]) + [_delegate alertViewWillDismiss:self]; + + // ----- + + if (animated) + { + [LGAlertView animateStandartWithAnimations:^(void) + { + [self dismissAnimations]; + } + completion:^(BOOL finished) + { + [self dismissComplete]; + + if (completionHandler) completionHandler(); + }]; + } + else + { + [self dismissAnimations]; + + [self dismissComplete]; + + if (completionHandler) completionHandler(); + } +} + +- (void)dismissAnimations +{ + _backgroundView.alpha = 0.f; + + _scrollView.transform = CGAffineTransformMakeScale(0.95, 0.95); + _scrollView.alpha = 0.f; + + _styleView.transform = CGAffineTransformMakeScale(0.95, 0.95); + _styleView.alpha = 0.f; +} + +- (void)dismissComplete +{ + _window.hidden = YES; + + [_windowPrevious makeKeyAndVisible]; + + self.viewController = nil; + self.window = nil; + + // ----- + + [[NSNotificationCenter defaultCenter] postNotificationName:kLGAlertViewDidDismissNotification object:self userInfo:nil]; + + if (_didDismissHandler) _didDismissHandler(self); + + if (_delegate && [_delegate respondsToSelector:@selector(alertViewDidDismiss:)]) + [_delegate alertViewDidDismiss:self]; +} + +#pragma mark - + +- (void)subviewsInvalidateWithSize:(CGSize)size +{ + CGFloat widthMax = kLGAlertViewWidth; + + if (_widthMax) + { + widthMax = MIN(size.width, size.height)-kLGAlertViewMargin*2; + + if (_widthMax < widthMax) + widthMax = _widthMax; + } + + // ----- + + if (!self.isExists) + { + _exists = YES; + + _backgroundView.backgroundColor = _coverColor; + + _styleView = [UIView new]; + _styleView.backgroundColor = _backgroundColor; + _styleView.layer.masksToBounds = NO; + _styleView.layer.cornerRadius = _layerCornerRadius; + _styleView.layer.borderColor = _layerBorderColor.CGColor; + _styleView.layer.borderWidth = _layerBorderWidth; + _styleView.layer.shadowColor = _layerShadowColor.CGColor; + _styleView.layer.shadowRadius = _layerShadowRadius; + _styleView.layer.shadowOpacity = 1.f; + _styleView.layer.shadowOffset = CGSizeZero; + [_view addSubview:_styleView]; + + _scrollView = [UIScrollView new]; + _scrollView.backgroundColor = [UIColor clearColor]; + _scrollView.indicatorStyle = _indicatorStyle; + _scrollView.alwaysBounceVertical = NO; + _scrollView.layer.masksToBounds = YES; + _scrollView.layer.cornerRadius = _layerCornerRadius; + [_view addSubview:_scrollView]; + + CGFloat offsetY = 0.f; + + if (_title.length) + { + _titleLabel = [UILabel new]; + _titleLabel.text = _title; + _titleLabel.textColor = _titleTextColor; + _titleLabel.textAlignment = _titleTextAlignment; + _titleLabel.numberOfLines = 0; + _titleLabel.lineBreakMode = NSLineBreakByWordWrapping; + _titleLabel.backgroundColor = [UIColor clearColor]; + _titleLabel.font = _titleFont; + + CGSize titleLabelSize = [_titleLabel sizeThatFits:CGSizeMake(widthMax-kLGAlertViewInnerMarginW*2, CGFLOAT_MAX)]; + CGRect titleLabelFrame = CGRectMake(kLGAlertViewInnerMarginW, kLGAlertViewInnerMarginH, widthMax-kLGAlertViewInnerMarginW*2, titleLabelSize.height); + if ([UIScreen mainScreen].scale == 1.f) + titleLabelFrame = CGRectIntegral(titleLabelFrame); + + _titleLabel.frame = titleLabelFrame; + [_scrollView addSubview:_titleLabel]; + + offsetY = _titleLabel.frame.origin.y+_titleLabel.frame.size.height; + } + + if (_message.length) + { + _messageLabel = [UILabel new]; + _messageLabel.text = _message; + _messageLabel.textColor = _messageTextColor; + _messageLabel.textAlignment = _messageTextAlignment; + _messageLabel.numberOfLines = 0; + _messageLabel.lineBreakMode = NSLineBreakByWordWrapping; + _messageLabel.backgroundColor = [UIColor clearColor]; + _messageLabel.font = _messageFont; + + if (!offsetY) offsetY = kLGAlertViewInnerMarginH/2; + + CGSize messageLabelSize = [_messageLabel sizeThatFits:CGSizeMake(widthMax-kLGAlertViewInnerMarginW*2, CGFLOAT_MAX)]; + CGRect messageLabelFrame = CGRectMake(kLGAlertViewInnerMarginW, offsetY+kLGAlertViewInnerMarginH/2, widthMax-kLGAlertViewInnerMarginW*2, messageLabelSize.height); + if ([UIScreen mainScreen].scale == 1.f) + messageLabelFrame = CGRectIntegral(messageLabelFrame); + + _messageLabel.frame = messageLabelFrame; + [_scrollView addSubview:_messageLabel]; + + offsetY = _messageLabel.frame.origin.y+_messageLabel.frame.size.height; + } + + if (_innerView) + { + CGRect innerViewFrame = CGRectMake(widthMax/2-_innerView.frame.size.width/2, offsetY+kLGAlertViewInnerMarginH, _innerView.frame.size.width, _innerView.frame.size.height); + if ([UIScreen mainScreen].scale == 1.f) + innerViewFrame = CGRectIntegral(innerViewFrame); + + _innerView.frame = innerViewFrame; + [_scrollView addSubview:_innerView]; + + offsetY = _innerView.frame.origin.y+_innerView.frame.size.height; + } + else if (_style == LGAlertViewStyleActivityIndicator) + { + _activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:_activityIndicatorViewStyle]; + _activityIndicator.color = _activityIndicatorViewColor; + _activityIndicator.backgroundColor = [UIColor clearColor]; + [_activityIndicator startAnimating]; + + CGRect activityIndicatorFrame = CGRectMake(widthMax/2-_activityIndicator.frame.size.width/2, offsetY+kLGAlertViewInnerMarginH, _activityIndicator.frame.size.width, _activityIndicator.frame.size.height); + if ([UIScreen mainScreen].scale == 1.f) + activityIndicatorFrame = CGRectIntegral(activityIndicatorFrame); + + _activityIndicator.frame = activityIndicatorFrame; + [_scrollView addSubview:_activityIndicator]; + + offsetY = _activityIndicator.frame.origin.y+_activityIndicator.frame.size.height; + } + else if (_style == LGAlertViewStyleProgressView) + { + _progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault]; + _progressView.backgroundColor = [UIColor clearColor]; + _progressView.progressTintColor = _progressViewProgressTintColor; + _progressView.trackTintColor = _progressViewTrackTintColor; + if (_progressViewProgressImage) + _progressView.progressImage = _progressViewProgressImage; + if (_progressViewTrackImage) + _progressView.trackImage = _progressViewTrackImage; + + CGRect progressViewFrame = CGRectMake(kLGAlertViewInnerMarginW, offsetY+kLGAlertViewInnerMarginH, widthMax-kLGAlertViewInnerMarginW*2, _progressView.frame.size.height); + if ([UIScreen mainScreen].scale == 1.f) + progressViewFrame = CGRectIntegral(progressViewFrame); + + _progressView.frame = progressViewFrame; + [_scrollView addSubview:_progressView]; + + offsetY = _progressView.frame.origin.y+_progressView.frame.size.height; + + _progressLabel = [UILabel new]; + _progressLabel.text = _progressLabelText; + _progressLabel.textColor = _progressLabelTextColor; + _progressLabel.textAlignment = _progressLabelTextAlignment; + _progressLabel.numberOfLines = 1; + _progressLabel.backgroundColor = [UIColor clearColor]; + _progressLabel.font = _progressLabelFont; + + CGSize progressLabelSize = [_progressLabel sizeThatFits:CGSizeMake(widthMax-kLGAlertViewInnerMarginW*2, CGFLOAT_MAX)]; + CGRect progressLabelFrame = CGRectMake(kLGAlertViewInnerMarginW, offsetY+kLGAlertViewInnerMarginH/2, widthMax-kLGAlertViewInnerMarginW*2, progressLabelSize.height); + if ([UIScreen mainScreen].scale == 1.f) + progressLabelFrame = CGRectIntegral(progressLabelFrame); + + _progressLabel.frame = progressLabelFrame; + [_scrollView addSubview:_progressLabel]; + + offsetY = _progressLabel.frame.origin.y+_progressLabel.frame.size.height; + } + else if (_style == LGAlertViewStyleTextFields) + { + for (NSUInteger i=0; i<_textFieldsArray.count; i++) + { + UIView *separatorView = _textFieldSeparatorsArray[i]; + separatorView.backgroundColor = _separatorsColor; + + CGRect separatorViewFrame = CGRectMake(0.f, offsetY+(i == 0 ? kLGAlertViewInnerMarginH : 0.f), widthMax, kLGAlertViewSeparatorHeight); + if ([UIScreen mainScreen].scale == 1.f) + separatorViewFrame = CGRectIntegral(separatorViewFrame); + + separatorView.frame = separatorViewFrame; + [_scrollView addSubview:separatorView]; + + offsetY = separatorView.frame.origin.y+separatorView.frame.size.height; + + // ----- + + LGAlertViewTextField *textField = _textFieldsArray[i]; + + CGRect textFieldFrame = CGRectMake(0.f, offsetY, widthMax, kLGAlertViewTextFieldHeight); + if ([UIScreen mainScreen].scale == 1.f) + textFieldFrame = CGRectIntegral(textFieldFrame); + + textField.frame = textFieldFrame; + [_scrollView addSubview:textField]; + + offsetY = textField.frame.origin.y+textField.frame.size.height; + } + + offsetY -= kLGAlertViewInnerMarginH; + } + + NSUInteger numberOfButtons = _buttonTitles.count; + + if (_destructiveButtonTitle.length) + numberOfButtons++; + if (_cancelButtonTitle.length) + numberOfButtons++; + + BOOL showTable = NO; + + if (numberOfButtons == 2) + { + if (_destructiveButtonTitle.length) + { + _destructiveButton = [UIButton new]; + _destructiveButton.backgroundColor = [UIColor clearColor]; + _destructiveButton.titleLabel.numberOfLines = _destructiveButtonNumberOfLines; + _destructiveButton.titleLabel.lineBreakMode = _destructiveButtonLineBreakMode; + _destructiveButton.titleLabel.adjustsFontSizeToFitWidth = _destructiveButtonAdjustsFontSizeToFitWidth; + _destructiveButton.titleLabel.minimumScaleFactor = _destructiveButtonMinimumScaleFactor; + _destructiveButton.titleLabel.font = _destructiveButtonFont; + [_destructiveButton setTitle:_destructiveButtonTitle forState:UIControlStateNormal]; + [_destructiveButton setTitleColor:_destructiveButtonTitleColor forState:UIControlStateNormal]; + [_destructiveButton setTitleColor:_destructiveButtonTitleColorHighlighted forState:UIControlStateHighlighted]; + [_destructiveButton setTitleColor:_destructiveButtonTitleColorHighlighted forState:UIControlStateSelected]; + [_destructiveButton setBackgroundImage:[LGAlertView image1x1WithColor:_destructiveButtonBackgroundColorHighlighted] forState:UIControlStateHighlighted]; + [_destructiveButton setBackgroundImage:[LGAlertView image1x1WithColor:_destructiveButtonBackgroundColorHighlighted] forState:UIControlStateSelected]; + _destructiveButton.contentEdgeInsets = UIEdgeInsetsMake(kLGAlertViewButtonTitleMarginH, kLGAlertViewInnerMarginW, kLGAlertViewButtonTitleMarginH, kLGAlertViewInnerMarginW); + _destructiveButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; + if (_destructiveButtonTextAlignment == NSTextAlignmentCenter) + _destructiveButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter; + else if (_destructiveButtonTextAlignment == NSTextAlignmentLeft) + _destructiveButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; + else if (_destructiveButtonTextAlignment == NSTextAlignmentRight) + _destructiveButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight; + [_destructiveButton addTarget:self action:@selector(destructiveAction:) forControlEvents:UIControlEventTouchUpInside]; + + CGSize size = [_destructiveButton sizeThatFits:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)]; + + if (size.width > kLGAlertViewWidth/2) + showTable = YES; + } + + if (_cancelButtonTitle.length && !showTable) + { + _cancelButton = [UIButton new]; + _cancelButton.backgroundColor = [UIColor clearColor]; + _cancelButton.titleLabel.numberOfLines = _cancelButtonNumberOfLines; + _cancelButton.titleLabel.lineBreakMode = _cancelButtonLineBreakMode; + _cancelButton.titleLabel.adjustsFontSizeToFitWidth = _cancelButtonAdjustsFontSizeToFitWidth; + _cancelButton.titleLabel.minimumScaleFactor = _cancelButtonMinimumScaleFactor; + _cancelButton.titleLabel.font = _cancelButtonFont; + [_cancelButton setTitle:_cancelButtonTitle forState:UIControlStateNormal]; + [_cancelButton setTitleColor:_cancelButtonTitleColor forState:UIControlStateNormal]; + [_cancelButton setTitleColor:_cancelButtonTitleColorHighlighted forState:UIControlStateHighlighted]; + [_cancelButton setTitleColor:_cancelButtonTitleColorHighlighted forState:UIControlStateSelected]; + [_cancelButton setBackgroundImage:[LGAlertView image1x1WithColor:_cancelButtonBackgroundColorHighlighted] forState:UIControlStateHighlighted]; + [_cancelButton setBackgroundImage:[LGAlertView image1x1WithColor:_cancelButtonBackgroundColorHighlighted] forState:UIControlStateSelected]; + _cancelButton.contentEdgeInsets = UIEdgeInsetsMake(kLGAlertViewButtonTitleMarginH, kLGAlertViewInnerMarginW, kLGAlertViewButtonTitleMarginH, kLGAlertViewInnerMarginW); + _cancelButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; + if (_cancelButtonTextAlignment == NSTextAlignmentCenter) + _cancelButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter; + else if (_cancelButtonTextAlignment == NSTextAlignmentLeft) + _cancelButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; + else if (_cancelButtonTextAlignment == NSTextAlignmentRight) + _cancelButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight; + [_cancelButton addTarget:self action:@selector(cancelAction:) forControlEvents:UIControlEventTouchUpInside]; + + CGSize size = [_cancelButton sizeThatFits:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)]; + + if (size.width > kLGAlertViewWidth/2) + showTable = YES; + } + + if (_buttonTitles.count > 0 && !showTable) + { + _firstButton = [UIButton new]; + _firstButton.backgroundColor = [UIColor clearColor]; + _firstButton.titleLabel.numberOfLines = _buttonsNumberOfLines; + _firstButton.titleLabel.lineBreakMode = _buttonsLineBreakMode; + _firstButton.titleLabel.adjustsFontSizeToFitWidth = _buttonsAdjustsFontSizeToFitWidth; + _firstButton.titleLabel.minimumScaleFactor = _buttonsMinimumScaleFactor; + _firstButton.titleLabel.font = _buttonsFont; + [_firstButton setTitle:_buttonTitles[0] forState:UIControlStateNormal]; + [_firstButton setTitleColor:_buttonsTitleColor forState:UIControlStateNormal]; + [_firstButton setTitleColor:_buttonsTitleColorHighlighted forState:UIControlStateHighlighted]; + [_firstButton setTitleColor:_buttonsTitleColorHighlighted forState:UIControlStateSelected]; + [_firstButton setBackgroundImage:[LGAlertView image1x1WithColor:_buttonsBackgroundColorHighlighted] forState:UIControlStateHighlighted]; + [_firstButton setBackgroundImage:[LGAlertView image1x1WithColor:_buttonsBackgroundColorHighlighted] forState:UIControlStateSelected]; + _firstButton.contentEdgeInsets = UIEdgeInsetsMake(kLGAlertViewButtonTitleMarginH, kLGAlertViewInnerMarginW, kLGAlertViewButtonTitleMarginH, kLGAlertViewInnerMarginW); + _firstButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; + if (_buttonsTextAlignment == NSTextAlignmentCenter) + _firstButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter; + else if (_buttonsTextAlignment == NSTextAlignmentLeft) + _firstButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; + else if (_buttonsTextAlignment == NSTextAlignmentRight) + _firstButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight; + [_firstButton addTarget:self action:@selector(firstButtonAction) forControlEvents:UIControlEventTouchUpInside]; + + CGSize size = [_firstButton sizeThatFits:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)]; + + if (size.width > kLGAlertViewWidth/2) + showTable = YES; + + if (_buttonTitles.count > 1 && !showTable) + { + _secondButton = [UIButton new]; + _secondButton.backgroundColor = [UIColor clearColor]; + _secondButton.titleLabel.numberOfLines = _buttonsNumberOfLines; + _secondButton.titleLabel.lineBreakMode = _buttonsLineBreakMode; + _secondButton.titleLabel.adjustsFontSizeToFitWidth = _buttonsAdjustsFontSizeToFitWidth; + _secondButton.titleLabel.minimumScaleFactor = _buttonsMinimumScaleFactor; + _secondButton.titleLabel.font = _buttonsFont; + [_secondButton setTitle:_buttonTitles[1] forState:UIControlStateNormal]; + [_secondButton setTitleColor:_buttonsTitleColor forState:UIControlStateNormal]; + [_secondButton setTitleColor:_buttonsTitleColorHighlighted forState:UIControlStateHighlighted]; + [_secondButton setTitleColor:_buttonsTitleColorHighlighted forState:UIControlStateSelected]; + [_secondButton setBackgroundImage:[LGAlertView image1x1WithColor:_buttonsBackgroundColorHighlighted] forState:UIControlStateHighlighted]; + [_secondButton setBackgroundImage:[LGAlertView image1x1WithColor:_buttonsBackgroundColorHighlighted] forState:UIControlStateSelected]; + _secondButton.contentEdgeInsets = UIEdgeInsetsMake(kLGAlertViewButtonTitleMarginH, kLGAlertViewInnerMarginW, kLGAlertViewButtonTitleMarginH, kLGAlertViewInnerMarginW); + _secondButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; + if (_buttonsTextAlignment == NSTextAlignmentCenter) + _secondButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter; + else if (_buttonsTextAlignment == NSTextAlignmentLeft) + _secondButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; + else if (_buttonsTextAlignment == NSTextAlignmentRight) + _secondButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight; + [_secondButton addTarget:self action:@selector(secondButtonAction) forControlEvents:UIControlEventTouchUpInside]; + + CGSize size = [_secondButton sizeThatFits:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)]; + + if (size.width > kLGAlertViewWidth/2) + showTable = YES; + } + } + + if (!showTable) + { + UIButton *firstButton = nil; + UIButton *secondButton = nil; + + if (_destructiveButton) + { + [_scrollView addSubview:_destructiveButton]; + + firstButton = _destructiveButton; + } + + if (_cancelButton) + { + [_scrollView addSubview:_cancelButton]; + + secondButton = _cancelButton; + } + + if (_firstButton) + { + [_scrollView addSubview:_firstButton]; + + if (!firstButton) firstButton = _firstButton; + else secondButton = _firstButton; + + if (_secondButton) + { + [_scrollView addSubview:_secondButton]; + + secondButton = _secondButton; + } + } + + // ----- + + if (offsetY) + { + _separatorHorizontalView = [UIView new]; + _separatorHorizontalView.backgroundColor = _separatorsColor; + + CGRect separatorHorizontalViewFrame = CGRectMake(0.f, offsetY+kLGAlertViewInnerMarginH, widthMax, kLGAlertViewSeparatorHeight); + if ([UIScreen mainScreen].scale == 1.f) + separatorHorizontalViewFrame = CGRectIntegral(separatorHorizontalViewFrame); + + _separatorHorizontalView.frame = separatorHorizontalViewFrame; + [_scrollView addSubview:_separatorHorizontalView]; + + offsetY = _separatorHorizontalView.frame.origin.y+_separatorHorizontalView.frame.size.height; + } + + // ----- + + _separatorVerticalView = [UIView new]; + _separatorVerticalView.backgroundColor = _separatorsColor; + + CGRect separatorVerticalViewFrame = CGRectMake(widthMax/2, offsetY, kLGAlertViewSeparatorHeight, MAX(UIScreen.mainScreen.bounds.size.width, UIScreen.mainScreen.bounds.size.height)); + if ([UIScreen mainScreen].scale == 1.f) + separatorVerticalViewFrame = CGRectIntegral(separatorVerticalViewFrame); + + _separatorVerticalView.frame = separatorVerticalViewFrame; + [_scrollView addSubview:_separatorVerticalView]; + + // ----- + + CGRect firstButtonFrame = CGRectMake(0.f, offsetY, widthMax/2, kLGAlertViewButtonHeight); + if ([UIScreen mainScreen].scale == 1.f) + firstButtonFrame = CGRectIntegral(firstButtonFrame); + firstButton.frame = firstButtonFrame; + + CGRect secondButtonFrame = CGRectMake(widthMax/2+kLGAlertViewSeparatorHeight, offsetY, widthMax/2-kLGAlertViewSeparatorHeight, kLGAlertViewButtonHeight); + if ([UIScreen mainScreen].scale == 1.f) + secondButtonFrame = CGRectIntegral(secondButtonFrame); + secondButton.frame = secondButtonFrame; + + offsetY = firstButton.frame.origin.y+firstButton.frame.size.height; + } + } + else showTable = YES; + + if (showTable) + { + if (!_buttonTitles) + _buttonTitles = [NSMutableArray new]; + + if (_destructiveButtonTitle.length) + [_buttonTitles insertObject:_destructiveButtonTitle atIndex:0]; + + if (_cancelButtonTitle.length) + [_buttonTitles addObject:_cancelButtonTitle]; + + _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain]; + _tableView.clipsToBounds = NO; + _tableView.backgroundColor = [UIColor clearColor]; + _tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + _tableView.dataSource = self; + _tableView.delegate = self; + _tableView.scrollEnabled = NO; + [_tableView registerClass:[LGAlertViewCell class] forCellReuseIdentifier:@"cell"]; + _tableView.frame = CGRectMake(0.f, 0.f, widthMax, CGFLOAT_MAX); + [_tableView reloadData]; + + if (!offsetY) offsetY = -kLGAlertViewInnerMarginH; + else + { + _separatorHorizontalView = [UIView new]; + _separatorHorizontalView.backgroundColor = _separatorsColor; + + CGRect separatorTitleViewFrame = CGRectMake(0.f, 0.f, widthMax, kLGAlertViewSeparatorHeight); + if ([UIScreen mainScreen].scale == 1.f) + separatorTitleViewFrame = CGRectIntegral(separatorTitleViewFrame); + + _separatorHorizontalView.frame = separatorTitleViewFrame; + _tableView.tableHeaderView = _separatorHorizontalView; + } + + CGRect tableViewFrame = CGRectMake(0.f, offsetY+kLGAlertViewInnerMarginH, widthMax, _tableView.contentSize.height); + if ([UIScreen mainScreen].scale == 1.f) + tableViewFrame = CGRectIntegral(tableViewFrame); + _tableView.frame = tableViewFrame; + + [_scrollView addSubview:_tableView]; + + offsetY = _tableView.frame.origin.y+_tableView.frame.size.height; + } + + // ----- + + _scrollView.contentSize = CGSizeMake(widthMax, offsetY); + } +} + +- (void)layoutInvalidateWithSize:(CGSize)size +{ + _view.frame = CGRectMake(0.f, 0.f, size.width, size.height); + + _backgroundView.frame = CGRectMake(0.f, 0.f, size.width, size.height); + + // ----- + + CGFloat widthMax = kLGAlertViewWidth; + + if (_widthMax) + { + widthMax = MIN(size.width, size.height)-kLGAlertViewMargin*2; + + if (_widthMax < widthMax) + widthMax = _widthMax; + } + + // ----- + + CGFloat heightMax = size.height-_keyboardHeight-kLGAlertViewMargin; + + if (_heightMax && _heightMax < heightMax) + heightMax = _heightMax; + + if (_cancelOnTouch && + !_cancelButtonTitle.length && + size.width < widthMax+kLGAlertViewButtonHeight*2) + heightMax -= kLGAlertViewButtonHeight*2; + + if (_scrollView.contentSize.height < heightMax) + heightMax = _scrollView.contentSize.height; + + // ----- + + CGRect scrollViewFrame = CGRectZero; + CGAffineTransform scrollViewTransform = CGAffineTransformIdentity; + CGFloat scrollViewAlpha = 1.f; + + scrollViewFrame = CGRectMake(size.width/2-widthMax/2, size.height/2-_keyboardHeight/2-heightMax/2, widthMax, heightMax); + + if (!self.isShowing) + { + scrollViewTransform = CGAffineTransformMakeScale(1.2, 1.2); + + scrollViewAlpha = 0.f; + } + + if ([UIScreen mainScreen].scale == 1.f) + { + scrollViewFrame = CGRectIntegral(scrollViewFrame); + + if (_tableView) + { + if (_tableView.frame.origin.y+_tableView.frame.size.height < scrollViewFrame.size.height) + scrollViewFrame.size.height = _tableView.frame.origin.y+_tableView.frame.size.height; + } + else + { + if (_separatorVerticalView && _separatorVerticalView.frame.origin.y+kLGAlertViewButtonHeight < scrollViewFrame.size.height) + scrollViewFrame.size.height = _separatorVerticalView.frame.origin.y+kLGAlertViewButtonHeight; + } + } + + // ----- + + _scrollView.frame = scrollViewFrame; + _scrollView.transform = scrollViewTransform; + _scrollView.alpha = scrollViewAlpha; + + CGFloat borderWidth = _layerBorderWidth; + _styleView.frame = CGRectMake(scrollViewFrame.origin.x-borderWidth, scrollViewFrame.origin.y-borderWidth, scrollViewFrame.size.width+borderWidth*2, scrollViewFrame.size.height+borderWidth*2); + _styleView.transform = scrollViewTransform; + _styleView.alpha = scrollViewAlpha; +} + +#pragma mark - + +- (void)cancelAction:(id)sender +{ + BOOL onButton = [sender isKindOfClass:[UIButton class]]; + + if (sender) + { + if (onButton) + [(UIButton *)sender setSelected:YES]; + else if ([sender isKindOfClass:[UIGestureRecognizer class]] && !self.isCancelOnTouch) + return; + } + + [self dismissAnimated:YES completionHandler:nil]; + + // ----- + + if (_cancelHandler) _cancelHandler(self, onButton); + + if (_delegate && [_delegate respondsToSelector:@selector(alertViewCancelled:)]) + [_delegate alertViewCancelled:self]; +} + +- (void)destructiveAction:(id)sender +{ + if (sender && [sender isKindOfClass:[UIButton class]]) + [(UIButton *)sender setSelected:YES]; + + [self dismissAnimated:YES completionHandler:nil]; + + if (_destructiveHandler) _destructiveHandler(self); + + if (_delegate && [_delegate respondsToSelector:@selector(alertViewDestructiveButtonPressed:)]) + [_delegate alertViewDestructiveButtonPressed:self]; +} + +- (void)firstButtonAction +{ + _firstButton.selected = YES; + + [self dismissAnimated:YES completionHandler:nil]; + + NSUInteger index = 0; + + NSString *title = _buttonTitles[0]; + + if (_actionHandler) _actionHandler(self, title, index); + + if (_delegate && [_delegate respondsToSelector:@selector(alertView:buttonPressedWithTitle:index:)]) + [_delegate alertView:self buttonPressedWithTitle:title index:index]; +} + +- (void)secondButtonAction +{ + _secondButton.selected = YES; + + [self dismissAnimated:YES completionHandler:nil]; + + NSUInteger index = 1; + + NSString *title = _buttonTitles[1]; + + if (_actionHandler) _actionHandler(self, title, index); + + if (_delegate && [_delegate respondsToSelector:@selector(alertView:buttonPressedWithTitle:index:)]) + [_delegate alertView:self buttonPressedWithTitle:title index:index]; +} + +#pragma mark - Support + ++ (void)animateStandartWithAnimations:(void(^)())animations completion:(void(^)(BOOL finished))completion +{ + if ([UIDevice currentDevice].systemVersion.floatValue >= 7.0) + { + [UIView animateWithDuration:0.5 + delay:0.0 + usingSpringWithDamping:1.f + initialSpringVelocity:0.5 + options:0 + animations:animations + completion:completion]; + } + else + { + [UIView animateWithDuration:0.5*0.66 + delay:0.0 + options:UIViewAnimationOptionCurveEaseInOut + animations:animations + completion:completion]; + } +} + ++ (UIImage *)image1x1WithColor:(UIColor *)color +{ + CGRect rect = CGRectMake(0.f, 0.f, 1.f, 1.f); + + UIGraphicsBeginImageContext(rect.size); + + CGContextRef context = UIGraphicsGetCurrentContext(); + + CGContextSetFillColorWithColor(context, color.CGColor); + CGContextFillRect(context, rect); + + UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + return image; +} + ++ (void)keyboardAnimateWithNotificationUserInfo:(NSDictionary *)notificationUserInfo animations:(void(^)(CGFloat keyboardHeight))animations +{ + CGFloat keyboardHeight = (notificationUserInfo[@"UIKeyboardBoundsUserInfoKey"] ? [notificationUserInfo[@"UIKeyboardBoundsUserInfoKey"] CGRectValue].size.height : 0.f); + if (!keyboardHeight) + keyboardHeight = (notificationUserInfo[UIKeyboardFrameBeginUserInfoKey] ? [notificationUserInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue].size.height : 0.f); + if (!keyboardHeight) + keyboardHeight = (notificationUserInfo[UIKeyboardFrameEndUserInfoKey] ? [notificationUserInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height : 0.f); + if (!keyboardHeight) + return; + + NSTimeInterval animationDuration = [notificationUserInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]; + int animationCurve = [notificationUserInfo[UIKeyboardAnimationCurveUserInfoKey] intValue]; + + [UIView beginAnimations:nil context:NULL]; + [UIView setAnimationDuration:animationDuration]; + [UIView setAnimationCurve:animationCurve]; + + if (animations) animations(keyboardHeight); + + [UIView commitAnimations]; +} + +@end diff --git a/LGAlertView/LGAlertViewCell.h b/LGAlertView/LGAlertViewCell.h new file mode 100644 index 0000000..ebd9383 --- /dev/null +++ b/LGAlertView/LGAlertViewCell.h @@ -0,0 +1,51 @@ +// +// LGAlertViewCell.h +// LGAlertView +// +// +// The MIT License (MIT) +// +// Copyright (c) 2015 Grigory Lutkov +// (https://github.com/Friend-LGA/LGAlertView) +// +// 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 LGAlertViewCell : UITableViewCell + +@property (strong, nonatomic) NSString *title; + +@property (strong, nonatomic) UIColor *titleColor; +@property (strong, nonatomic) UIColor *titleColorHighlighted; + +@property (strong, nonatomic) UIColor *backgroundColorHighlighted; + +@property (assign, nonatomic, getter=isSeparatorVisible) BOOL separatorVisible; +@property (strong, nonatomic) UIColor *separatorColor_; + +@property (strong, nonatomic) UIFont *font; +@property (assign, nonatomic) NSUInteger numberOfLines; +@property (assign, nonatomic) NSLineBreakMode lineBreakMode; +@property (assign, nonatomic) NSTextAlignment textAlignment; +@property (assign, nonatomic) BOOL adjustsFontSizeToFitWidth; +@property (assign, nonatomic) CGFloat minimumScaleFactor; + +@end diff --git a/LGAlertView/LGAlertViewCell.m b/LGAlertView/LGAlertViewCell.m new file mode 100644 index 0000000..737a949 --- /dev/null +++ b/LGAlertView/LGAlertViewCell.m @@ -0,0 +1,122 @@ +// +// LGAlertViewCell.m +// LGAlertView +// +// +// The MIT License (MIT) +// +// Copyright (c) 2015 Grigory Lutkov +// (https://github.com/Friend-LGA/LGAlertView) +// +// 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 "LGAlertViewCell.h" + +#define kLGAlertViewSeparatorHeight ([UIScreen mainScreen].scale == 1.f || [UIDevice currentDevice].systemVersion.floatValue < 7.0 ? 1.f : 0.5) + +@interface LGAlertViewCell () + +@property (strong, nonatomic) UILabel *titleLabel; +@property (strong, nonatomic) UIView *separatorView; + +@end + +@implementation LGAlertViewCell + +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier +{ + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) + { + self.selectionStyle = UITableViewCellSelectionStyleNone; + + _titleLabel = [UILabel new]; + _titleLabel.backgroundColor = [UIColor clearColor]; + [self addSubview:_titleLabel]; + + _separatorView = [UIView new]; + [self addSubview:_separatorView]; + } + return self; +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + _titleLabel.text = _title; + _titleLabel.textAlignment = _textAlignment; + _titleLabel.font = _font; + _titleLabel.numberOfLines = _numberOfLines; + _titleLabel.lineBreakMode = _lineBreakMode; + _titleLabel.adjustsFontSizeToFitWidth = _adjustsFontSizeToFitWidth; + _titleLabel.minimumScaleFactor = _minimumScaleFactor; + + CGRect titleLabelFrame = CGRectMake(10.f, 0.f, self.frame.size.width-20.f, self.frame.size.height); + + if ([UIScreen mainScreen].scale == 1.f) + titleLabelFrame = CGRectIntegral(titleLabelFrame); + + _titleLabel.frame = titleLabelFrame; + + if (self.isSeparatorVisible) + { + _separatorView.hidden = NO; + + _separatorView.backgroundColor = _separatorColor_; + + _separatorView.frame = CGRectMake(0.f, self.frame.size.height-kLGAlertViewSeparatorHeight, self.frame.size.width, kLGAlertViewSeparatorHeight); + } + else _separatorView.hidden = YES; +} + +- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated +{ + [super setHighlighted:highlighted animated:animated]; + + if (highlighted) + { + _titleLabel.textColor = _titleColorHighlighted; + self.backgroundColor = _backgroundColorHighlighted; + } + else + { + _titleLabel.textColor = _titleColor; + self.backgroundColor = [UIColor clearColor]; + } +} + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated +{ + [super setSelected:selected animated:animated]; + + if (selected) + { + _titleLabel.textColor = _titleColorHighlighted; + self.backgroundColor = _backgroundColorHighlighted; + } + else + { + _titleLabel.textColor = _titleColor; + self.backgroundColor = [UIColor clearColor]; + } +} + +@end diff --git a/LGAlertView/LGAlertViewShared.h b/LGAlertView/LGAlertViewShared.h new file mode 100644 index 0000000..4d78eb4 --- /dev/null +++ b/LGAlertView/LGAlertViewShared.h @@ -0,0 +1,30 @@ +// +// LGAlertViewShared.h +// LGAlertView +// +// +// The MIT License (MIT) +// +// Copyright (c) 2015 Grigory Lutkov +// (https://github.com/Friend-LGA/LGAlertView) +// +// 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. +// + +static CGFloat const kLGAlertViewInnerMarginW = 10.f; diff --git a/LGAlertView/LGAlertViewTextField.h b/LGAlertView/LGAlertViewTextField.h new file mode 100644 index 0000000..9758af9 --- /dev/null +++ b/LGAlertView/LGAlertViewTextField.h @@ -0,0 +1,34 @@ +// +// LGAlertViewTextField.h +// LGAlertView +// +// +// The MIT License (MIT) +// +// Copyright (c) 2015 Grigory Lutkov +// (https://github.com/Friend-LGA/LGAlertView) +// +// 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 LGAlertViewTextField : UITextField + +@end diff --git a/LGAlertView/LGAlertViewTextField.m b/LGAlertView/LGAlertViewTextField.m new file mode 100644 index 0000000..67b6a05 --- /dev/null +++ b/LGAlertView/LGAlertViewTextField.m @@ -0,0 +1,98 @@ +// +// LGAlertViewTextField.m +// LGAlertView +// +// +// The MIT License (MIT) +// +// Copyright (c) 2015 Grigory Lutkov +// (https://github.com/Friend-LGA/LGAlertView) +// +// 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 "LGAlertViewTextField.h" +#import "LGAlertViewShared.h" + +@implementation LGAlertViewTextField + +- (instancetype)init +{ + self = [super init]; + if (self) + { + self.backgroundColor = [UIColor colorWithWhite:0.97 alpha:1.f]; + self.textColor = [UIColor blackColor]; + self.font = [UIFont systemFontOfSize:16.f]; + self.clearButtonMode = UITextFieldViewModeAlways; + } + return self; +} + +- (CGRect)textRectForBounds:(CGRect)bounds +{ + bounds.origin.x += kLGAlertViewInnerMarginW; + bounds.size.width -= kLGAlertViewInnerMarginW*2; + + if ([UIDevice currentDevice].systemVersion.floatValue < 7.0) + { + bounds.origin.y = self.frame.size.height/2-self.font.lineHeight/2; + bounds.size.height = self.font.lineHeight; + } + + if (self.leftView) + { + bounds.origin.x += (self.leftView.frame.size.width+kLGAlertViewInnerMarginW); + bounds.size.width -= (self.leftView.frame.size.width+kLGAlertViewInnerMarginW); + } + + if (self.rightView) + bounds.size.width -= (self.rightView.frame.size.width+kLGAlertViewInnerMarginW); + else if (self.clearButtonMode == UITextFieldViewModeAlways) + bounds.size.width -= 20.f; + + return bounds; +} + +- (CGRect)editingRectForBounds:(CGRect)bounds +{ + bounds.origin.x += kLGAlertViewInnerMarginW; + bounds.size.width -= kLGAlertViewInnerMarginW*2; + + if ([UIDevice currentDevice].systemVersion.floatValue < 7.0) + { + bounds.origin.y = self.frame.size.height/2-self.font.lineHeight/2; + bounds.size.height = self.font.lineHeight; + } + + if (self.leftView) + { + bounds.origin.x += (self.leftView.frame.size.width+kLGAlertViewInnerMarginW); + bounds.size.width -= (self.leftView.frame.size.width+kLGAlertViewInnerMarginW); + } + + if (self.rightView) + bounds.size.width -= (self.rightView.frame.size.width+kLGAlertViewInnerMarginW); + else if (self.clearButtonMode == UITextFieldViewModeAlways) + bounds.size.width -= 20.f; + + return bounds; +} + +@end diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..676f292 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Grigory Lutkov + +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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..69f3084 --- /dev/null +++ b/README.md @@ -0,0 +1,131 @@ +# LGAlertView + +Customizable implementation of UIAlertView. + +## Preview + + + + + + + + + + + +## Installation + +### With source code + +[Download repository](https://github.com/Friend-LGA/LGAlertView/archive/master.zip), then add [LGAlertView directory](https://github.com/Friend-LGA/LGAlertView/blob/master/LGAlertView/) to your project. + +### With CocoaPods + +[CocoaPods](http://cocoapods.org/) is a dependency manager for Objective-C, which automates and simplifies the process of using 3rd-party libraries in your projects. See the "Get Started" section for more details. + +#### Podfile + +``` +platform :ios, '6.0' +pod 'LGAlertView', '~> 1.0.0' +``` + +## Usage + +In the source files where you need to use the library, import the header file: + +```objective-c +#import "LGAlertView.h" +``` + +### Initialization + +You have several methods for initialization: + +```objective-c +- (instancetype)initWithTitle:(NSString *)title + message:(NSString *)message + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle; + +- (instancetype)initWithViewStyleWithTitle:(NSString *)title + message:(NSString *)message + view:(UIView *)view + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle; + +- (instancetype)initWithActivityIndicatorStyleWithTitle:(NSString *)title + message:(NSString *)message + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle; + +- (instancetype)initWithProgressViewStyleWithTitle:(NSString *)title + message:(NSString *)message + progressLabelText:(NSString *)progressLabelText + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle; + +- (instancetype)initWithTextFieldsStyleWithTitle:(NSString *)title + message:(NSString *)message + numberOfTextFields:(NSUInteger)numberOfTextFields + textFieldsSetupHandler:(void(^)(UITextField *textField, NSUInteger index))textFieldsSetupHandler + buttonTitles:(NSArray *)buttonTitles + cancelButtonTitle:(NSString *)cancelButtonTitle + destructiveButtonTitle:(NSString *)destructiveButtonTitle; +``` + +More init methods you can find in [LGAlertView.h](https://github.com/Friend-LGA/LGAlertView/blob/master/LGAlertView/LGAlertView.h) + +### Handle actions + +To handle actions you can use initialization methods with blocks or delegate, or implement it after initialization. + +#### Delegate + +```objective-c +@property (assign, nonatomic) id delegate; + +- (void)alertViewWillShow:(LGAlertView *)alertView; +- (void)alertViewWillDismiss:(LGAlertView *)alertView; +- (void)alertViewDidShow:(LGAlertView *)alertView; +- (void)alertViewDidDismiss:(LGAlertView *)alertView; +- (void)alertView:(LGAlertView *)alertView buttonPressedWithTitle:(NSString *)title index:(NSUInteger)index; +- (void)alertViewCancelled:(LGAlertView *)alertView; +- (void)alertViewDestructiveButtonPressed:(LGAlertView *)alertView; +``` + +#### Blocks + +```objective-c +@property (strong, nonatomic) void (^willShowHandler)(LGAlertView *alertView); +@property (strong, nonatomic) void (^willDismissHandler)(LGAlertView *alertView); +@property (strong, nonatomic) void (^didShowHandler)(LGAlertView *alertView); +@property (strong, nonatomic) void (^didDismissHandler)(LGAlertView *alertView); +@property (strong, nonatomic) void (^actionHandler)(LGAlertView *alertView, NSString *title, NSUInteger index); +@property (strong, nonatomic) void (^cancelHandler)(LGAlertView *alertView, BOOL onButton); +@property (strong, nonatomic) void (^destructiveHandler)(LGAlertView *alertView); +``` + +#### Notifications + +Here is also some notifications, that you can add to NSNotificationsCenter: + +```objective-c +kLGAlertViewWillShowNotification; +kLGAlertViewWillDismissNotification; +kLGAlertViewDidShowNotification; +kLGAlertViewDidDismissNotification; +``` + +### More + +For more details try Xcode [Demo project](https://github.com/Friend-LGA/LGAlertView/blob/master/Demo) and see [LGAlertView.h](https://github.com/Friend-LGA/LGAlertView/blob/master/LGAlertView/LGAlertView.h) + +## License + +LGAlertView is released under the MIT license. See [LICENSE](https://raw.githubusercontent.com/Friend-LGA/LGAlertView/master/LICENSE) for details.