diff --git a/.swift-version b/.swift-version new file mode 100644 index 0000000..8c50098 --- /dev/null +++ b/.swift-version @@ -0,0 +1 @@ +3.1 diff --git a/Alertift.podspec b/Alertift.podspec new file mode 100644 index 0000000..a29d1d8 --- /dev/null +++ b/Alertift.podspec @@ -0,0 +1,13 @@ +Pod::Spec.new do |s| + s.name = "Alertift" + s.version = "1.0" + s.summary = "UIAlertControlelr wrapper for Swift." + s.homepage = "https://github.com/sgr-ksmt/Alertift" + # s.screenshots = "" + s.license = 'MIT' + s.author = { "Suguru Kishimoto" => "melodydance.k.s@gmail.com" } + s.source = { :git => "https://github.com/sgr-ksmt/Alertift.git", :tag => s.version.to_s } + s.platform = :ios, '9.0' + s.requires_arc = true + s.source_files = "Sources/**/*" +end diff --git a/Alertift.xcodeproj/project.pbxproj b/Alertift.xcodeproj/project.pbxproj new file mode 100644 index 0000000..3b2926a --- /dev/null +++ b/Alertift.xcodeproj/project.pbxproj @@ -0,0 +1,337 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 4D13C7721EB064EF007BBB43 /* Alertift.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D13C7701EB064EF007BBB43 /* Alertift.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4D13C7B11EB22B8F007BBB43 /* Action.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D13C7AB1EB22B8F007BBB43 /* Action.swift */; }; + 4D13C7B21EB22B8F007BBB43 /* ActionSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D13C7AC1EB22B8F007BBB43 /* ActionSheet.swift */; }; + 4D13C7B31EB22B8F007BBB43 /* Alert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D13C7AD1EB22B8F007BBB43 /* Alert.swift */; }; + 4D13C7B41EB22B8F007BBB43 /* AlertBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D13C7AE1EB22B8F007BBB43 /* AlertBase.swift */; }; + 4D13C7B51EB22B8F007BBB43 /* Alertift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D13C7AF1EB22B8F007BBB43 /* Alertift.swift */; }; + 4D13C7B61EB22B8F007BBB43 /* InnerAlertController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D13C7B01EB22B8F007BBB43 /* InnerAlertController.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 4D13C76D1EB064EF007BBB43 /* Alertift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Alertift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 4D13C7701EB064EF007BBB43 /* Alertift.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Alertift.h; sourceTree = ""; }; + 4D13C7711EB064EF007BBB43 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 4D13C7AB1EB22B8F007BBB43 /* Action.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Action.swift; sourceTree = ""; }; + 4D13C7AC1EB22B8F007BBB43 /* ActionSheet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheet.swift; sourceTree = ""; }; + 4D13C7AD1EB22B8F007BBB43 /* Alert.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Alert.swift; sourceTree = ""; }; + 4D13C7AE1EB22B8F007BBB43 /* AlertBase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AlertBase.swift; sourceTree = ""; }; + 4D13C7AF1EB22B8F007BBB43 /* Alertift.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Alertift.swift; sourceTree = ""; }; + 4D13C7B01EB22B8F007BBB43 /* InnerAlertController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InnerAlertController.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 4D13C7691EB064EF007BBB43 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 4D13C7631EB064EF007BBB43 = { + isa = PBXGroup; + children = ( + 4D13C7AA1EB22B8E007BBB43 /* Sources */, + 4D13C76F1EB064EF007BBB43 /* Alertift */, + 4D13C76E1EB064EF007BBB43 /* Products */, + ); + sourceTree = ""; + }; + 4D13C76E1EB064EF007BBB43 /* Products */ = { + isa = PBXGroup; + children = ( + 4D13C76D1EB064EF007BBB43 /* Alertift.framework */, + ); + name = Products; + sourceTree = ""; + }; + 4D13C76F1EB064EF007BBB43 /* Alertift */ = { + isa = PBXGroup; + children = ( + 4D13C7701EB064EF007BBB43 /* Alertift.h */, + 4D13C7711EB064EF007BBB43 /* Info.plist */, + ); + path = Alertift; + sourceTree = ""; + }; + 4D13C7AA1EB22B8E007BBB43 /* Sources */ = { + isa = PBXGroup; + children = ( + 4D13C7AB1EB22B8F007BBB43 /* Action.swift */, + 4D13C7AC1EB22B8F007BBB43 /* ActionSheet.swift */, + 4D13C7AD1EB22B8F007BBB43 /* Alert.swift */, + 4D13C7AE1EB22B8F007BBB43 /* AlertBase.swift */, + 4D13C7AF1EB22B8F007BBB43 /* Alertift.swift */, + 4D13C7B01EB22B8F007BBB43 /* InnerAlertController.swift */, + ); + path = Sources; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 4D13C76A1EB064EF007BBB43 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4D13C7721EB064EF007BBB43 /* Alertift.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 4D13C76C1EB064EF007BBB43 /* Alertift */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4D13C7751EB064EF007BBB43 /* Build configuration list for PBXNativeTarget "Alertift" */; + buildPhases = ( + 4D13C7681EB064EF007BBB43 /* Sources */, + 4D13C7691EB064EF007BBB43 /* Frameworks */, + 4D13C76A1EB064EF007BBB43 /* Headers */, + 4D13C76B1EB064EF007BBB43 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Alertift; + productName = Alertift; + productReference = 4D13C76D1EB064EF007BBB43 /* Alertift.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 4D13C7641EB064EF007BBB43 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0830; + ORGANIZATIONNAME = "Suguru Kishimoto"; + TargetAttributes = { + 4D13C76C1EB064EF007BBB43 = { + CreatedOnToolsVersion = 8.3.2; + LastSwiftMigration = 0830; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 4D13C7671EB064EF007BBB43 /* Build configuration list for PBXProject "Alertift" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 4D13C7631EB064EF007BBB43; + productRefGroup = 4D13C76E1EB064EF007BBB43 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 4D13C76C1EB064EF007BBB43 /* Alertift */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 4D13C76B1EB064EF007BBB43 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 4D13C7681EB064EF007BBB43 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4D13C7B31EB22B8F007BBB43 /* Alert.swift in Sources */, + 4D13C7B61EB22B8F007BBB43 /* InnerAlertController.swift in Sources */, + 4D13C7B41EB22B8F007BBB43 /* AlertBase.swift in Sources */, + 4D13C7B11EB22B8F007BBB43 /* Action.swift in Sources */, + 4D13C7B51EB22B8F007BBB43 /* Alertift.swift in Sources */, + 4D13C7B21EB22B8F007BBB43 /* ActionSheet.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 4D13C7731EB064EF007BBB43 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + 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_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + 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 = 9.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 4D13C7741EB064EF007BBB43 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + 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_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + 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 = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 4D13C7761EB064EF007BBB43 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Alertift/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "-.Alertift"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 4D13C7771EB064EF007BBB43 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Alertift/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "-.Alertift"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 4D13C7671EB064EF007BBB43 /* Build configuration list for PBXProject "Alertift" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4D13C7731EB064EF007BBB43 /* Debug */, + 4D13C7741EB064EF007BBB43 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4D13C7751EB064EF007BBB43 /* Build configuration list for PBXNativeTarget "Alertift" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4D13C7761EB064EF007BBB43 /* Debug */, + 4D13C7771EB064EF007BBB43 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 4D13C7641EB064EF007BBB43 /* Project object */; +} diff --git a/Alertift.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Alertift.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..1fc797f --- /dev/null +++ b/Alertift.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Alertift.xcodeproj/xcshareddata/xcschemes/Alertift.xcscheme b/Alertift.xcodeproj/xcshareddata/xcschemes/Alertift.xcscheme new file mode 100644 index 0000000..6cd1c3d --- /dev/null +++ b/Alertift.xcodeproj/xcshareddata/xcschemes/Alertift.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Alertift.xcworkspace/contents.xcworkspacedata b/Alertift.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..b997a39 --- /dev/null +++ b/Alertift.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Alertift/Alertift.h b/Alertift/Alertift.h new file mode 100644 index 0000000..434c085 --- /dev/null +++ b/Alertift/Alertift.h @@ -0,0 +1,19 @@ +// +// Alertift.h +// Alertift +// +// Created by Suguru Kishimoto on 4/26/17. +// Copyright © 2017 Suguru Kishimoto. All rights reserved. +// + +#import + +//! Project version number for Alertift. +FOUNDATION_EXPORT double AlertiftVersionNumber; + +//! Project version string for Alertift. +FOUNDATION_EXPORT const unsigned char AlertiftVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Alertift/Info.plist b/Alertift/Info.plist new file mode 100644 index 0000000..fbe1e6b --- /dev/null +++ b/Alertift/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/Demo/Demo.xcodeproj/project.pbxproj b/Demo/Demo.xcodeproj/project.pbxproj new file mode 100644 index 0000000..bd07837 --- /dev/null +++ b/Demo/Demo.xcodeproj/project.pbxproj @@ -0,0 +1,329 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 4D13C7851EB06535007BBB43 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D13C7841EB06535007BBB43 /* AppDelegate.swift */; }; + 4D13C7871EB06535007BBB43 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D13C7861EB06535007BBB43 /* ViewController.swift */; }; + 4D13C78A1EB06535007BBB43 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4D13C7881EB06535007BBB43 /* Main.storyboard */; }; + 4D13C78C1EB06535007BBB43 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4D13C78B1EB06535007BBB43 /* Assets.xcassets */; }; + 4D13C78F1EB06535007BBB43 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4D13C78D1EB06535007BBB43 /* LaunchScreen.storyboard */; }; + 4D13C79D1EB18FB2007BBB43 /* Alertift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D13C79C1EB18FB2007BBB43 /* Alertift.framework */; }; + 4D13C79E1EB18FB2007BBB43 /* Alertift.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 4D13C79C1EB18FB2007BBB43 /* Alertift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 4D13C79F1EB18FB2007BBB43 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 4D13C79E1EB18FB2007BBB43 /* Alertift.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 4D13C7811EB06535007BBB43 /* Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Demo.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4D13C7841EB06535007BBB43 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 4D13C7861EB06535007BBB43 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 4D13C7891EB06535007BBB43 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 4D13C78B1EB06535007BBB43 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 4D13C78E1EB06535007BBB43 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 4D13C7901EB06535007BBB43 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 4D13C79C1EB18FB2007BBB43 /* Alertift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Alertift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 4D13C77E1EB06535007BBB43 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4D13C79D1EB18FB2007BBB43 /* Alertift.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 4D13C7781EB06535007BBB43 = { + isa = PBXGroup; + children = ( + 4D13C79C1EB18FB2007BBB43 /* Alertift.framework */, + 4D13C7831EB06535007BBB43 /* Demo */, + 4D13C7821EB06535007BBB43 /* Products */, + ); + sourceTree = ""; + }; + 4D13C7821EB06535007BBB43 /* Products */ = { + isa = PBXGroup; + children = ( + 4D13C7811EB06535007BBB43 /* Demo.app */, + ); + name = Products; + sourceTree = ""; + }; + 4D13C7831EB06535007BBB43 /* Demo */ = { + isa = PBXGroup; + children = ( + 4D13C7841EB06535007BBB43 /* AppDelegate.swift */, + 4D13C7861EB06535007BBB43 /* ViewController.swift */, + 4D13C7881EB06535007BBB43 /* Main.storyboard */, + 4D13C78B1EB06535007BBB43 /* Assets.xcassets */, + 4D13C78D1EB06535007BBB43 /* LaunchScreen.storyboard */, + 4D13C7901EB06535007BBB43 /* Info.plist */, + ); + path = Demo; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 4D13C7801EB06535007BBB43 /* Demo */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4D13C7931EB06535007BBB43 /* Build configuration list for PBXNativeTarget "Demo" */; + buildPhases = ( + 4D13C77D1EB06535007BBB43 /* Sources */, + 4D13C77E1EB06535007BBB43 /* Frameworks */, + 4D13C77F1EB06535007BBB43 /* Resources */, + 4D13C79F1EB18FB2007BBB43 /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Demo; + productName = Demo; + productReference = 4D13C7811EB06535007BBB43 /* Demo.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 4D13C7791EB06535007BBB43 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0830; + LastUpgradeCheck = 0830; + ORGANIZATIONNAME = "Suguru Kishimoto"; + TargetAttributes = { + 4D13C7801EB06535007BBB43 = { + CreatedOnToolsVersion = 8.3.2; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 4D13C77C1EB06535007BBB43 /* Build configuration list for PBXProject "Demo" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 4D13C7781EB06535007BBB43; + productRefGroup = 4D13C7821EB06535007BBB43 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 4D13C7801EB06535007BBB43 /* Demo */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 4D13C77F1EB06535007BBB43 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4D13C78F1EB06535007BBB43 /* LaunchScreen.storyboard in Resources */, + 4D13C78C1EB06535007BBB43 /* Assets.xcassets in Resources */, + 4D13C78A1EB06535007BBB43 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 4D13C77D1EB06535007BBB43 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4D13C7871EB06535007BBB43 /* ViewController.swift in Sources */, + 4D13C7851EB06535007BBB43 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 4D13C7881EB06535007BBB43 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 4D13C7891EB06535007BBB43 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 4D13C78D1EB06535007BBB43 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 4D13C78E1EB06535007BBB43 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 4D13C7911EB06535007BBB43 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + 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_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + 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 = 9.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 4D13C7921EB06535007BBB43 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + 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_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + 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 = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 4D13C7941EB06535007BBB43 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = Demo/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "-.alertift.Demo"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 4D13C7951EB06535007BBB43 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = Demo/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "-.alertift.Demo"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 4D13C77C1EB06535007BBB43 /* Build configuration list for PBXProject "Demo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4D13C7911EB06535007BBB43 /* Debug */, + 4D13C7921EB06535007BBB43 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4D13C7931EB06535007BBB43 /* Build configuration list for PBXNativeTarget "Demo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4D13C7941EB06535007BBB43 /* Debug */, + 4D13C7951EB06535007BBB43 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 4D13C7791EB06535007BBB43 /* Project object */; +} diff --git a/Demo/Demo/AppDelegate.swift b/Demo/Demo/AppDelegate.swift new file mode 100644 index 0000000..61687c5 --- /dev/null +++ b/Demo/Demo/AppDelegate.swift @@ -0,0 +1,15 @@ +// +// AppDelegate.swift +// Demo +// +// Created by Suguru Kishimoto on 4/26/17. +// Copyright © 2017 Suguru Kishimoto. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + var window: UIWindow? +} + diff --git a/Demo/Demo/Assets.xcassets/AppIcon.appiconset/Contents.json b/Demo/Demo/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..118c98f --- /dev/null +++ b/Demo/Demo/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,38 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Demo/Demo/Base.lproj/LaunchScreen.storyboard b/Demo/Demo/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..fdf3f97 --- /dev/null +++ b/Demo/Demo/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Demo/Demo/Base.lproj/Main.storyboard b/Demo/Demo/Base.lproj/Main.storyboard new file mode 100644 index 0000000..dfb7dca --- /dev/null +++ b/Demo/Demo/Base.lproj/Main.storyboard @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Demo/Demo/Info.plist b/Demo/Demo/Info.plist new file mode 100644 index 0000000..38e98af --- /dev/null +++ b/Demo/Demo/Info.plist @@ -0,0 +1,38 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Demo/Demo/ViewController.swift b/Demo/Demo/ViewController.swift new file mode 100644 index 0000000..0e9f5bf --- /dev/null +++ b/Demo/Demo/ViewController.swift @@ -0,0 +1,109 @@ +// +// ViewController.swift +// Demo +// +// Created by Suguru Kishimoto on 4/26/17. +// Copyright © 2017 Suguru Kishimoto. All rights reserved. +// + +import UIKit +import Alertift + +class ViewController: UIViewController { + + @IBOutlet private var buttons: [UIButton]! { + didSet { + buttons.enumerated().forEach { index, button in + button.tag = index + button.addTarget(self, action: #selector(buttonDidTap(_:)), for: .touchUpInside) + } + } + } + private enum AlertType: Int { + case simple + case yesOrNo + case login + case actionsheet + } + + @objc private func buttonDidTap(_ button: UIButton) { + guard let type = AlertType(rawValue: button.tag) else { + return + } + + switch type { + case .simple: + showSimpleAlert() + case .yesOrNo: + showYesOrNoAlert() + case .login: + showLoginAlert() + case .actionsheet: + showActionSheet(source: self.view, frame: button.frame) + } + } + + private func showSimpleAlert() { + Alertift.alert(title: "Sample 1", message: "Simple alert!") + .action(.default("OK")) + .show() + } + + private func showYesOrNoAlert() { + Alertift.alert(title: "Sample 2",message: "Do you like 🍣?") + .action(.default("Yes"), isPreferred: true) { + Alertift.alert(message: "🍣🍣🍣") + .action(.default("Close")) + .show() + } + .action(.cancel("No")) { + Alertift.alert(message: "😂😂😂") + .action(.destructive("Close")) + .show() + } + .show() + } + + private func showLoginAlert() { + Alertift.alert(title: "Sign in", message: "Input your ID and Password") + .textField { textField in + textField.placeholder = "ID" + } + .textField { textField in + textField.placeholder = "Password" + textField.isSecureTextEntry = true + } + .handleTextFieldTextDidChange { textField, index in + let text = textField.text ?? "" + print("\(index), \(text)") + } + .action(.cancel("Cancel")) + .action(.default("Sign in"), textFieldsHandler: { textFields in + let id = textFields?.first?.text ?? "" + let password = textFields?.last?.text ?? "" + Alertift.alert(title: "Sign in successfully", message: "ID: \(id)\nPassword: \(password)") + .action(.default("OK")) + .show() + }) + .show() + } + private func showActionSheet(source: UIView, frame: CGRect) { + Alertift.actionSheet(message: "Which food do you like?") + .popover(sourceView: source, sourceRect: frame) + .action(.default("🍣")) + .action(.default("🍎")) + .action(.default("🍖")) + .action(.default("🍅")) + .action(.cancel("None of them")) + .finally { action, index in + if action.style == .cancel { + return + } + Alertift.alert(message: "\(index). \(action.title!)") + .action(.default("OK")) + .show() + } + .show() + } +} + diff --git a/Documents/img1.png b/Documents/img1.png new file mode 100644 index 0000000..8b37c65 Binary files /dev/null and b/Documents/img1.png differ diff --git a/Documents/img2.png b/Documents/img2.png new file mode 100644 index 0000000..011663a Binary files /dev/null and b/Documents/img2.png differ diff --git a/Documents/img3.png b/Documents/img3.png new file mode 100644 index 0000000..04dade8 Binary files /dev/null and b/Documents/img3.png differ diff --git a/Documents/img4.png b/Documents/img4.png new file mode 100644 index 0000000..a32d7d4 Binary files /dev/null and b/Documents/img4.png differ diff --git a/Documents/img5.png b/Documents/img5.png new file mode 100644 index 0000000..0fd7950 Binary files /dev/null and b/Documents/img5.png differ diff --git a/README.md b/README.md index 8531e85..3b932fa 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,166 @@ # Alertift -UIAlertController wrapper for Swift. +UIAlertControlelr wrapper for Swift + +[![GitHub release](https://img.shields.io/github/release/sgr-ksmt/Alertift.svg)](https://github.com/sgr-ksmt/Alertift/releases) +![Language](https://img.shields.io/badge/language-Swift%203-orange.svg) +[![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) +[![CocoaPods](https://img.shields.io/badge/Cocoa%20Pods-✓-4BC51D.svg?style=flat)](https://cocoapods.org/pods/Alertift) +[![CocoaPodsDL](https://img.shields.io/cocoapods/dt/Alertift.svg)](https://cocoapods.org/pods/Alertift) +[![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/matteocrippa/awesome-swift#ui) + + +```swift +Alertift.alert(title: "Confirm", message: "Delete this post?") + .action(.destructive("Delete")) { + // delete post + } + .action(.cancel("Cancel")) + .show() +``` + +![img1](Documents/img1.png) + +## Feature +- Method chain +- UITextField support +- iPad support(Action Sheet, popover) + +## Examples + +### Simple Alert + +```swift +Alertift.alert(title: "Sample 1", message: "Simple alert!") + .action(.default("OK")) + .show() +``` + +![img2](Documents/img2.png) + + +```swift +Alertift.alert(title: "Confirm", message: "Delete this post?") + .action(.destructive("Delete")) { + // delete post + } + .action(.cancel("Cancel")) + .show() +``` + +![img1](Documents/img1.png) + + +### Prompt Alert + +```swift +Alertift.alert(title: "Sign in", message: "Input your ID and Password") + .textField { textField in + textField.placeholder = "ID" + } + .textField { textField in + textField.placeholder = "Password" + textField.isSecureTextEntry = true + } + .action(.cancel("Cancel")) + .action(.default("Sign in"), textFieldsHandler: { textFields in + let id = textFields?.first?.text ?? "" + let password = textFields?.last?.text ?? "" + // sign in + }) + .show() +``` + +![img3](Documents/img3.png) + +### Action Sheet + +```swift +Alertift.actionSheet(message: "Which food do you like?") + .action(.default("🍣")) + .action(.default("🍎")) + .action(.default("🍖")) + .action(.default("🍅")) + .action(.cancel("None of them")) + .finally { action, index in + if action.style == .cancel { + return + } + Alertift.alert(message: "\(index). \(action.title!)") + .action(.default("OK")) + .show() + } + .show() +``` + +![img4](Documents/img4.png) + +#### for iPad +Use `popover(sourceView:SourceRect)` + +```swift +Alertift.actionSheet(message: "Which food do you like?") + .popover(sourceView: self.view, sourceRect: button.frame) + .action(.default("🍣")) + .action(.default("🍎")) + .action(.default("🍖")) + .action(.default("🍅")) + .action(.cancel("None of them")) + .finally(handler: { action, index in + if action.style == .cancel { + return + } + Alertift.alert(message: "\(index). \(action.title!)") + .action(.default("OK")) + .show() + }) + .show() +``` + +![img5](Documents/img5.png) + + +## Requirements +- iOS 9.0+ +- Xcode 8.1+ +- Swift 3.0+ + +## Installation + +### Carthage + +- Add the following to your *Cartfile*: + +```bash +github "sgr-ksmt/Alertift" ~> 1.0 +``` + +- Run `carthage update` +- Add the framework as described. +
Details: [Carthage Readme](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application) + + +### CocoaPods + +**Alertift** is available through [CocoaPods](http://cocoapods.org). To install +it, simply add the following line to your Podfile: + +```ruby +pod 'Alertift', '~> 1.0' +``` + +and run `pod install` + +### Manually Install +Download all `*.swift` files and put your project. + +## Change log +Change log is [here](https://github.com/sgr-ksmt/Alertift/blob/master/CHANGELOG.md). + +## Communication +- If you found a bug, open an issue. +- If you have a feature request, open an issue. +- If you want to contribute, submit a pull request.:muscle: + +## License + +**Alertift** is under MIT license. See the [LICENSE](LICENSE) file for more info. diff --git a/Sources/Action.swift b/Sources/Action.swift new file mode 100644 index 0000000..8b9fa32 --- /dev/null +++ b/Sources/Action.swift @@ -0,0 +1,48 @@ +// +// Action.swift +// Alertift +// +// Created by Suguru Kishimoto on 4/27/17. +// Copyright © 2017 Suguru Kishimoto. All rights reserved. +// + +import Foundation + +extension Alertift { + /// Action type for **Alert**, **ActionSheet** + /// + /// - `default`: Default action(action title) + /// - destructive: Destructive action(action title) + /// - cancel: Cancel description(action title) + public enum Action { + case `default`(String?) + case destructive(String?) + case cancel(String?) + + /// **UIAlertAction**'s title + private var title: String? { + switch self { + case .default(let title): return title + case .destructive(let title): return title + case .cancel(let title): return title + } + } + + /// **UIAlertAction**'s style + private var style: UIAlertActionStyle { + switch self { + case .default( _): return .default + case .destructive( _): return .destructive + case .cancel( _): return .cancel + } + } + + /// **Build UIAlertAction** + /// + /// - Parameter actionHandler: Action handler for **UIAlertAction** + /// - Returns: Instance of **UIAlertAction** + func buildAlertAction(handler actionHandler: @escaping (UIAlertAction) -> Void) -> UIAlertAction { + return UIAlertAction(title: title, style: style, handler: { actionHandler($0) }) + } + } +} diff --git a/Sources/ActionSheet.swift b/Sources/ActionSheet.swift new file mode 100644 index 0000000..addef97 --- /dev/null +++ b/Sources/ActionSheet.swift @@ -0,0 +1,43 @@ +// +// ActionSheet.swift +// Alertift +// +// Created by Suguru Kishimoto on 4/27/17. +// Copyright © 2017 Suguru Kishimoto. All rights reserved. +// + +import Foundation + +extension Alertift { + /// ActionSheet + final public class ActionSheet: AlertBase { + /// Make action sheet + /// + /// - Parameters: + /// - title: The title of the alert. Use this string to get the user’s attention and communicate the reason for the alert. + /// - message: Descriptive text that provides additional details about the reason for the alert. + /// - Returns: Instance of **ActionSheet** + public init(title: String? = nil, message: String? = nil) { + super.init(title: title, message: message, style: .actionSheet) + } + + /// Add action to alertController + public func action(_ action: Alertift.Action, handler: @escaping Alertift.ActionHandler = {}) -> Self { + _alertController.addAction(buildAlertAction(action, handler: _alertController.combineActionHandler(handler))) + return self + } + + /// Add sourceView and sourceRect to **popoverPresentationController**. + /// + /// If you want to use action sheet on iPad, you have to use this method. + /// - Parameters: + /// - view: sourceView + /// - rect: sourceRect + /// - Returns: MySelf + public func popover(sourceView view: UIView?, sourceRect rect: CGRect) -> Self { + _alertController.popoverPresentationController?.sourceView = view + _alertController.popoverPresentationController?.sourceRect = rect + return self + } + } +} diff --git a/Sources/Alert.swift b/Sources/Alert.swift new file mode 100644 index 0000000..07ca364 --- /dev/null +++ b/Sources/Alert.swift @@ -0,0 +1,99 @@ +// +// Alert.swift +// Alertift +// +// Created by Suguru Kishimoto on 4/26/17. +// Copyright © 2017 Suguru Kishimoto. All rights reserved. +// + +import Foundation + +extension Alertift { + /// Alert + final public class Alert: AlertBase { + /// TextFieldHandler + public typealias TextFieldHandler = ((UITextField, Int) -> Void) + + /// ActionWithTextFieldsHandler + public typealias ActionWithTextFieldsHandler = ([UITextField]?) -> Void + + /// Make alert + /// + /// - Parameters: + /// - title: The title of the alert. Use this string to get the user’s attention and communicate the reason for the alert. + /// - message: Descriptive text that provides additional details about the reason for the alert. + /// - Returns: Instance of **Alert** + public init(title: String? = nil, message: String? = nil) { + super.init(title: title, message: message, style: .alert) + } + + /// Add alertAction to alertController + /// + /// - Parameters: + /// - alertAction: UIAlertAction + /// - isPreferred: If isPreferred is true, alertAction becomes preferredAction. + private func addActionToAlertController(_ alertAction: UIAlertAction, isPreferred: Bool) { + _alertController.addAction(alertAction) + if isPreferred { + _alertController.preferredAction = alertAction + } + } + + /// Add action to Alert + /// + /// - Parameters: + /// - action: Alert action. + /// - isPreferred: If you want to change this action to preferredAction, set true. Default is false. + /// - handler: The block to execute after this action performed. + /// - Returns: Myself + public func action(_ action: Alertift.Action, isPreferred: Bool = false, handler: @escaping Alertift.ActionHandler = {}) -> Self { + addActionToAlertController( + buildAlertAction(action, handler: _alertController.combineActionHandler(handler)), + isPreferred: isPreferred + ) + return self + } + + /// Add action to Alert + /// + /// - Parameters: + /// - action: Alert action. + /// - isPreferred: If you want to change this action to preferredAction, set true. Default is false. + /// - textFieldsHandler: The block that returns array of UITextFields to execute after this action performed. + /// - Returns: Myself + final public func action(_ action: Alertift.Action, isPreferred: Bool = false, textFieldsHandler: @escaping ActionWithTextFieldsHandler) -> Self { + addActionToAlertController( + buildAlertAction(action, handler: _alertController.combineActionWithTextFieldsHandler(textFieldsHandler)), + isPreferred: isPreferred + ) + return self + } + + /// Add text field to alertController + /// + /// - Parameter handler: Define handler if you want to customize UITextField. Default is nil. + /// - Returns: Myself + public func textField(configurationHandler handler: ((UITextField) -> Void)? = nil) -> Self { + _alertController.addTextField { [weak self] textField in + guard let strongSelf = self else { + return + } + handler?(textField) + strongSelf._alertController.registerTextFieldObserver(textField) + } + + return self + } + + /// Add textFieldHandler to alertController. + /// + /// If text field's text is changed, execute textFieldHandler with text field and index. + /// + /// - Parameter textFieldTextDidChangeHandler: TextFieldHandler (UITextField, Int) -> Void + /// - Returns: Myself + public func handleTextFieldTextDidChange(textFieldTextDidChangeHandler: TextFieldHandler?) -> Self { + _alertController.textFieldTextDidChangeHandler = textFieldTextDidChangeHandler + return self + } + } +} diff --git a/Sources/AlertBase.swift b/Sources/AlertBase.swift new file mode 100644 index 0000000..74e7295 --- /dev/null +++ b/Sources/AlertBase.swift @@ -0,0 +1,66 @@ +// +// AlertBase.swift +// Alertift +// +// Created by Suguru Kishimoto on 4/27/17. +// Copyright © 2017 Suguru Kishimoto. All rights reserved. +// + +import Foundation + +extension Alertift { + /// AlertBase + /// superclass of Alert, ActionSheet. + public class AlertBase { + + /// UIAlertController + public var alertController: UIAlertController { + return _alertController as UIAlertController + } + + /// InnerAlertController (internal). + let _alertController: InnerAlertController + + /// Handler for finally. + private var finallyHandler: Alertift.FinallyHandler? + + + /// Initializer + /// + /// - Parameters: + /// - title: The title of the alert. Use this string to get the user’s attention and communicate the reason for the alert. + /// - message: Descriptive text that provides additional details about the reason for the alert. + /// - style: The style to use when presenting the alert controller. Use this parameter to configure the alert controller as an action sheet or as a modal alert. + init(title: String? = nil, message: String? = nil, style: UIAlertControllerStyle) { + _alertController = InnerAlertController(title: title, message: message, preferredStyle: style) + } + + /// Build **UIAlertAction** using **Alertift.Action** and handler. + /// + /// - Parameters: + /// - action: action + /// - handler: The handler to execute after the action selected. + /// - Returns: **UIAlertAction** + func buildAlertAction(_ action: Alertift.Action, handler: @escaping (UIAlertAction) -> Void) -> UIAlertAction { + return action.buildAlertAction(handler: handler) + } + + /// Add finally handler. + /// + /// - Parameter handler: The handler to execute after either alert selected. + /// - Returns: Myself + public func finally(handler: @escaping Alertift.FinallyHandler) -> Self { + _alertController.finallyHandler = handler + return self + } + + /// Show alert (or action sheet). + /// + /// - Parameters: + /// - viewController: The view controller to display over the current view controller’s content. Default is **UIApplication.shared.keyWindow?.rootViewController** + /// - completion: The block to execute after the presentation finishes. This block has no return value and takes no parameters. You may specify nil for this parameter. + final public func show(on viewController: UIViewController? = UIApplication.shared.keyWindow?.rootViewController, completion: (() -> Void)? = nil) { + viewController?.present(_alertController, animated: true, completion: completion) + } + } +} diff --git a/Sources/Alertift.swift b/Sources/Alertift.swift new file mode 100644 index 0000000..f47d91d --- /dev/null +++ b/Sources/Alertift.swift @@ -0,0 +1,51 @@ +// +// Alertift.swift +// Alertift +// +// Created by Suguru Kishimoto on 4/26/17. +// Copyright © 2017 Suguru Kishimoto. All rights reserved. +// + +import Foundation + + +/// Alertift +/// make alert or action sheet. +public final class Alertift { + /// private initializer + private init() {} + + /// Make alert + /// + /// - Parameters: + /// - title: The title of the alert. Use this string to get the user’s attention and communicate the reason for the alert. + /// - message: Descriptive text that provides additional details about the reason for the alert. + /// - Returns: Instance of **Alert** + public static func alert(title: String? = nil, message: String? = nil) -> Alert { + return Alert(title: title, message: message) + } + + /// Make action sheet + /// + /// - Parameters: + /// - title: The title of the alert. Use this string to get the user’s attention and communicate the reason for the alert. + /// - message: Descriptive text that provides additional details about the reason for the alert. + /// - Returns: Instance of **ActionSheet** + public static func actionSheet(title: String? = nil, message: String? = nil) -> ActionSheet { + return ActionSheet(title: title, message: message) + } +} + +extension Alertift { + /// Action handler + public typealias ActionHandler = () -> Void + + /// Finally handler + public typealias FinallyHandler = (UIAlertAction, Int) -> Void +} + + +/// Internal typealiases +typealias _AlertBase = Alertift.AlertBase +typealias _Alert = Alertift.Alert +typealias _ActionSheet = Alertift.ActionSheet diff --git a/Sources/InnerAlertController.swift b/Sources/InnerAlertController.swift new file mode 100644 index 0000000..f5678ea --- /dev/null +++ b/Sources/InnerAlertController.swift @@ -0,0 +1,73 @@ +// +// InnerAlertController.swift +// Alertift +// +// Created by Suguru Kishimoto on 4/27/17. +// Copyright © 2017 Suguru Kishimoto. All rights reserved. +// + +import Foundation +import UIKit + +/// InnerAlertController +/// subclass of **UIAlertController** +class InnerAlertController: UIAlertController { + /// textFieldTextDidChangeHandler: ((UITextField, Int) -> Void) + var textFieldTextDidChangeHandler: _Alert.TextFieldHandler? + + /// finallyHandler: (UIAlertAction, Int) -> Void + var finallyHandler: Alertift.FinallyHandler? + + /// Register UITextFieldTextDidChange notification + /// + /// - Parameter textField: textField + func registerTextFieldObserver(_ textField: UITextField) { + NotificationCenter.default.addObserver( + self, + selector: #selector(self.textFieldDidChange(_:)), + name: .UITextFieldTextDidChange, object: textField + ) + } + + /// Delegate method for UITextFieldTextDidChange + /// + /// - Parameter notification: notification (object is UITextField) + @objc private func textFieldDidChange(_ notification: Notification) { + guard let textField = notification.object as? UITextField else { + return + } + + guard let index = textFields?.index(of: textField) else { + return + } + textFieldTextDidChangeHandler?(textField, index) + } + + /// Combine originalHandler and finallyHandler with textFields. + /// + /// - Parameter originalHandler: original action handler. + /// - Returns: New action handler. + func combineActionWithTextFieldsHandler(_ originalHandler: @escaping _Alert.ActionWithTextFieldsHandler) -> (UIAlertAction) -> Void { + return combineActionHandler { [weak self] in + originalHandler(self?.textFields) + } + } + + /// Combine originalHandler and finallyHandler. + /// + /// - Parameter originalHandler: original action handler. + /// - Returns: New action handler. + func combineActionHandler(_ originalHandler: @escaping () -> Void) -> (UIAlertAction) -> Void { + return { [weak self] action in + guard let strongSelf = self else { + return + } + originalHandler() + strongSelf.finallyHandler?(action, strongSelf.actions.index(of: action) ?? -1) + } + } + + deinit { + NotificationCenter.default.removeObserver(self) + } +}