├── LICENSE ├── LYAlertView.podspec ├── LYAlertViewDemo.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── discover.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── discover.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ └── xcschememanagement.plist ├── LYAlertViewDemo ├── AppDelegate.swift ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist ├── LYAlertView │ ├── LYAlertAnimation.swift │ ├── LYAlertBuilder.swift │ ├── LYAlertFactory.swift │ ├── LYAlertFactoryProtocol.swift │ ├── LYAlertInteractiveItem.swift │ ├── LYAlertShowView.swift │ ├── LYAlertTextFieldItem.swift │ ├── LYAlertTitleItem.swift │ ├── LYAlertView.swift │ ├── LYCommonSet.swift │ ├── LYLineView.swift │ └── StringExtension.swift ├── SceneDelegate.swift └── ViewController.swift └── README.md /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 MikeBanana 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LYAlertView.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint LYAlertViewDemo.podspec' to ensure this is a 3 | # valid spec and to remove all comments including this before submitting the spec. 4 | # 5 | # To learn more about Podspec attributes see https://guides.cocoapods.org/syntax/podspec.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |spec| 10 | 11 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 12 | # 13 | # These will help people to find your library, and whilst it 14 | # can feel like a chore to fill in it's definitely to your advantage. The 15 | # summary should be tweet-length, and the description more in depth. 16 | # 17 | 18 | spec.name = "LYAlertView" 19 | spec.version = "0.0.4" 20 | spec.summary = "一个具有高度拓展性的弹框轮子" 21 | 22 | # This description is used to generate tags and improve search results. 23 | # * Think: What does it do? Why did you write it? What is the focus? 24 | # * Try to keep it short, snappy and to the point. 25 | # * Write the description between the DESC delimiters below. 26 | # * Finally, don't worry about the indent, CocoaPods strips it! 27 | spec.description = "工厂模式和建造者模式相结合,拓展性高,自带动画的弹框" 28 | spec.frameworks = "Foundation","UIKit" 29 | 30 | spec.homepage = "https://github.com/Mikebanana/LYAlertViewDemo" 31 | # spec.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif" 32 | 33 | 34 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 35 | # 36 | # Licensing your code is important. See https://choosealicense.com for more info. 37 | # CocoaPods will detect a license file if there is a named LICENSE* 38 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. 39 | # 40 | spec.swift_version = '5.0' 41 | # spec.license = "MIT" 42 | spec.license = { :type => "MIT", :file => "FILE_LICENSE" } 43 | 44 | 45 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 46 | # 47 | # Specify the authors of the library, with email addresses. Email addresses 48 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also 49 | # accepts just a name if you'd rather not provide an email address. 50 | # 51 | # Specify a social_media_url where others can refer to, for example a twitter 52 | # profile URL. 53 | # 54 | 55 | spec.author = { "Mikebanana" => "liyu283026@163.com" } 56 | # Or just: spec.author = "Mikebanana" 57 | # spec.authors = { "Mikebanana" => "liyu283026@163.com" } 58 | # spec.social_media_url = "https://twitter.com/Mikebanana" 59 | 60 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 61 | # 62 | # If this Pod runs only on iOS or OS X, then specify the platform and 63 | # the deployment target. You can optionally include the target after the platform. 64 | # 65 | 66 | spec.platform = :ios 67 | # spec.platform = :ios, "5.0" 68 | 69 | # When using multiple platforms 70 | spec.ios.deployment_target = "13.0" 71 | # spec.osx.deployment_target = "10.7" 72 | # spec.watchos.deployment_target = "2.0" 73 | # spec.tvos.deployment_target = "9.0" 74 | 75 | 76 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 77 | # 78 | # Specify the location from where the source should be retrieved. 79 | # Supports git, hg, bzr, svn and HTTP. 80 | # 81 | 82 | spec.source = { :git => "https://github.com/Mikebanana/LYAlertViewDemo.git", :tag => "#{spec.version}" } 83 | 84 | 85 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 86 | # 87 | # CocoaPods is smart about how it includes source code. For source files 88 | # giving a folder will include any swift, h, m, mm, c & cpp files. 89 | # For header files it will include any header in the folder. 90 | # Not including the public_header_files will make all headers public. 91 | # 92 | 93 | spec.source_files = "LYAlertViewDemo/LYAlertView", "LYAlertViewDemo/LYAlertView/*.{swift}" 94 | # spec.exclude_files = "Classes/Exclude" 95 | 96 | # spec.public_header_files = "Classes/**/*.h" 97 | 98 | 99 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 100 | # 101 | # A list of resources included with the Pod. These are copied into the 102 | # target bundle with a build phase script. Anything else will be cleaned. 103 | # You can preserve files from being cleaned, please don't preserve 104 | # non-essential files like tests, examples and documentation. 105 | # 106 | 107 | # spec.resource = "icon.png" 108 | # spec.resources = "Resources/*.png" 109 | 110 | # spec.preserve_paths = "FilesToSave", "MoreFilesToSave" 111 | 112 | 113 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 114 | # 115 | # Link your library with frameworks, or libraries. Libraries do not include 116 | # the lib prefix of their name. 117 | # 118 | 119 | # spec.framework = "SomeFramework" 120 | # spec.frameworks = "SomeFramework", "AnotherFramework" 121 | 122 | # spec.library = "iconv" 123 | # spec.libraries = "iconv", "xml2" 124 | 125 | 126 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 127 | # 128 | # If your library depends on compiler flags you can set them in the xcconfig hash 129 | # where they will only apply to your library. If you depend on other Podspecs 130 | # you can include multiple dependencies to ensure it works. 131 | 132 | # spec.requires_arc = true 133 | 134 | # spec.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } 135 | # spec.dependency "JSONKit", "~> 1.4" 136 | 137 | end 138 | -------------------------------------------------------------------------------- /LYAlertViewDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0815A0CE25A59ADB008F1F6A /* LYAlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0815A0CD25A59ADB008F1F6A /* LYAlertView.swift */; }; 11 | 083971AE25C2A28100B628FB /* LYAlertTextFieldItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 083971AD25C2A28100B628FB /* LYAlertTextFieldItem.swift */; }; 12 | 0890BFD325AC2B93002F1E04 /* LYAlertShowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0890BFD225AC2B93002F1E04 /* LYAlertShowView.swift */; }; 13 | 0890BFD825AD3C78002F1E04 /* LYLineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0890BFD725AD3C78002F1E04 /* LYLineView.swift */; }; 14 | 0890BFDE25AD9720002F1E04 /* LYAlertAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0890BFDD25AD9720002F1E04 /* LYAlertAnimation.swift */; }; 15 | 08EFD96D25A30D51002E09A2 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08EFD96C25A30D51002E09A2 /* AppDelegate.swift */; }; 16 | 08EFD96F25A30D51002E09A2 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08EFD96E25A30D51002E09A2 /* SceneDelegate.swift */; }; 17 | 08EFD97125A30D51002E09A2 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08EFD97025A30D51002E09A2 /* ViewController.swift */; }; 18 | 08EFD97425A30D51002E09A2 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 08EFD97225A30D51002E09A2 /* Main.storyboard */; }; 19 | 08EFD97625A30D54002E09A2 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 08EFD97525A30D54002E09A2 /* Assets.xcassets */; }; 20 | 08EFD97925A30D54002E09A2 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 08EFD97725A30D54002E09A2 /* LaunchScreen.storyboard */; }; 21 | 08EFD98925A30D80002E09A2 /* LYCommonSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08EFD98225A30D80002E09A2 /* LYCommonSet.swift */; }; 22 | 08EFD98A25A30D80002E09A2 /* LYAlertTitleItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08EFD98325A30D80002E09A2 /* LYAlertTitleItem.swift */; }; 23 | 08EFD98B25A30D80002E09A2 /* StringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08EFD98425A30D80002E09A2 /* StringExtension.swift */; }; 24 | 08EFD98C25A30D80002E09A2 /* LYAlertBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08EFD98525A30D80002E09A2 /* LYAlertBuilder.swift */; }; 25 | 08EFD98D25A30D81002E09A2 /* LYAlertFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08EFD98625A30D80002E09A2 /* LYAlertFactory.swift */; }; 26 | 08EFD98E25A30D81002E09A2 /* LYAlertFactoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08EFD98725A30D80002E09A2 /* LYAlertFactoryProtocol.swift */; }; 27 | 08EFD98F25A30D81002E09A2 /* LYAlertInteractiveItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08EFD98825A30D80002E09A2 /* LYAlertInteractiveItem.swift */; }; 28 | /* End PBXBuildFile section */ 29 | 30 | /* Begin PBXFileReference section */ 31 | 0815A0CD25A59ADB008F1F6A /* LYAlertView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LYAlertView.swift; sourceTree = ""; }; 32 | 083971AD25C2A28100B628FB /* LYAlertTextFieldItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LYAlertTextFieldItem.swift; sourceTree = ""; }; 33 | 0890BFD225AC2B93002F1E04 /* LYAlertShowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LYAlertShowView.swift; sourceTree = ""; }; 34 | 0890BFD725AD3C78002F1E04 /* LYLineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LYLineView.swift; sourceTree = ""; }; 35 | 0890BFDD25AD9720002F1E04 /* LYAlertAnimation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LYAlertAnimation.swift; sourceTree = ""; }; 36 | 08EFD96925A30D51002E09A2 /* LYAlertViewDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LYAlertViewDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 37 | 08EFD96C25A30D51002E09A2 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 38 | 08EFD96E25A30D51002E09A2 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; 39 | 08EFD97025A30D51002E09A2 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 40 | 08EFD97325A30D51002E09A2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 41 | 08EFD97525A30D54002E09A2 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 42 | 08EFD97825A30D54002E09A2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 43 | 08EFD97A25A30D54002E09A2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 44 | 08EFD98225A30D80002E09A2 /* LYCommonSet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LYCommonSet.swift; sourceTree = ""; }; 45 | 08EFD98325A30D80002E09A2 /* LYAlertTitleItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LYAlertTitleItem.swift; sourceTree = ""; }; 46 | 08EFD98425A30D80002E09A2 /* StringExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringExtension.swift; sourceTree = ""; }; 47 | 08EFD98525A30D80002E09A2 /* LYAlertBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LYAlertBuilder.swift; sourceTree = ""; }; 48 | 08EFD98625A30D80002E09A2 /* LYAlertFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LYAlertFactory.swift; sourceTree = ""; }; 49 | 08EFD98725A30D80002E09A2 /* LYAlertFactoryProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LYAlertFactoryProtocol.swift; sourceTree = ""; }; 50 | 08EFD98825A30D80002E09A2 /* LYAlertInteractiveItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LYAlertInteractiveItem.swift; sourceTree = ""; }; 51 | /* End PBXFileReference section */ 52 | 53 | /* Begin PBXFrameworksBuildPhase section */ 54 | 08EFD96625A30D51002E09A2 /* Frameworks */ = { 55 | isa = PBXFrameworksBuildPhase; 56 | buildActionMask = 2147483647; 57 | files = ( 58 | ); 59 | runOnlyForDeploymentPostprocessing = 0; 60 | }; 61 | /* End PBXFrameworksBuildPhase section */ 62 | 63 | /* Begin PBXGroup section */ 64 | 08EFD96025A30D51002E09A2 = { 65 | isa = PBXGroup; 66 | children = ( 67 | 08EFD96B25A30D51002E09A2 /* LYAlertViewDemo */, 68 | 08EFD96A25A30D51002E09A2 /* Products */, 69 | ); 70 | sourceTree = ""; 71 | }; 72 | 08EFD96A25A30D51002E09A2 /* Products */ = { 73 | isa = PBXGroup; 74 | children = ( 75 | 08EFD96925A30D51002E09A2 /* LYAlertViewDemo.app */, 76 | ); 77 | name = Products; 78 | sourceTree = ""; 79 | }; 80 | 08EFD96B25A30D51002E09A2 /* LYAlertViewDemo */ = { 81 | isa = PBXGroup; 82 | children = ( 83 | 08EFD98125A30D61002E09A2 /* LYAlertView */, 84 | 08EFD96C25A30D51002E09A2 /* AppDelegate.swift */, 85 | 08EFD96E25A30D51002E09A2 /* SceneDelegate.swift */, 86 | 08EFD97025A30D51002E09A2 /* ViewController.swift */, 87 | 08EFD97225A30D51002E09A2 /* Main.storyboard */, 88 | 08EFD97525A30D54002E09A2 /* Assets.xcassets */, 89 | 08EFD97725A30D54002E09A2 /* LaunchScreen.storyboard */, 90 | 08EFD97A25A30D54002E09A2 /* Info.plist */, 91 | ); 92 | path = LYAlertViewDemo; 93 | sourceTree = ""; 94 | }; 95 | 08EFD98125A30D61002E09A2 /* LYAlertView */ = { 96 | isa = PBXGroup; 97 | children = ( 98 | 08EFD98525A30D80002E09A2 /* LYAlertBuilder.swift */, 99 | 0890BFD225AC2B93002F1E04 /* LYAlertShowView.swift */, 100 | 08EFD98625A30D80002E09A2 /* LYAlertFactory.swift */, 101 | 08EFD98725A30D80002E09A2 /* LYAlertFactoryProtocol.swift */, 102 | 08EFD98825A30D80002E09A2 /* LYAlertInteractiveItem.swift */, 103 | 08EFD98325A30D80002E09A2 /* LYAlertTitleItem.swift */, 104 | 083971AD25C2A28100B628FB /* LYAlertTextFieldItem.swift */, 105 | 0815A0CD25A59ADB008F1F6A /* LYAlertView.swift */, 106 | 08EFD98225A30D80002E09A2 /* LYCommonSet.swift */, 107 | 08EFD98425A30D80002E09A2 /* StringExtension.swift */, 108 | 0890BFD725AD3C78002F1E04 /* LYLineView.swift */, 109 | 0890BFDD25AD9720002F1E04 /* LYAlertAnimation.swift */, 110 | ); 111 | path = LYAlertView; 112 | sourceTree = ""; 113 | }; 114 | /* End PBXGroup section */ 115 | 116 | /* Begin PBXNativeTarget section */ 117 | 08EFD96825A30D51002E09A2 /* LYAlertViewDemo */ = { 118 | isa = PBXNativeTarget; 119 | buildConfigurationList = 08EFD97D25A30D54002E09A2 /* Build configuration list for PBXNativeTarget "LYAlertViewDemo" */; 120 | buildPhases = ( 121 | 08EFD96525A30D51002E09A2 /* Sources */, 122 | 08EFD96625A30D51002E09A2 /* Frameworks */, 123 | 08EFD96725A30D51002E09A2 /* Resources */, 124 | ); 125 | buildRules = ( 126 | ); 127 | dependencies = ( 128 | ); 129 | name = LYAlertViewDemo; 130 | productName = LYAlertViewDemo; 131 | productReference = 08EFD96925A30D51002E09A2 /* LYAlertViewDemo.app */; 132 | productType = "com.apple.product-type.application"; 133 | }; 134 | /* End PBXNativeTarget section */ 135 | 136 | /* Begin PBXProject section */ 137 | 08EFD96125A30D51002E09A2 /* Project object */ = { 138 | isa = PBXProject; 139 | attributes = { 140 | LastSwiftUpdateCheck = 1220; 141 | LastUpgradeCheck = 1220; 142 | TargetAttributes = { 143 | 08EFD96825A30D51002E09A2 = { 144 | CreatedOnToolsVersion = 12.2; 145 | }; 146 | }; 147 | }; 148 | buildConfigurationList = 08EFD96425A30D51002E09A2 /* Build configuration list for PBXProject "LYAlertViewDemo" */; 149 | compatibilityVersion = "Xcode 9.3"; 150 | developmentRegion = en; 151 | hasScannedForEncodings = 0; 152 | knownRegions = ( 153 | en, 154 | Base, 155 | ); 156 | mainGroup = 08EFD96025A30D51002E09A2; 157 | productRefGroup = 08EFD96A25A30D51002E09A2 /* Products */; 158 | projectDirPath = ""; 159 | projectRoot = ""; 160 | targets = ( 161 | 08EFD96825A30D51002E09A2 /* LYAlertViewDemo */, 162 | ); 163 | }; 164 | /* End PBXProject section */ 165 | 166 | /* Begin PBXResourcesBuildPhase section */ 167 | 08EFD96725A30D51002E09A2 /* Resources */ = { 168 | isa = PBXResourcesBuildPhase; 169 | buildActionMask = 2147483647; 170 | files = ( 171 | 08EFD97925A30D54002E09A2 /* LaunchScreen.storyboard in Resources */, 172 | 08EFD97625A30D54002E09A2 /* Assets.xcassets in Resources */, 173 | 08EFD97425A30D51002E09A2 /* Main.storyboard in Resources */, 174 | ); 175 | runOnlyForDeploymentPostprocessing = 0; 176 | }; 177 | /* End PBXResourcesBuildPhase section */ 178 | 179 | /* Begin PBXSourcesBuildPhase section */ 180 | 08EFD96525A30D51002E09A2 /* Sources */ = { 181 | isa = PBXSourcesBuildPhase; 182 | buildActionMask = 2147483647; 183 | files = ( 184 | 08EFD98E25A30D81002E09A2 /* LYAlertFactoryProtocol.swift in Sources */, 185 | 08EFD97125A30D51002E09A2 /* ViewController.swift in Sources */, 186 | 08EFD98A25A30D80002E09A2 /* LYAlertTitleItem.swift in Sources */, 187 | 0815A0CE25A59ADB008F1F6A /* LYAlertView.swift in Sources */, 188 | 0890BFD825AD3C78002F1E04 /* LYLineView.swift in Sources */, 189 | 08EFD98B25A30D80002E09A2 /* StringExtension.swift in Sources */, 190 | 0890BFDE25AD9720002F1E04 /* LYAlertAnimation.swift in Sources */, 191 | 08EFD96D25A30D51002E09A2 /* AppDelegate.swift in Sources */, 192 | 0890BFD325AC2B93002F1E04 /* LYAlertShowView.swift in Sources */, 193 | 08EFD98D25A30D81002E09A2 /* LYAlertFactory.swift in Sources */, 194 | 08EFD98925A30D80002E09A2 /* LYCommonSet.swift in Sources */, 195 | 08EFD98F25A30D81002E09A2 /* LYAlertInteractiveItem.swift in Sources */, 196 | 08EFD96F25A30D51002E09A2 /* SceneDelegate.swift in Sources */, 197 | 08EFD98C25A30D80002E09A2 /* LYAlertBuilder.swift in Sources */, 198 | 083971AE25C2A28100B628FB /* LYAlertTextFieldItem.swift in Sources */, 199 | ); 200 | runOnlyForDeploymentPostprocessing = 0; 201 | }; 202 | /* End PBXSourcesBuildPhase section */ 203 | 204 | /* Begin PBXVariantGroup section */ 205 | 08EFD97225A30D51002E09A2 /* Main.storyboard */ = { 206 | isa = PBXVariantGroup; 207 | children = ( 208 | 08EFD97325A30D51002E09A2 /* Base */, 209 | ); 210 | name = Main.storyboard; 211 | sourceTree = ""; 212 | }; 213 | 08EFD97725A30D54002E09A2 /* LaunchScreen.storyboard */ = { 214 | isa = PBXVariantGroup; 215 | children = ( 216 | 08EFD97825A30D54002E09A2 /* Base */, 217 | ); 218 | name = LaunchScreen.storyboard; 219 | sourceTree = ""; 220 | }; 221 | /* End PBXVariantGroup section */ 222 | 223 | /* Begin XCBuildConfiguration section */ 224 | 08EFD97B25A30D54002E09A2 /* Debug */ = { 225 | isa = XCBuildConfiguration; 226 | buildSettings = { 227 | ALWAYS_SEARCH_USER_PATHS = NO; 228 | CLANG_ANALYZER_NONNULL = YES; 229 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 230 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 231 | CLANG_CXX_LIBRARY = "libc++"; 232 | CLANG_ENABLE_MODULES = YES; 233 | CLANG_ENABLE_OBJC_ARC = YES; 234 | CLANG_ENABLE_OBJC_WEAK = YES; 235 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 236 | CLANG_WARN_BOOL_CONVERSION = YES; 237 | CLANG_WARN_COMMA = YES; 238 | CLANG_WARN_CONSTANT_CONVERSION = YES; 239 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 240 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 241 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 242 | CLANG_WARN_EMPTY_BODY = YES; 243 | CLANG_WARN_ENUM_CONVERSION = YES; 244 | CLANG_WARN_INFINITE_RECURSION = YES; 245 | CLANG_WARN_INT_CONVERSION = YES; 246 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 247 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 248 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 249 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 250 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 251 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 252 | CLANG_WARN_STRICT_PROTOTYPES = YES; 253 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 254 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 255 | CLANG_WARN_UNREACHABLE_CODE = YES; 256 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 257 | COPY_PHASE_STRIP = NO; 258 | DEBUG_INFORMATION_FORMAT = dwarf; 259 | ENABLE_STRICT_OBJC_MSGSEND = YES; 260 | ENABLE_TESTABILITY = YES; 261 | GCC_C_LANGUAGE_STANDARD = gnu11; 262 | GCC_DYNAMIC_NO_PIC = NO; 263 | GCC_NO_COMMON_BLOCKS = YES; 264 | GCC_OPTIMIZATION_LEVEL = 0; 265 | GCC_PREPROCESSOR_DEFINITIONS = ( 266 | "DEBUG=1", 267 | "$(inherited)", 268 | ); 269 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 270 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 271 | GCC_WARN_UNDECLARED_SELECTOR = YES; 272 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 273 | GCC_WARN_UNUSED_FUNCTION = YES; 274 | GCC_WARN_UNUSED_VARIABLE = YES; 275 | IPHONEOS_DEPLOYMENT_TARGET = 14.2; 276 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 277 | MTL_FAST_MATH = YES; 278 | ONLY_ACTIVE_ARCH = YES; 279 | SDKROOT = iphoneos; 280 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 281 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 282 | }; 283 | name = Debug; 284 | }; 285 | 08EFD97C25A30D54002E09A2 /* Release */ = { 286 | isa = XCBuildConfiguration; 287 | buildSettings = { 288 | ALWAYS_SEARCH_USER_PATHS = NO; 289 | CLANG_ANALYZER_NONNULL = YES; 290 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 291 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 292 | CLANG_CXX_LIBRARY = "libc++"; 293 | CLANG_ENABLE_MODULES = YES; 294 | CLANG_ENABLE_OBJC_ARC = YES; 295 | CLANG_ENABLE_OBJC_WEAK = YES; 296 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 297 | CLANG_WARN_BOOL_CONVERSION = YES; 298 | CLANG_WARN_COMMA = YES; 299 | CLANG_WARN_CONSTANT_CONVERSION = YES; 300 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 301 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 302 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 303 | CLANG_WARN_EMPTY_BODY = YES; 304 | CLANG_WARN_ENUM_CONVERSION = YES; 305 | CLANG_WARN_INFINITE_RECURSION = YES; 306 | CLANG_WARN_INT_CONVERSION = YES; 307 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 308 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 309 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 310 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 311 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 312 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 313 | CLANG_WARN_STRICT_PROTOTYPES = YES; 314 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 315 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 316 | CLANG_WARN_UNREACHABLE_CODE = YES; 317 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 318 | COPY_PHASE_STRIP = NO; 319 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 320 | ENABLE_NS_ASSERTIONS = NO; 321 | ENABLE_STRICT_OBJC_MSGSEND = YES; 322 | GCC_C_LANGUAGE_STANDARD = gnu11; 323 | GCC_NO_COMMON_BLOCKS = YES; 324 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 325 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 326 | GCC_WARN_UNDECLARED_SELECTOR = YES; 327 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 328 | GCC_WARN_UNUSED_FUNCTION = YES; 329 | GCC_WARN_UNUSED_VARIABLE = YES; 330 | IPHONEOS_DEPLOYMENT_TARGET = 14.2; 331 | MTL_ENABLE_DEBUG_INFO = NO; 332 | MTL_FAST_MATH = YES; 333 | SDKROOT = iphoneos; 334 | SWIFT_COMPILATION_MODE = wholemodule; 335 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 336 | VALIDATE_PRODUCT = YES; 337 | }; 338 | name = Release; 339 | }; 340 | 08EFD97E25A30D54002E09A2 /* Debug */ = { 341 | isa = XCBuildConfiguration; 342 | buildSettings = { 343 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 344 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 345 | CODE_SIGN_STYLE = Automatic; 346 | DEVELOPMENT_TEAM = 59VAR55L55; 347 | INFOPLIST_FILE = LYAlertViewDemo/Info.plist; 348 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 349 | LD_RUNPATH_SEARCH_PATHS = ( 350 | "$(inherited)", 351 | "@executable_path/Frameworks", 352 | ); 353 | MARKETING_VERSION = 1.0.3; 354 | PRODUCT_BUNDLE_IDENTIFIER = com.LYAlertViewDemo; 355 | PRODUCT_NAME = "$(TARGET_NAME)"; 356 | SWIFT_VERSION = 5.0; 357 | TARGETED_DEVICE_FAMILY = 1; 358 | }; 359 | name = Debug; 360 | }; 361 | 08EFD97F25A30D54002E09A2 /* Release */ = { 362 | isa = XCBuildConfiguration; 363 | buildSettings = { 364 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 365 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 366 | CODE_SIGN_STYLE = Automatic; 367 | DEVELOPMENT_TEAM = 59VAR55L55; 368 | INFOPLIST_FILE = LYAlertViewDemo/Info.plist; 369 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 370 | LD_RUNPATH_SEARCH_PATHS = ( 371 | "$(inherited)", 372 | "@executable_path/Frameworks", 373 | ); 374 | MARKETING_VERSION = 1.0.3; 375 | PRODUCT_BUNDLE_IDENTIFIER = com.LYAlertViewDemo; 376 | PRODUCT_NAME = "$(TARGET_NAME)"; 377 | SWIFT_VERSION = 5.0; 378 | TARGETED_DEVICE_FAMILY = 1; 379 | }; 380 | name = Release; 381 | }; 382 | /* End XCBuildConfiguration section */ 383 | 384 | /* Begin XCConfigurationList section */ 385 | 08EFD96425A30D51002E09A2 /* Build configuration list for PBXProject "LYAlertViewDemo" */ = { 386 | isa = XCConfigurationList; 387 | buildConfigurations = ( 388 | 08EFD97B25A30D54002E09A2 /* Debug */, 389 | 08EFD97C25A30D54002E09A2 /* Release */, 390 | ); 391 | defaultConfigurationIsVisible = 0; 392 | defaultConfigurationName = Release; 393 | }; 394 | 08EFD97D25A30D54002E09A2 /* Build configuration list for PBXNativeTarget "LYAlertViewDemo" */ = { 395 | isa = XCConfigurationList; 396 | buildConfigurations = ( 397 | 08EFD97E25A30D54002E09A2 /* Debug */, 398 | 08EFD97F25A30D54002E09A2 /* Release */, 399 | ); 400 | defaultConfigurationIsVisible = 0; 401 | defaultConfigurationName = Release; 402 | }; 403 | /* End XCConfigurationList section */ 404 | }; 405 | rootObject = 08EFD96125A30D51002E09A2 /* Project object */; 406 | } 407 | -------------------------------------------------------------------------------- /LYAlertViewDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /LYAlertViewDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /LYAlertViewDemo.xcodeproj/project.xcworkspace/xcuserdata/discover.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mikebanana/LYAlertViewDemo/b5338a48a4368490e39b3db0c1c549ef4de43487/LYAlertViewDemo.xcodeproj/project.xcworkspace/xcuserdata/discover.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /LYAlertViewDemo.xcodeproj/xcuserdata/discover.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /LYAlertViewDemo.xcodeproj/xcuserdata/discover.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | LYAlertViewDemo.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /LYAlertViewDemo/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // LYAlertViewDemo 4 | // 5 | // Created by DisCover on 2021/1/4. 6 | // 7 | 8 | import UIKit 9 | 10 | @main 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | 13 | 14 | 15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 16 | // Override point for customization after application launch. 17 | return true 18 | } 19 | 20 | // MARK: UISceneSession Lifecycle 21 | 22 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 23 | // Called when a new scene session is being created. 24 | // Use this method to select a configuration to create the new scene with. 25 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 26 | } 27 | 28 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 29 | // Called when the user discards a scene session. 30 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 31 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 32 | } 33 | 34 | 35 | } 36 | 37 | -------------------------------------------------------------------------------- /LYAlertViewDemo/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /LYAlertViewDemo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | } 93 | ], 94 | "info" : { 95 | "author" : "xcode", 96 | "version" : 1 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /LYAlertViewDemo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /LYAlertViewDemo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /LYAlertViewDemo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /LYAlertViewDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | $(MARKETING_VERSION) 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | UISceneConfigurations 28 | 29 | UIWindowSceneSessionRoleApplication 30 | 31 | 32 | UISceneConfigurationName 33 | Default Configuration 34 | UISceneDelegateClassName 35 | $(PRODUCT_MODULE_NAME).SceneDelegate 36 | UISceneStoryboardFile 37 | Main 38 | 39 | 40 | 41 | 42 | UIApplicationSupportsIndirectInputEvents 43 | 44 | UILaunchStoryboardName 45 | LaunchScreen 46 | UIMainStoryboardFile 47 | Main 48 | UIRequiredDeviceCapabilities 49 | 50 | armv7 51 | 52 | UISupportedInterfaceOrientations 53 | 54 | UIInterfaceOrientationPortrait 55 | 56 | UISupportedInterfaceOrientations~ipad 57 | 58 | UIInterfaceOrientationPortrait 59 | UIInterfaceOrientationPortraitUpsideDown 60 | UIInterfaceOrientationLandscapeLeft 61 | UIInterfaceOrientationLandscapeRight 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /LYAlertViewDemo/LYAlertView/LYAlertAnimation.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LYAlertAnimation.swift 3 | // LYAlertViewDemo 4 | // 5 | // Created by DisCover on 2021/1/12. 6 | // 7 | 8 | import UIKit 9 | public enum LYAlertAnimationPopType { 10 | case `default` 11 | case scale 12 | case shakeFromTop 13 | case shakeFromBottom 14 | case shakeFromLeft 15 | case shakeFromRight 16 | case dropFromLeft 17 | case dropFromRight 18 | 19 | } 20 | public enum LYAlertAnimationDissType { 21 | case `default` 22 | case scale 23 | case shakeToTop 24 | case shakeToBottom 25 | case shakeToLeft 26 | case shakeToRight 27 | case dropFromLeft 28 | case dropFromRight 29 | 30 | } 31 | 32 | class LYAlertAnimation:NSObject { 33 | 34 | private var targerView:UIView = UIView() 35 | 36 | func show(_ type:LYAlertAnimationPopType,_ during:CFTimeInterval,_ target:UIView){ 37 | let start = target.layer.position 38 | 39 | switch type { 40 | case .default: 41 | UIView.animate(withDuration: during) { 42 | target.alpha = 1 43 | } 44 | case .scale: 45 | target.alpha = 1 46 | animation(target.layer, during, [0.8,1.25,1.0]) 47 | case .shakeFromTop: 48 | target.alpha = 1 49 | target.layer.position = CGPoint(x: start.x, y: -start.y) 50 | dampingAnimation(target, during, start) 51 | case .shakeFromBottom: 52 | target.alpha = 1 53 | target.layer.position = CGPoint(x: start.x, y: LYCommonSet.Kheith + start.y) 54 | dampingAnimation(target, during, start) 55 | case .shakeFromLeft: 56 | target.alpha = 1 57 | target.layer.position = CGPoint(x: -start.x, y: start.y) 58 | dampingAnimation(target, during, start) 59 | case .shakeFromRight: 60 | target.alpha = 1 61 | target.layer.position = CGPoint(x:LYCommonSet.Kwidth+start.x, y: start.y) 62 | dampingAnimation(target, during, start) 63 | case.dropFromLeft: 64 | target.alpha = 1 65 | target.layer.position = CGPoint(x: start.x, y: -start.y) 66 | target.transform = CGAffineTransform.init(rotationAngle: 15/180.0 * CGFloat.pi) 67 | 68 | dropAnimation(target, during, start, .dropFromLeft) 69 | case.dropFromRight: 70 | target.alpha = 1 71 | target.layer.position = CGPoint(x: start.x, y: -start.y) 72 | target.transform = CGAffineTransform.init(rotationAngle: -15/180.0 * CGFloat.pi) 73 | 74 | dropAnimation(target, during, start, .dropFromRight) 75 | } 76 | self.targerView = target 77 | } 78 | 79 | 80 | func hide(_ type:LYAlertAnimationDissType,_ during:CFTimeInterval,_ target:UIView){ 81 | let start = target.layer.position 82 | var end = target.layer.position 83 | switch type { 84 | case .default: 85 | UIView.animate(withDuration: during) { 86 | target.alpha = 0 87 | } completion: { (isCom) in 88 | target.removeFromSuperview() 89 | } 90 | 91 | case .scale: 92 | 93 | animation(target.layer, during, [1.0,0.66,0.33,0.01]) 94 | case .shakeToTop: 95 | end = CGPoint(x: start.x, y: -start.y) 96 | dampingAnimationDiss(target, during, start,end, type) 97 | case .shakeToBottom: 98 | 99 | end = CGPoint(x: start.x, y: LYCommonSet.Kheith + start.y) 100 | dampingAnimationDiss(target, during, start,end, type) 101 | case .shakeToLeft: 102 | 103 | end = CGPoint(x: -start.x, y: start.y) 104 | dampingAnimationDiss(target, during, start,end, type) 105 | case .shakeToRight: 106 | 107 | end = CGPoint(x:LYCommonSet.Kwidth+start.x, y: start.y) 108 | dampingAnimationDiss(target, during, start,end, type) 109 | case.dropFromLeft: 110 | 111 | end = CGPoint(x: start.x, y: LYCommonSet.Kheith + start.y) 112 | 113 | dropAnimationDiss(target, during, end, type) 114 | case.dropFromRight: 115 | 116 | end = CGPoint(x: start.x, y: LYCommonSet.Kheith + start.y) 117 | 118 | dropAnimationDiss(target, during, end, type) 119 | } 120 | } 121 | 122 | 123 | 124 | private func dropAnimation(_ target:UIView,_ duration:TimeInterval,_ start:CGPoint,_ type:LYAlertAnimationPopType){ 125 | UIView.animate(withDuration: duration, delay: 0, usingSpringWithDamping: 0.75, initialSpringVelocity: 1.0, options: .curveEaseIn) { 126 | target.layer.position = start 127 | } completion: { (isCom) in 128 | } 129 | UIView.animate(withDuration: duration*0.6) { 130 | target.layer.transform = CATransform3DMakeRotation(type == .dropFromLeft ? 6/180.0 * CGFloat.pi : -6/180.0 * CGFloat.pi , 0, 0, 0) 131 | } completion: { (isCom) in 132 | UIView.animate(withDuration: duration*0.2) { 133 | target.transform = CGAffineTransform.init(rotationAngle: type == .dropFromLeft ? 1/180.0 * CGFloat.pi : -1/180.0 * CGFloat.pi) 134 | 135 | } completion: { (isCom) in 136 | UIView.animate(withDuration: duration*0.2) { 137 | target.transform = CGAffineTransform.identity 138 | } 139 | } 140 | 141 | 142 | } 143 | 144 | } 145 | private func dropAnimationDiss(_ target:UIView,_ duration:TimeInterval,_ end:CGPoint,_ type:LYAlertAnimationDissType){ 146 | UIView.animate(withDuration: duration) { 147 | target.layer.position = end 148 | } completion: { (isCom) in 149 | 150 | } 151 | animationRo(target.layer, duration, type == .dropFromLeft ? 15/180.0 * CGFloat.pi : -15/180.0 * CGFloat.pi) 152 | 153 | 154 | 155 | } 156 | 157 | private func dampingAnimation(_ target:UIView,_ duration:TimeInterval,_ start:CGPoint){ 158 | UIView.animate(withDuration: duration, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 1.0, options: .curveEaseIn) { 159 | target.layer.position = start 160 | } completion: { (isCom) in 161 | 162 | } 163 | } 164 | private func dampingAnimationDiss(_ target:UIView,_ duration:TimeInterval,_ start:CGPoint,_ end:CGPoint,_ type:LYAlertAnimationDissType){ 165 | UIView.animate(withDuration: duration*0.2) { 166 | switch type{ 167 | case .shakeToTop: 168 | target.layer.position = CGPoint(x: start.x, y: start.y+50.0) 169 | case .shakeToBottom: 170 | target.layer.position = CGPoint(x: start.x, y: start.y-50.0) 171 | case .shakeToLeft: 172 | target.layer.position = CGPoint(x: start.x+50.0, y: start.y) 173 | case .shakeToRight: 174 | target.layer.position = CGPoint(x: start.x-50.0, y: start.y) 175 | default: 176 | break 177 | } 178 | } completion: { (isCom) in 179 | UIView.animate(withDuration: duration*0.8) { 180 | target.layer.position = end 181 | } 182 | } 183 | 184 | } 185 | private func animationRo(_ layer:CALayer,_ duration:CFTimeInterval,_ rangle:CGFloat){ 186 | let animation = CABasicAnimation.init(keyPath: "transform.rotation.z") 187 | animation.duration = duration 188 | animation.isRemovedOnCompletion = false 189 | animation.fillMode = .forwards 190 | animation.fromValue = 0 191 | animation.toValue = rangle 192 | 193 | 194 | animation.timingFunction = CAMediaTimingFunction.init(name: .easeIn) 195 | layer.add(animation, forKey: nil) 196 | } 197 | private func animation(_ layer:CALayer,_ duration:CFTimeInterval,_ values:[CGFloat]){ 198 | let animation = CAKeyframeAnimation.init(keyPath: "transform") 199 | animation.duration = duration 200 | animation.isRemovedOnCompletion = false 201 | animation.fillMode = .forwards 202 | var arr = [NSValue]() 203 | for i in values{ 204 | arr.append(NSValue.init(caTransform3D: CATransform3DMakeScale(i, i, 1))) 205 | 206 | } 207 | animation.values = arr 208 | 209 | 210 | animation.timingFunction = CAMediaTimingFunction.init(name: .easeIn) 211 | layer.add(animation, forKey: nil) 212 | } 213 | 214 | } 215 | -------------------------------------------------------------------------------- /LYAlertViewDemo/LYAlertView/LYAlertBuilder.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LYAlertBuilder.swift 3 | // LYAlertViewDemo 4 | // 5 | // Created by DisCover on 2021/1/4. 6 | // Copyright © 2021 ly. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | 12 | public class LYAlertBuilder { 13 | var alertView:LYAlertShowView? 14 | public init(_ title:(UIView&LYAlertItemProtocol)?,_ content:UIView&LYAlertItemProtocol,_ buttons:[UIView&LYAlertInteractiveItemProtocol]) { 15 | alertView = LYAlertShowView.init(title, content, buttons) 16 | } 17 | 18 | public func borderColor(_ color:UIColor) -> Self { 19 | self.alertView?.alertView.layer.borderColor = color.cgColor 20 | return self 21 | } 22 | public func borderWidth(_ width:CGFloat) -> Self { 23 | self.alertView?.alertView.layer.borderWidth = width 24 | return self 25 | } 26 | public func cornerRadius(_ radius:CGFloat) -> Self { 27 | self.alertView?.alertView.layer.cornerRadius = radius 28 | return self 29 | } 30 | public func shadowPath(_ path:CGPath) -> Self { 31 | self.alertView?.alertView.layer.shadowPath = path 32 | return self 33 | } 34 | public func shadowOffset(_ size:CGSize) -> Self { 35 | self.alertView?.alertView.layer.shadowOffset = size 36 | return self 37 | } 38 | public func shadowRadius(_ radius:CGFloat) -> Self { 39 | self.alertView?.alertView.layer.shadowRadius = radius 40 | return self 41 | } 42 | public func shadowOpacity(_ opacity:Float) -> Self { 43 | self.alertView?.alertView.layer.shadowOpacity = opacity 44 | return self 45 | } 46 | public func shadowColor(_ color:UIColor) -> Self { 47 | self.alertView?.alertView.layer.shadowColor = color.cgColor 48 | return self 49 | } 50 | public func maskAlpha(_ alpha:CGFloat) -> Self { 51 | self.alertView?.blackView.backgroundColor = LYCommonSet.RGBA(r: 0, g: 0, b: 0, a: alpha) 52 | return self 53 | } 54 | public func tapMaskHide(_ isHide:Bool) -> Self { 55 | self.alertView?.isHide = isHide 56 | return self 57 | } 58 | public func showAnimation(_ type:LYAlertAnimationPopType,_ during:CFTimeInterval)->Self{ 59 | self.alertView?.showType = type 60 | self.alertView?.showDuring = during 61 | return self 62 | } 63 | public func hideAnimation(_ type:LYAlertAnimationDissType,_ during:CFTimeInterval)->Self{ 64 | self.alertView?.hideType = type 65 | self.alertView?.hideDuring = during 66 | return self 67 | } 68 | 69 | public func build()-> LYAlertShowView?{ 70 | return alertView 71 | } 72 | 73 | } 74 | 75 | -------------------------------------------------------------------------------- /LYAlertViewDemo/LYAlertView/LYAlertFactory.swift: -------------------------------------------------------------------------------- 1 | //// 2 | //// LYAlertFactory.swift 3 | //// LYAlertViewDemo 4 | //// 5 | //// Created by DisCover on 2020/12/17. 6 | //// Copyright © 2020 ly. All rights reserved. 7 | //// 8 | // 9 | import Foundation 10 | import UIKit 11 | //具体工厂类 12 | public class LYAlertFactory:LYAlertFactoryProtocol{ 13 | public init() {} 14 | //创建展示 item 15 | public func creatAlertShowItem(_ type: LYAlertTitleItemType, _ text: String) -> UIView&LYAlertTitleShowProtocol { 16 | return LYAlertTitleItem.init(type, text: text) 17 | } 18 | //创建交互 item 19 | public func creatAlertInteractiveItem(_ text: String) -> UIView&LYAlertInteractiveItemProtocol { 20 | return LYAlertInteractiveItem.init(text) 21 | } 22 | //创建输入 item 23 | public func creatAlertFieldItem(_ placeholder: String)->UIView&LYAlertTextFieldProtocol{ 24 | return LYAlertTextFieldItem.init(placeholder) 25 | } 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /LYAlertViewDemo/LYAlertView/LYAlertFactoryProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // File.swift 3 | // LYAlertViewDemo 4 | // 5 | // Created by DisCover on 2020/12/17. 6 | // Copyright © 2020 ly. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | public protocol LYAlertFactoryProtocol { 12 | func creatAlertShowItem(_ type:LYAlertTitleItemType, _ text:String) -> UIView&LYAlertTitleShowProtocol 13 | func creatAlertInteractiveItem(_ text: String)->UIView&LYAlertInteractiveItemProtocol 14 | func creatAlertFieldItem(_ placeholder: String)->UIView&LYAlertTextFieldProtocol 15 | 16 | } 17 | 18 | public protocol LYAlertItemProtocol{ 19 | func titleColor(_ color:UIColor) -> Self 20 | func fontSize(_ font:CGFloat) -> Self 21 | func line(_ color:UIColor,_ width:CGFloat) -> Self 22 | 23 | func attribute(_ attribute:[NSAttributedString.Key :Any])->Self 24 | } 25 | 26 | extension LYAlertItemProtocol{ 27 | func attribute(_ attribute:[NSAttributedString.Key :Any])->Self{ 28 | return self 29 | } 30 | func line(_ color:UIColor,_ width:CGFloat) -> Self{ 31 | return self 32 | } 33 | 34 | } 35 | 36 | public protocol LYAlertTextFieldProtocol:LYAlertItemProtocol { 37 | func borderStyle(_ style:UITextField.BorderStyle)->Self 38 | func attributedPlaceholder(_ str:NSAttributedString)->Self 39 | func clearsOnBeginEditing(_ clear:Bool)->Self 40 | func delegate(_ delegate:UIResponder)->Self 41 | func keyboardType(_ type:UIKeyboardType)->Self 42 | 43 | 44 | 45 | } 46 | 47 | 48 | public protocol LYAlertTitleShowProtocol:LYAlertItemProtocol { 49 | func textAlignment(_ alignment:NSTextAlignment) -> Self 50 | } 51 | public protocol LYAlertInteractiveItemProtocol:LYAlertItemProtocol { 52 | func btnBackgroundColor(_ color:UIColor) -> Self 53 | func itemBackgroundColor(_ color:UIColor) -> Self 54 | func btnRadius(_ radius:CGFloat) -> Self 55 | func btnBorderWidth(_ borderWidth:CGFloat) -> Self 56 | func btnBorderColor(_ color:UIColor) -> Self 57 | func line(_ color:UIColor,_ width:CGFloat,_ type:LYLineType) -> Self 58 | func btnHeight(_ height:CGFloat)->Self 59 | func btnMarin(_ marin:CGFloat)->Self 60 | 61 | func action(clo:@escaping LYCommonSet.btnClosure) -> Self 62 | } 63 | -------------------------------------------------------------------------------- /LYAlertViewDemo/LYAlertView/LYAlertInteractiveItem.swift: -------------------------------------------------------------------------------- 1 | //// 2 | //// LYAlertInteractiveItem.swift 3 | //// LYAlertViewDemo 4 | //// 5 | //// Created by DisCover on 2020/12/18. 6 | //// Copyright © 2020 ly. All rights reserved. 7 | //// 8 | 9 | import UIKit 10 | 11 | class LYAlertInteractiveItem: UIView,LYAlertInteractiveItemProtocol { 12 | func titleColor(_ color: UIColor) -> Self { 13 | button.setTitleColor(color, for: .normal) 14 | return self 15 | } 16 | func btnBackgroundColor(_ color:UIColor) -> Self{ 17 | button.backgroundColor = color 18 | return self 19 | 20 | } 21 | func itemBackgroundColor(_ color:UIColor) -> Self{ 22 | self.backgroundColor = color 23 | return self 24 | } 25 | func btnRadius(_ radius:CGFloat) -> Self{ 26 | button.layer.cornerRadius = radius 27 | return self 28 | } 29 | func btnBorderWidth(_ borderWidth:CGFloat) -> Self{ 30 | button.layer.borderWidth = borderWidth 31 | return self 32 | } 33 | func btnBorderColor(_ color:UIColor) -> Self{ 34 | button.layer.borderColor = color.cgColor 35 | return self 36 | } 37 | 38 | func fontSize(_ font: CGFloat) -> Self { 39 | button.titleLabel?.font = UIFont.systemFont(ofSize: font) 40 | return self 41 | } 42 | func line(_ color:UIColor,_ width:CGFloat,_ type:LYLineType) -> Self{ 43 | let line = LYLineView.init(width, color, type, self) 44 | layer.addSublayer(line) 45 | return self 46 | } 47 | func btnHeight(_ height:CGFloat)->Self{ 48 | self.buttonHeigth = height 49 | LYCommonSet.InteractiveItemHeight = buttonHeigth + buttonMarin*2 50 | 51 | self.frame = CGRect(x: 0, y: 0, width: LYCommonSet.Awidth, height: LYCommonSet.InteractiveItemHeight) 52 | return self 53 | } 54 | func btnMarin(_ marin:CGFloat)->Self{ 55 | self.buttonMarin = marin 56 | LYCommonSet.InteractiveItemHeight = buttonHeigth + buttonMarin*2 57 | 58 | self.frame = CGRect(x: 0, y: 0, width: LYCommonSet.Awidth, height: LYCommonSet.InteractiveItemHeight) 59 | return self 60 | } 61 | func attribute(_ attribute:[NSAttributedString.Key :Any])->Self{ 62 | let aString = NSAttributedString(string: text, attributes: attribute) 63 | self.button.setAttributedTitle(aString, for: .normal) 64 | return self 65 | } 66 | 67 | @discardableResult 68 | func action(clo:@escaping LYCommonSet.btnClosure) -> Self { 69 | 70 | self.closure = { [weak self] in 71 | clo() 72 | if let hide = self?.hideClosure{ 73 | hide() 74 | } 75 | } 76 | 77 | return self 78 | } 79 | 80 | private var button = UIButton() 81 | private var text = "" 82 | public var closure:LYCommonSet.btnClosure? 83 | public var hideClosure:LYCommonSet.btnClosure? 84 | private var buttonHeigth :CGFloat = LYCommonSet.buttonHeight 85 | private var buttonMarin:CGFloat = LYCommonSet.buttonMarin 86 | 87 | override init(frame: CGRect) { 88 | super.init(frame: frame) 89 | 90 | button.addTarget(self, action: #selector(btnClick), for: .touchUpInside) 91 | addSubview(button) 92 | } 93 | convenience init(_ text:String){ 94 | 95 | self.init(frame: CGRect(x: 0, y: 0, width: LYCommonSet.Awidth, height:LYCommonSet.InteractiveItemHeight)) 96 | self.text = text 97 | button.setTitle(text, for: .normal) 98 | 99 | 100 | } 101 | 102 | required init?(coder: NSCoder) { 103 | fatalError("init(coder:) has not been implemented") 104 | } 105 | override func layoutSubviews() { 106 | super.layoutSubviews() 107 | self.button.frame = CGRect(x: self.buttonMarin, y: self.buttonMarin, width: self.frame.width - 2*self.buttonMarin, height: self.buttonHeigth) 108 | 109 | 110 | } 111 | 112 | @objc private func btnClick(){ 113 | if let clo = closure{ 114 | clo() 115 | } 116 | } 117 | 118 | 119 | } 120 | -------------------------------------------------------------------------------- /LYAlertViewDemo/LYAlertView/LYAlertShowView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LYAlertShowView.swift 3 | // LYAlertViewDemo 4 | // 5 | // Created by DisCover on 2021/1/11. 6 | // 7 | 8 | import UIKit 9 | 10 | public class LYAlertShowView: UIView { 11 | var title:(UIView&LYAlertItemProtocol)? 12 | 13 | var content:(UIView&LYAlertItemProtocol)? 14 | 15 | var buttons:[LYAlertInteractiveItem]? 16 | 17 | var animation:LYAlertAnimation? 18 | 19 | var showType:LYAlertAnimationPopType = .default 20 | var hideType:LYAlertAnimationDissType = .default 21 | var showDuring:CFTimeInterval = 0.2 22 | var hideDuring:CFTimeInterval = 0.2 23 | 24 | var isHide = false 25 | 26 | lazy var blackView:UIView = { 27 | let blackView = UIView(frame: UIScreen.main.bounds) 28 | blackView.alpha = 0 29 | blackView.backgroundColor = LYCommonSet.RGBA(r: 0, g: 0, b: 0, a: 0.2) 30 | blackView.isUserInteractionEnabled = true 31 | let tap = UITapGestureRecognizer() 32 | tap.addTarget(self, action:#selector(tapBlack)) 33 | blackView.addGestureRecognizer(tap) 34 | return blackView 35 | 36 | }() 37 | lazy var alertView : LYAlertView = { 38 | let alertView = LYAlertView.init(self.title, self.content!, self.buttons!) 39 | alertView.backgroundColor = LYCommonSet.alertDefaultBackgroundColor 40 | alertView.alpha = 0 41 | return alertView 42 | }() 43 | 44 | override init(frame: CGRect) { 45 | super.init(frame: frame) 46 | self.animation = LYAlertAnimation() 47 | 48 | 49 | } 50 | convenience init(_ title:(UIView&LYAlertItemProtocol)?,_ content:UIView&LYAlertItemProtocol,_ buttons:[UIView&LYAlertInteractiveItemProtocol]){ 51 | self.init(frame: UIScreen.main.bounds) 52 | self.title = title 53 | self.content = content 54 | self.buttons = buttons as? [LYAlertInteractiveItem] 55 | if let b = self.buttons{ 56 | for btn in b{ 57 | btn.hideClosure = {[weak self] in 58 | self?.hide() 59 | } 60 | } 61 | } 62 | addSubview(blackView) 63 | addSubview(alertView) 64 | 65 | 66 | 67 | } 68 | 69 | required init?(coder: NSCoder) { 70 | fatalError("init(coder:) has not been implemented") 71 | } 72 | 73 | @objc func tapBlack(){ 74 | self.endEditing(true) 75 | 76 | if isHide{ 77 | hide() 78 | } 79 | 80 | } 81 | 82 | 83 | public func show(){ 84 | 85 | LYCommonSet.keyWindows()?.addSubview(self) 86 | 87 | self.animation?.show(self.showType, showDuring, self.alertView) 88 | 89 | UIView.animate(withDuration: showDuring, animations: { 90 | self.blackView.alpha = 1 91 | }) { (isCom) in 92 | } 93 | } 94 | 95 | 96 | public func hide(){ 97 | self.animation?.hide(hideType, hideDuring, self.alertView) 98 | self.endEditing(true) 99 | UIView.animate(withDuration: hideDuring, animations: { 100 | self.blackView.alpha = 0 101 | }) { (isCom) in 102 | self.removeFromSuperview() 103 | } 104 | 105 | } 106 | 107 | 108 | 109 | 110 | } 111 | -------------------------------------------------------------------------------- /LYAlertViewDemo/LYAlertView/LYAlertTextFieldItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LYAlertTextFieldItem.swift 3 | // LYAlertViewDemo 4 | // 5 | // Created by DisCover on 2021/1/28. 6 | // 7 | 8 | import UIKit 9 | 10 | class LYAlertTextFieldItem: UIView,LYAlertTextFieldProtocol { 11 | func delegate(_ delegate: UIResponder) -> Self { 12 | self.textField.delegate = delegate as? UITextFieldDelegate 13 | return self 14 | } 15 | 16 | 17 | func borderStyle(_ style: UITextField.BorderStyle) -> Self { 18 | self.textField.borderStyle = style 19 | return self 20 | } 21 | 22 | func attributedPlaceholder(_ str: NSAttributedString) -> Self { 23 | self.textField.attributedPlaceholder = str 24 | return self 25 | } 26 | 27 | func clearsOnBeginEditing(_ clear: Bool) -> Self { 28 | self.textField.clearsOnBeginEditing = clear 29 | return self 30 | } 31 | 32 | func titleColor(_ color: UIColor) -> Self { 33 | self.textField.textColor = color 34 | return self 35 | } 36 | 37 | func fontSize(_ font: CGFloat) -> Self { 38 | self.textField.font = UIFont.systemFont(ofSize: font) 39 | return self 40 | } 41 | func line(_ color:UIColor,_ width:CGFloat) -> Self{ 42 | let line = LYLineView.init(width, color, .bottom, self) 43 | layer.addSublayer(line) 44 | return self 45 | } 46 | func keyboardType(_ type:UIKeyboardType)->Self{ 47 | self.textField.keyboardType = type 48 | return self 49 | } 50 | 51 | var textField = UITextField() 52 | 53 | override init(frame: CGRect) { 54 | super.init(frame: frame) 55 | self.addSubview(textField) 56 | 57 | 58 | } 59 | 60 | required init?(coder: NSCoder) { 61 | fatalError("init(coder:) has not been implemented") 62 | } 63 | 64 | convenience init(_ placeholder:String){ 65 | 66 | self.init(frame:CGRect(x: 0, y: 0, width: LYCommonSet.Awidth, height: LYCommonSet.titleSize.height + 2 * LYCommonSet.buttonMarin)) 67 | self.textField.placeholder = placeholder 68 | 69 | 70 | 71 | } 72 | override func layoutSubviews() { 73 | super.layoutSubviews() 74 | self.textField.frame = CGRect(x: LYCommonSet.buttonMarin, y: 2*LYCommonSet.buttonMarin, width: LYCommonSet.Awidth - 2*(LYCommonSet.buttonMarin), height: self.frame.height - 4*(LYCommonSet.buttonMarin)) 75 | } 76 | 77 | } 78 | 79 | -------------------------------------------------------------------------------- /LYAlertViewDemo/LYAlertView/LYAlertTitleItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LYAlertTitleItem.swift 3 | // LYAlertViewDemo 4 | // 5 | // Created by DisCover on 2020/12/17. 6 | // Copyright © 2020 ly. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public enum LYAlertTitleItemType { 12 | case title 13 | case content 14 | } 15 | 16 | class LYAlertTitleItem: UIView,LYAlertTitleShowProtocol { 17 | 18 | 19 | func fontSize(_ font:CGFloat) -> Self { 20 | self.font = font 21 | self.label.font = UIFont.systemFont(ofSize: font) 22 | return self 23 | } 24 | func titleColor(_ color:UIColor) -> Self { 25 | self.label.textColor = color 26 | return self 27 | } 28 | func textAlignment(_ alignment:NSTextAlignment) -> Self { 29 | self.label.textAlignment = alignment 30 | return self 31 | } 32 | 33 | func line(_ color:UIColor,_ width:CGFloat) -> Self{ 34 | let line = LYLineView.init(width, color, .bottom, self) 35 | layer.addSublayer(line) 36 | return self 37 | } 38 | func attribute(_ attribute:[NSAttributedString.Key :Any])->Self{ 39 | let aString = NSAttributedString(string: text, attributes: attribute) 40 | self.label.attributedText = aString 41 | let rect = aString.returnAttRect(width: LYCommonSet.Awidth - 2.0*LYCommonSet.buttonMarin) 42 | self.frame = CGRect(x: 0, y: 0, width: LYCommonSet.Awidth, height: rect.height + 3.0 * LYCommonSet.buttonMarin) 43 | return self 44 | } 45 | 46 | private var label = UILabel() 47 | private var type:LYAlertTitleItemType = .title 48 | private var text = "" 49 | private var font:CGFloat = LYCommonSet.titleFont{ 50 | didSet{ 51 | switch type { 52 | case .title: 53 | self.frame = LYCommonSet.titleSize 54 | case .content: 55 | let rect = text.returnRect(font: font, width: LYCommonSet.Awidth - 2.0*LYCommonSet.buttonMarin) 56 | self.frame = CGRect(x: 0, y: 0, width: LYCommonSet.Awidth, height: rect.height + 3.0 * LYCommonSet.buttonMarin) 57 | 58 | } 59 | 60 | } 61 | } 62 | 63 | override init(frame: CGRect) { 64 | super.init(frame: frame) 65 | 66 | label.textAlignment = .center 67 | label.numberOfLines = 0 68 | 69 | addSubview(label) 70 | 71 | } 72 | convenience init(_ type:LYAlertTitleItemType,text:String){ 73 | 74 | self.init(frame: .zero) 75 | self.type = type 76 | self.text = text 77 | self.font = LYCommonSet.titleFont 78 | label.text = text 79 | } 80 | 81 | required init?(coder: NSCoder) { 82 | fatalError("init(coder:) has not been implemented") 83 | } 84 | 85 | override func layoutSubviews() { 86 | superview?.layoutSubviews() 87 | label.frame = CGRect(x: LYCommonSet.buttonMarin, y: LYCommonSet.buttonMarin, width: frame.width - 2.0*LYCommonSet.buttonMarin, height: frame.height - 2.0*LYCommonSet.buttonMarin) 88 | 89 | } 90 | 91 | 92 | } 93 | -------------------------------------------------------------------------------- /LYAlertViewDemo/LYAlertView/LYAlertView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LYAlertView.swift 3 | // LYAlertViewDemo 4 | // 5 | // Created by DisCover on 2021/1/6. 6 | // 7 | 8 | import UIKit 9 | 10 | class LYAlertView: UIView { 11 | var title:(UIView&LYAlertItemProtocol)? 12 | 13 | var content:(UIView&LYAlertItemProtocol)? 14 | 15 | var buttons:[LYAlertInteractiveItem]? 16 | 17 | 18 | override init(frame: CGRect) { 19 | super.init(frame: frame) 20 | self.clipsToBounds = true 21 | NotificationCenter.default.addObserver(self, selector: #selector(keyBoard(not:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil) 22 | 23 | } 24 | 25 | required init?(coder: NSCoder) { 26 | fatalError("init(coder:) has not been implemented") 27 | } 28 | 29 | @objc func keyBoard(not:Notification){ 30 | 31 | let duration = not.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as! TimeInterval 32 | 33 | let endFrame = (not.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue 34 | 35 | let keyboardHeight = endFrame.origin.y 36 | let margin = LYCommonSet.Kheith - keyboardHeight 37 | 38 | if margin != 0{ 39 | 40 | let offsetY = self.frame.origin.y - (LYCommonSet.Kheith - margin - self.frame.height) 41 | 42 | UIView.animate(withDuration: duration) { 43 | self.transform = CGAffineTransform.init(translationX: 0, y: -offsetY) 44 | } 45 | 46 | }else{ 47 | UIView.animate(withDuration: duration) { 48 | self.transform = CGAffineTransform.identity 49 | } 50 | } 51 | 52 | 53 | } 54 | convenience init(_ title:(UIView&LYAlertItemProtocol)?,_ content:UIView&LYAlertItemProtocol,_ buttons:[LYAlertInteractiveItem]){ 55 | self.init(frame: CGRect.zero) 56 | self.title = title 57 | self.content = content 58 | self.buttons = buttons 59 | if title != nil{ 60 | self.addSubview(title!) 61 | } 62 | 63 | self.addSubview(content) 64 | for btn in buttons{ 65 | self.addSubview(btn) 66 | } 67 | var alertHeight:CGFloat = 0 68 | if buttons.count == 2{ 69 | alertHeight = (title?.frame.height ?? 0) + content.frame.height + LYCommonSet.InteractiveItemHeight 70 | }else{ 71 | alertHeight = (title?.frame.height ?? 0) + content.frame.height + CGFloat(buttons.count) * LYCommonSet.InteractiveItemHeight 72 | } 73 | self.frame = CGRect(x: (LYCommonSet.Kwidth - LYCommonSet.Awidth)/2.0, y: (LYCommonSet.Kheith - alertHeight)/2.0, width: LYCommonSet.Awidth, height: alertHeight) 74 | 75 | 76 | } 77 | override func layoutSubviews() { 78 | super.layoutSubviews() 79 | 80 | if let c = content,let b = buttons{ 81 | c.frame = CGRect(x: 0, y: title?.frame.maxY ?? 0, width: c.frame.width, height: c.frame.height) 82 | 83 | if b.count == 2{ 84 | for(i,btn) in b.enumerated(){ 85 | btn.frame = CGRect(x: CGFloat(i)*(self.frame.width/2), y: c.frame.maxY, width: self.frame.width/2, height: LYCommonSet.InteractiveItemHeight) 86 | } 87 | }else{ 88 | for(i,btn) in b.enumerated(){ 89 | btn.frame = CGRect(x: 0, y: c.frame.maxY + CGFloat(i)*LYCommonSet.InteractiveItemHeight, width: self.frame.width, height: LYCommonSet.InteractiveItemHeight) 90 | } 91 | } 92 | } 93 | 94 | } 95 | deinit { 96 | NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillChangeFrameNotification, object: nil) 97 | 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /LYAlertViewDemo/LYAlertView/LYCommonSet.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LYCommonSet.swift 3 | // LYAlertViewDemo 4 | // 5 | // Created by DisCover on 2021/1/4. 6 | // Copyright © 2021 ly. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public enum LYCommonSet { 12 | //弹框默认宽度 13 | static let Awidth:CGFloat = 270.0 14 | //标题默认 size 15 | static let titleSize = CGRect(x: 0, y: 0, width: Awidth, height: 50) 16 | 17 | //标题默认字体大小 18 | static let titleFont:CGFloat = 17.0 19 | //按钮间隔 20 | static let buttonMarin:CGFloat = 15 21 | //field间隔 22 | static let fieldMarin:CGFloat = 30 23 | 24 | //响应 item 的高度 25 | static var InteractiveItemHeight:CGFloat = 74 26 | //按钮的高度 27 | static let buttonHeight:CGFloat = 44 28 | //屏宽 29 | static let Kwidth = UIScreen.main.bounds.size.width 30 | //屏高 31 | static let Kheith = UIScreen.main.bounds.size.height 32 | static let alertDefaultBackgroundColor = LYCommonSet.RGBA(r: 240, g: 240, b: 240, a: 1) 33 | //RGB 34 | static func RGBA (r:CGFloat, g:CGFloat, b:CGFloat, a:CGFloat)->UIColor { return UIColor.init(red: r/255.0, green: g/255.0, blue: b/255.0, alpha: a) } 35 | 36 | 37 | public typealias btnClosure = ()->() 38 | //主屏幕 39 | static func keyWindows()->UIWindow?{ 40 | if #available(iOS 13.0, *) { 41 | let arr = Array(UIApplication.shared.connectedScenes) 42 | let scene:UIWindowScene = arr.first as! UIWindowScene 43 | let keyWindow = scene.windows[0] 44 | return keyWindow 45 | 46 | }else{ 47 | return UIApplication.shared.keyWindow 48 | } 49 | 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /LYAlertViewDemo/LYAlertView/LYLineView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LYLineView.swift 3 | // LYAlertViewDemo 4 | // 5 | // Created by DisCover on 2021/1/12. 6 | // 7 | 8 | import UIKit 9 | 10 | public enum LYLineType { 11 | case bottom 12 | case left 13 | } 14 | 15 | class LYLineView: CALayer { 16 | 17 | 18 | 19 | init(_ lineWidth:CGFloat,_ color:UIColor ,_ type:LYLineType,_ superView:UIView){ 20 | super.init() 21 | switch type { 22 | case .left: 23 | self.frame = CGRect(x: LYCommonSet.Awidth/2.0 - lineWidth ,y: 0, width: lineWidth, height: superView.frame.height) 24 | default: 25 | self.frame = CGRect(x: 0,y: superView.frame.height - lineWidth, width: superView.frame.width, height: lineWidth) 26 | 27 | } 28 | self.backgroundColor = color.cgColor 29 | 30 | 31 | } 32 | 33 | required init?(coder: NSCoder) { 34 | fatalError("init(coder:) has not been implemented") 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /LYAlertViewDemo/LYAlertView/StringExtension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StringExtension.swift 3 | // LYAlertViewDemo 4 | // 5 | // Created by DisCover on 2021/1/4. 6 | // Copyright © 2021 ly. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension String{ 12 | func returnRect(font:CGFloat,width:CGFloat)->CGRect{ 13 | return (self as NSString).boundingRect(with: CGSize(width: width, height: 1000), options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font : UIFont.systemFont(ofSize: font)], context: nil) 14 | } 15 | 16 | } 17 | extension NSAttributedString{ 18 | func returnAttRect(width:CGFloat)->CGRect{ 19 | return self.boundingRect(with: CGSize(width: width, height: 1000), options: .usesLineFragmentOrigin, context: nil) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /LYAlertViewDemo/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.swift 3 | // LYAlertViewDemo 4 | // 5 | // Created by DisCover on 2021/1/4. 6 | // 7 | 8 | import UIKit 9 | 10 | class SceneDelegate: UIResponder, UIWindowSceneDelegate { 11 | 12 | var window: UIWindow? 13 | 14 | 15 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 16 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. 17 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. 18 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). 19 | guard let _ = (scene as? UIWindowScene) else { return } 20 | } 21 | 22 | func sceneDidDisconnect(_ scene: UIScene) { 23 | // Called as the scene is being released by the system. 24 | // This occurs shortly after the scene enters the background, or when its session is discarded. 25 | // Release any resources associated with this scene that can be re-created the next time the scene connects. 26 | // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). 27 | } 28 | 29 | func sceneDidBecomeActive(_ scene: UIScene) { 30 | // Called when the scene has moved from an inactive state to an active state. 31 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 32 | } 33 | 34 | func sceneWillResignActive(_ scene: UIScene) { 35 | // Called when the scene will move from an active state to an inactive state. 36 | // This may occur due to temporary interruptions (ex. an incoming phone call). 37 | } 38 | 39 | func sceneWillEnterForeground(_ scene: UIScene) { 40 | // Called as the scene transitions from the background to the foreground. 41 | // Use this method to undo the changes made on entering the background. 42 | } 43 | 44 | func sceneDidEnterBackground(_ scene: UIScene) { 45 | // Called as the scene transitions from the foreground to the background. 46 | // Use this method to save data, release shared resources, and store enough scene-specific state information 47 | // to restore the scene back to its current state. 48 | } 49 | 50 | 51 | } 52 | 53 | -------------------------------------------------------------------------------- /LYAlertViewDemo/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // LYAlertViewDemo 4 | // 5 | // Created by DisCover on 2021/1/4. 6 | // 7 | 8 | import UIKit 9 | 10 | class ViewController: UIViewController { 11 | 12 | fileprivate let cellid = "cell" 13 | 14 | 15 | var dataArr = [ 16 | "默认alpha动画", 17 | "缩放动画", 18 | "顶部掉落弹性动画", 19 | "底部弹出弹性动画", 20 | "左侧弹出弹性动画", 21 | "右侧弹出弹性动画", 22 | "顶部靠左掉落动画", 23 | "顶部靠右掉落动画", 24 | "带弹框的" 25 | ] 26 | 27 | var text = "" 28 | 29 | override func viewDidLoad() { 30 | super.viewDidLoad() 31 | self.title = "LYAlertViewDemo" 32 | view.addSubview(tableView) 33 | } 34 | 35 | lazy var tableView : UITableView = { 36 | let table = UITableView.init(frame: CGRect(x: 0, y: 0, width: LYCommonSet.Kwidth, height: LYCommonSet.Kheith), style: .plain) 37 | table.backgroundColor = LYCommonSet.RGBA(r: 245, g: 245, b: 245, a: 1) 38 | table.delegate = self 39 | table.dataSource = self 40 | table.register(UITableViewCell.self, forCellReuseIdentifier: cellid) 41 | table.tableFooterView = UIView() 42 | return table 43 | }() 44 | 45 | 46 | 47 | } 48 | extension ViewController:UITableViewDelegate,UITableViewDataSource{ 49 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 50 | return dataArr.count 51 | } 52 | 53 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 54 | let cell = tableView.dequeueReusableCell(withIdentifier: cellid, for: indexPath) 55 | cell.textLabel?.text = dataArr[indexPath.row] 56 | cell.backgroundColor = UIColor.white 57 | cell.selectionStyle = .none 58 | return cell 59 | } 60 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 61 | 62 | if indexPath.row == 0{ 63 | let item1 = LYAlertFactory() 64 | .creatAlertShowItem(.title, "温馨提示") 65 | .fontSize(17) 66 | .titleColor(UIColor.darkGray) 67 | let item2 = LYAlertFactory() 68 | .creatAlertShowItem(.content, "是否确认向老师发起一对一错题辅导请求?") 69 | .fontSize(16) 70 | .titleColor(UIColor.darkGray) 71 | .line(UIColor.lightGray, 0.5) 72 | let item3 = LYAlertFactory() 73 | .creatAlertInteractiveItem("我再想想") 74 | .fontSize(15) 75 | .btnHeight(30) 76 | .btnMarin(10) 77 | .titleColor(UIColor.gray) 78 | .line(UIColor.lightGray, 0.5, .left) 79 | .action { 80 | print("我再想想") 81 | } 82 | let item4 = LYAlertFactory() 83 | .creatAlertInteractiveItem("确认发起") 84 | .fontSize(15) 85 | .btnHeight(30) 86 | .btnMarin(10) 87 | .titleColor(UIColor.brown) 88 | .line(UIColor.lightGray, 0.5, .left) 89 | .action { 90 | print("确认发起") 91 | } 92 | let alert = LYAlertBuilder.init(item1, item2, [item3,item4]) 93 | .cornerRadius(15) 94 | .maskAlpha(0.4) 95 | .build() 96 | alert?.show() 97 | }else if indexPath.row == 1{ 98 | let item2 = LYAlertFactory() 99 | .creatAlertShowItem(.content, "是否确认向老师发起一对一错题辅导请求?") 100 | .fontSize(16) 101 | .titleColor(UIColor.darkGray) 102 | .line(UIColor.lightGray, 0.5) 103 | let item3 = LYAlertFactory() 104 | .creatAlertInteractiveItem("我再想想") 105 | .fontSize(15) 106 | .btnHeight(30) 107 | .btnMarin(10) 108 | .titleColor(UIColor.gray) 109 | .line(UIColor.lightGray, 0.5, .left) 110 | .action { 111 | print("我再想想") 112 | } 113 | let item4 = LYAlertFactory() 114 | .creatAlertInteractiveItem("确认发起") 115 | .fontSize(15) 116 | .btnHeight(30) 117 | .btnMarin(10) 118 | .titleColor(UIColor.brown) 119 | .line(UIColor.lightGray, 0.5, .left) 120 | .action { 121 | print("确认发起") 122 | } 123 | let alert = LYAlertBuilder.init(nil, item2, [item3,item4]) 124 | .cornerRadius(15) 125 | .maskAlpha(0.4) 126 | .showAnimation(.scale, 0.5) 127 | .hideAnimation(.scale, 0.5) 128 | .build() 129 | alert?.show() 130 | }else if indexPath.row == 2{ 131 | 132 | let item1 = LYAlertFactory() 133 | .creatAlertShowItem(.title, "温馨提示") 134 | .fontSize(17) 135 | .titleColor(UIColor.darkGray) 136 | let item2 = LYAlertFactory() 137 | .creatAlertShowItem(.content, "是否确认向老师发起一对一错题辅导请求?") 138 | .fontSize(16) 139 | .titleColor(UIColor.darkGray) 140 | .line(UIColor.lightGray, 0.5) 141 | let item3 = LYAlertFactory() 142 | .creatAlertInteractiveItem("我再想想") 143 | .fontSize(15) 144 | .btnHeight(44) 145 | .btnMarin(15) 146 | .btnRadius(5) 147 | .btnBackgroundColor(UIColor.orange) 148 | .titleColor(UIColor.white) 149 | .line(UIColor.lightGray, 0.5, .left) 150 | .action { 151 | print("我再想想") 152 | } 153 | let item4 = LYAlertFactory() 154 | .creatAlertInteractiveItem("确认发起") 155 | .fontSize(15) 156 | .btnRadius(5) 157 | .btnHeight(44) 158 | .btnMarin(15) 159 | .btnBackgroundColor(UIColor.orange) 160 | .titleColor(UIColor.white) 161 | .line(UIColor.lightGray, 0.5, .left) 162 | .action { 163 | print("确认发起") 164 | } 165 | let alert = LYAlertBuilder.init(item1, item2, [item3,item4]) 166 | .cornerRadius(15) 167 | .maskAlpha(0.6) 168 | .showAnimation(.shakeFromTop, 0.5) 169 | .hideAnimation(.shakeToTop, 0.5) 170 | .build() 171 | alert?.show() 172 | }else if indexPath.row == 3{ 173 | 174 | let item1 = LYAlertFactory() 175 | .creatAlertShowItem(.title, "温馨提示") 176 | .fontSize(17) 177 | .line(UIColor.lightGray, 0.5) 178 | .titleColor(UIColor.darkGray) 179 | let item2 = LYAlertFactory() 180 | .creatAlertShowItem(.content, "是否确认向老师发起一对一错题辅导请求是否确认向老师发起一对一错题辅导请求是否确认向老师发起一对一错题辅导请求是否确认向老师发起一对一错题辅导请求是否确认向老师发起一对一错题辅导请求?") 181 | .fontSize(16) 182 | .textAlignment(.justified) 183 | .titleColor(UIColor.darkGray) 184 | .line(UIColor.lightGray, 0.5) 185 | let item3 = LYAlertFactory() 186 | .creatAlertInteractiveItem("我再想想") 187 | .fontSize(15) 188 | .btnHeight(44) 189 | .btnMarin(15) 190 | .btnRadius(5) 191 | .btnBackgroundColor(UIColor.orange) 192 | .titleColor(UIColor.white) 193 | .line(UIColor.lightGray, 0.5, .left) 194 | .action { 195 | print("我再想想") 196 | } 197 | let item4 = LYAlertFactory() 198 | .creatAlertInteractiveItem("确认发起") 199 | .fontSize(15) 200 | .btnRadius(5) 201 | .btnHeight(44) 202 | .btnMarin(15) 203 | .btnBackgroundColor(UIColor.orange) 204 | .titleColor(UIColor.white) 205 | .line(UIColor.lightGray, 0.5, .left) 206 | .action { 207 | print("确认发起") 208 | } 209 | let alert = LYAlertBuilder.init(item1, item2, [item3,item4]) 210 | .cornerRadius(15) 211 | .maskAlpha(0.6) 212 | .showAnimation(.shakeFromBottom, 0.5) 213 | .hideAnimation(.shakeToTop, 0.5) 214 | .build() 215 | alert?.show() 216 | }else if indexPath.row == 4{ 217 | let dic = [NSAttributedString.Key.kern:NSNumber.init(value: 15)] 218 | let item1 = LYAlertFactory() 219 | .creatAlertShowItem(.title, "温馨提示") 220 | .fontSize(17) 221 | .attribute(dic) 222 | .titleColor(UIColor.darkGray) 223 | let item2 = LYAlertFactory() 224 | .creatAlertShowItem(.content, "是否确认向老师发起一对一错题辅导请求?") 225 | .fontSize(16) 226 | .titleColor(UIColor.darkGray) 227 | .line(UIColor.lightGray, 0.5) 228 | 229 | let item4 = LYAlertFactory() 230 | .creatAlertInteractiveItem("确认发起") 231 | .fontSize(15) 232 | .btnRadius(5) 233 | .btnHeight(44) 234 | .btnMarin(15) 235 | .btnBackgroundColor(UIColor.orange) 236 | .titleColor(UIColor.white) 237 | .action { 238 | print("确认发起") 239 | } 240 | let alert = LYAlertBuilder.init(item1, item2, [item4]) 241 | .cornerRadius(15) 242 | .maskAlpha(0.6) 243 | .showAnimation(.shakeFromLeft, 0.5) 244 | .hideAnimation(.shakeToLeft, 0.5) 245 | .build() 246 | alert?.show() 247 | }else if indexPath.row == 5{ 248 | let item1 = LYAlertFactory() 249 | .creatAlertShowItem(.title, "温馨提示") 250 | .fontSize(17) 251 | .titleColor(UIColor.darkGray) 252 | let item2 = LYAlertFactory() 253 | .creatAlertShowItem(.content, "是否确认向老师发起一对一错题辅导请求?") 254 | .fontSize(16) 255 | .titleColor(UIColor.darkGray) 256 | .line(UIColor.lightGray, 0.5) 257 | let item3 = LYAlertFactory() 258 | .creatAlertInteractiveItem("我再想想") 259 | .fontSize(15) 260 | .btnHeight(30) 261 | .btnMarin(10) 262 | .titleColor(UIColor.gray) 263 | .line(UIColor.lightGray, 0.5, .bottom) 264 | .action { 265 | print("我再想想") 266 | } 267 | let item4 = LYAlertFactory() 268 | .creatAlertInteractiveItem("确认发起") 269 | .fontSize(15) 270 | .btnHeight(30) 271 | .btnMarin(10) 272 | .titleColor(UIColor.brown) 273 | .line(UIColor.lightGray, 0.5, .bottom) 274 | .action { 275 | print("确认发起") 276 | } 277 | let item5 = LYAlertFactory() 278 | .creatAlertInteractiveItem("取消") 279 | .fontSize(15) 280 | .btnHeight(30) 281 | .btnMarin(10) 282 | .titleColor(UIColor.brown) 283 | .action { 284 | print("取消") 285 | } 286 | let alert = LYAlertBuilder.init(item1, item2, [item3,item4,item5]) 287 | .cornerRadius(15) 288 | .maskAlpha(0.4) 289 | .showAnimation(.shakeFromRight, 0.5) 290 | .hideAnimation(.shakeToLeft, 0.5) 291 | .build() 292 | alert?.show() 293 | }else if indexPath.row == 6{ 294 | let item1 = LYAlertFactory() 295 | .creatAlertShowItem(.title, "温馨提示") 296 | .fontSize(17) 297 | .titleColor(UIColor.darkGray) 298 | let item2 = LYAlertFactory() 299 | .creatAlertShowItem(.content, "是否确认向老师发起一对一错题辅导请求?") 300 | .fontSize(16) 301 | .titleColor(UIColor.darkGray) 302 | .line(UIColor.lightGray, 0.5) 303 | let item3 = LYAlertFactory() 304 | .creatAlertInteractiveItem("我再想想") 305 | .fontSize(15) 306 | .btnHeight(44) 307 | .btnMarin(0) 308 | .itemBackgroundColor(UIColor.orange) 309 | .btnBackgroundColor(UIColor.clear) 310 | .titleColor(UIColor.white) 311 | .line(UIColor.gray, 0.5, .left) 312 | .action { 313 | print("我再想想") 314 | } 315 | let item4 = LYAlertFactory() 316 | .creatAlertInteractiveItem("确认发起") 317 | .fontSize(15) 318 | .btnHeight(44) 319 | .btnMarin(0) 320 | .itemBackgroundColor(UIColor.orange) 321 | .titleColor(UIColor.white) 322 | .action { 323 | print("确认发起") 324 | } 325 | let alert = LYAlertBuilder.init(item1, item2, [item3,item4]) 326 | .cornerRadius(15) 327 | .maskAlpha(0.6) 328 | .showAnimation(.dropFromLeft, 0.5) 329 | .hideAnimation(.dropFromLeft, 0.5) 330 | .build() 331 | alert?.show() 332 | }else if indexPath.row == 7{ 333 | let item1 = LYAlertFactory() 334 | .creatAlertShowItem(.title, "温馨提示") 335 | .fontSize(17) 336 | .titleColor(UIColor.darkGray) 337 | let item2 = LYAlertFactory() 338 | .creatAlertShowItem(.content, "是否确认向老师发起一对一错题辅导请求?") 339 | .fontSize(16) 340 | .titleColor(UIColor.darkGray) 341 | .line(UIColor.lightGray, 0.5) 342 | 343 | let item4 = LYAlertFactory() 344 | .creatAlertInteractiveItem("确认发起") 345 | .fontSize(15) 346 | .btnHeight(44) 347 | .btnMarin(0) 348 | .itemBackgroundColor(UIColor.orange) 349 | .titleColor(UIColor.white) 350 | .action { 351 | print("确认发起") 352 | } 353 | let alert = LYAlertBuilder.init(item1, item2, [item4]) 354 | .cornerRadius(15) 355 | .maskAlpha(0.6) 356 | .showAnimation(.dropFromRight, 0.5) 357 | .hideAnimation(.dropFromRight, 0.5) 358 | .build() 359 | alert?.show() 360 | }else if indexPath.row == 8{ 361 | let item1 = LYAlertFactory() 362 | .creatAlertShowItem(.title, "温馨提示") 363 | .fontSize(17) 364 | .titleColor(UIColor.darkGray) 365 | let item2 = LYAlertFactory() 366 | .creatAlertFieldItem("请输入老师的ID以发起辅导请求") 367 | .fontSize(16) 368 | .delegate(self) 369 | .titleColor(UIColor.darkGray) 370 | .keyboardType(.default) 371 | .line(UIColor.lightGray, 0.5) 372 | 373 | let item4 = LYAlertFactory() 374 | .creatAlertInteractiveItem("确认发起") 375 | .fontSize(15) 376 | .btnHeight(44) 377 | .btnMarin(0) 378 | .itemBackgroundColor(UIColor.orange) 379 | .titleColor(UIColor.white) 380 | .action { [weak self] in 381 | print(" 老师 ID : \(self?.text ?? "")") 382 | } 383 | let alert = LYAlertBuilder.init(item1, item2, [item4]) 384 | .cornerRadius(15) 385 | .maskAlpha(0.6) 386 | .tapMaskHide(false) 387 | .showAnimation(.dropFromRight, 0.5) 388 | .hideAnimation(.dropFromRight, 0.5) 389 | .build() 390 | alert?.show() 391 | } 392 | 393 | 394 | } 395 | 396 | } 397 | extension ViewController:UITextFieldDelegate{ 398 | func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { 399 | if let s = textField.text{ 400 | self.text = s + string 401 | } 402 | 403 | return true 404 | } 405 | } 406 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ## 1.安装 3 | #### 方式一:使用CocoaPods 4 | ``` 5 | pod 'LYAlertView' 6 | ``` 7 | #### 方式二:手动导入 8 | - 将`LYAlertView`文件夹中的所有源代码拽入项目中 9 | - 直接调用 10 | ## 2.调用示例 11 | ``` 12 | let item1 = LYAlertFactory() 13 | .creatAlertShowItem(.title, "温馨提示") 14 | .fontSize(17) 15 | .titleColor(UIColor.darkGray) 16 | let item2 = LYAlertFactory() 17 | .creatAlertShowItem(.content, "是否确认向老师发起一对一错题辅导请求?") 18 | .fontSize(16) 19 | .titleColor(UIColor.darkGray) 20 | .line(UIColor.lightGray, 0.5) 21 | let item3 = LYAlertFactory() 22 | .creatAlertInteractiveItem("我再想想") 23 | .fontSize(15) 24 | .btnHeight(30) 25 | .btnMarin(10) 26 | .titleColor(UIColor.gray) 27 | .line(UIColor.lightGray, 0.5, .left) 28 | .action { 29 | print("我再想想") 30 | } 31 | let item4 = LYAlertFactory() 32 | .creatAlertInteractiveItem("确认发起") 33 | .fontSize(15) 34 | .btnHeight(30) 35 | .btnMarin(10) 36 | .titleColor(UIColor.brown) 37 | .line(UIColor.lightGray, 0.5, .left) 38 | .action { 39 | print("确认发起") 40 | } 41 | let alert = LYAlertBuilder.init(item1, item2, [item3,item4]) 42 | .cornerRadius(15) 43 | .maskAlpha(0.6) 44 | .showAnimation(.shakeFromTop, 0.5) 45 | .hideAnimation(.shakeToTop, 0.5) 46 | .build() 47 | alert?.show() 48 | ``` 49 | ## 3.效果展示 50 | ![1](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8c86df424b5742ab888389217ce17472~tplv-k3u1fbpfcp-watermark.image) 51 | ![2](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/93670f55f100444c8decd88149ebed70~tplv-k3u1fbpfcp-watermark.image) 52 | ![3](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/896cd5fc9df24e05b6f4191956fa4935~tplv-k3u1fbpfcp-watermark.image) 53 | ![4](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b455687449e94abab5653d0201f7c976~tplv-k3u1fbpfcp-watermark.image) 54 | --------------------------------------------------------------------------------