├── README.md ├── SelUpdateAlert.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcuserdata │ └── zhuku.xcuserdatad │ └── xcschemes │ └── xcschememanagement.plist └── SelUpdateAlert ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets ├── AppIcon.appiconset │ └── Contents.json ├── Contents.json ├── VersionUpdate_Cancel.imageset │ ├── Contents.json │ ├── VersionUpdate_Cancel@2x.png │ └── VersionUpdate_Cancel@3x.png └── VersionUpdate_Icon.imageset │ ├── Contents.json │ ├── VersionUpdate_Icon@2x.png │ └── VersionUpdate_Icon@3x.png ├── Base.lproj └── LaunchScreen.storyboard ├── Info.plist ├── Main ├── SELAlertViewController.h └── SELAlertViewController.m ├── UpdateAlert ├── SELUpdateAlert.h ├── SELUpdateAlert.m ├── SELUpdateAlertConst.h └── SELUpdateAlertConst.m └── main.m /README.md: -------------------------------------------------------------------------------- 1 | # SELUpdateAlert 2 | 快捷添加版本更新提示 3 | 4 | 简书地址:https://www.jianshu.com/p/3f92dda8f85e 5 | 6 | ![image](https://github.com/RockChanel/SWGIF/blob/master/SELUpdateAlert/SELUpdateAlert.gif) 7 | 8 | 一句话快捷添加版本更新提示 9 | 10 | /** 添加更新提示 */ 11 | //方法一: 12 | [SELUpdateAlert showUpdateAlertWithVersion:@"1.0.0" Descriptions:@[@"1.xxxxxxxxxx",@"2.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",@"3.xxxxxxxxxx",@"4.xxxxxxxxxx"]]; 13 | 14 | //方法二: 15 | //[SELUpdateAlert showUpdateAlertWithVersion:@"1.0.0" Description:@"1.xxxxxxxxxx\n2.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n3.xxxxxxxxx\n4.xxxxxxxxxx"]; 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /SelUpdateAlert.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | EDAFC6DB202AFBE000BB9CC2 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = EDAFC6DA202AFBE000BB9CC2 /* AppDelegate.m */; }; 11 | EDAFC6E3202AFBE000BB9CC2 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EDAFC6E2202AFBE000BB9CC2 /* Assets.xcassets */; }; 12 | EDAFC6E6202AFBE000BB9CC2 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EDAFC6E4202AFBE000BB9CC2 /* LaunchScreen.storyboard */; }; 13 | EDAFC6E9202AFBE000BB9CC2 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = EDAFC6E8202AFBE000BB9CC2 /* main.m */; }; 14 | EDAFC6FC202AFFAF00BB9CC2 /* SELAlertViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = EDAFC6FB202AFFAF00BB9CC2 /* SELAlertViewController.m */; }; 15 | EDAFC6FF202AFFE600BB9CC2 /* SELUpdateAlertConst.m in Sources */ = {isa = PBXBuildFile; fileRef = EDAFC6FE202AFFE600BB9CC2 /* SELUpdateAlertConst.m */; }; 16 | EDAFC702202B3F9A00BB9CC2 /* SELUpdateAlert.m in Sources */ = {isa = PBXBuildFile; fileRef = EDAFC701202B3F9A00BB9CC2 /* SELUpdateAlert.m */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXFileReference section */ 20 | EDAFC6D6202AFBE000BB9CC2 /* SelUpdateAlert.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SelUpdateAlert.app; sourceTree = BUILT_PRODUCTS_DIR; }; 21 | EDAFC6D9202AFBE000BB9CC2 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 22 | EDAFC6DA202AFBE000BB9CC2 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 23 | EDAFC6E2202AFBE000BB9CC2 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 24 | EDAFC6E5202AFBE000BB9CC2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 25 | EDAFC6E7202AFBE000BB9CC2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 26 | EDAFC6E8202AFBE000BB9CC2 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 27 | EDAFC6FA202AFFAF00BB9CC2 /* SELAlertViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SELAlertViewController.h; sourceTree = ""; }; 28 | EDAFC6FB202AFFAF00BB9CC2 /* SELAlertViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SELAlertViewController.m; sourceTree = ""; }; 29 | EDAFC6FD202AFFE600BB9CC2 /* SELUpdateAlertConst.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SELUpdateAlertConst.h; sourceTree = ""; }; 30 | EDAFC6FE202AFFE600BB9CC2 /* SELUpdateAlertConst.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SELUpdateAlertConst.m; sourceTree = ""; }; 31 | EDAFC700202B3F9A00BB9CC2 /* SELUpdateAlert.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SELUpdateAlert.h; sourceTree = ""; }; 32 | EDAFC701202B3F9A00BB9CC2 /* SELUpdateAlert.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SELUpdateAlert.m; sourceTree = ""; }; 33 | /* End PBXFileReference section */ 34 | 35 | /* Begin PBXFrameworksBuildPhase section */ 36 | EDAFC6D3202AFBE000BB9CC2 /* Frameworks */ = { 37 | isa = PBXFrameworksBuildPhase; 38 | buildActionMask = 2147483647; 39 | files = ( 40 | ); 41 | runOnlyForDeploymentPostprocessing = 0; 42 | }; 43 | /* End PBXFrameworksBuildPhase section */ 44 | 45 | /* Begin PBXGroup section */ 46 | EDAFC6CD202AFBE000BB9CC2 = { 47 | isa = PBXGroup; 48 | children = ( 49 | EDAFC6D8202AFBE000BB9CC2 /* SelUpdateAlert */, 50 | EDAFC6D7202AFBE000BB9CC2 /* Products */, 51 | ); 52 | sourceTree = ""; 53 | }; 54 | EDAFC6D7202AFBE000BB9CC2 /* Products */ = { 55 | isa = PBXGroup; 56 | children = ( 57 | EDAFC6D6202AFBE000BB9CC2 /* SelUpdateAlert.app */, 58 | ); 59 | name = Products; 60 | sourceTree = ""; 61 | }; 62 | EDAFC6D8202AFBE000BB9CC2 /* SelUpdateAlert */ = { 63 | isa = PBXGroup; 64 | children = ( 65 | EDAFC6D9202AFBE000BB9CC2 /* AppDelegate.h */, 66 | EDAFC6DA202AFBE000BB9CC2 /* AppDelegate.m */, 67 | EDAFC6F0202AFC3400BB9CC2 /* Main */, 68 | EDAFC6EF202AFC2200BB9CC2 /* UpdateAlert */, 69 | EDAFC6E2202AFBE000BB9CC2 /* Assets.xcassets */, 70 | EDAFC6E4202AFBE000BB9CC2 /* LaunchScreen.storyboard */, 71 | EDAFC6E7202AFBE000BB9CC2 /* Info.plist */, 72 | EDAFC6E8202AFBE000BB9CC2 /* main.m */, 73 | ); 74 | path = SelUpdateAlert; 75 | sourceTree = ""; 76 | }; 77 | EDAFC6EF202AFC2200BB9CC2 /* UpdateAlert */ = { 78 | isa = PBXGroup; 79 | children = ( 80 | EDAFC6FD202AFFE600BB9CC2 /* SELUpdateAlertConst.h */, 81 | EDAFC6FE202AFFE600BB9CC2 /* SELUpdateAlertConst.m */, 82 | EDAFC700202B3F9A00BB9CC2 /* SELUpdateAlert.h */, 83 | EDAFC701202B3F9A00BB9CC2 /* SELUpdateAlert.m */, 84 | ); 85 | path = UpdateAlert; 86 | sourceTree = ""; 87 | }; 88 | EDAFC6F0202AFC3400BB9CC2 /* Main */ = { 89 | isa = PBXGroup; 90 | children = ( 91 | EDAFC6FA202AFFAF00BB9CC2 /* SELAlertViewController.h */, 92 | EDAFC6FB202AFFAF00BB9CC2 /* SELAlertViewController.m */, 93 | ); 94 | path = Main; 95 | sourceTree = ""; 96 | }; 97 | /* End PBXGroup section */ 98 | 99 | /* Begin PBXNativeTarget section */ 100 | EDAFC6D5202AFBE000BB9CC2 /* SelUpdateAlert */ = { 101 | isa = PBXNativeTarget; 102 | buildConfigurationList = EDAFC6EC202AFBE000BB9CC2 /* Build configuration list for PBXNativeTarget "SelUpdateAlert" */; 103 | buildPhases = ( 104 | EDAFC6D2202AFBE000BB9CC2 /* Sources */, 105 | EDAFC6D3202AFBE000BB9CC2 /* Frameworks */, 106 | EDAFC6D4202AFBE000BB9CC2 /* Resources */, 107 | ); 108 | buildRules = ( 109 | ); 110 | dependencies = ( 111 | ); 112 | name = SelUpdateAlert; 113 | productName = SelUpdateAlert; 114 | productReference = EDAFC6D6202AFBE000BB9CC2 /* SelUpdateAlert.app */; 115 | productType = "com.apple.product-type.application"; 116 | }; 117 | /* End PBXNativeTarget section */ 118 | 119 | /* Begin PBXProject section */ 120 | EDAFC6CE202AFBE000BB9CC2 /* Project object */ = { 121 | isa = PBXProject; 122 | attributes = { 123 | LastUpgradeCheck = 0920; 124 | ORGANIZATIONNAME = selwyn; 125 | TargetAttributes = { 126 | EDAFC6D5202AFBE000BB9CC2 = { 127 | CreatedOnToolsVersion = 9.2; 128 | ProvisioningStyle = Automatic; 129 | }; 130 | }; 131 | }; 132 | buildConfigurationList = EDAFC6D1202AFBE000BB9CC2 /* Build configuration list for PBXProject "SelUpdateAlert" */; 133 | compatibilityVersion = "Xcode 8.0"; 134 | developmentRegion = en; 135 | hasScannedForEncodings = 0; 136 | knownRegions = ( 137 | en, 138 | Base, 139 | ); 140 | mainGroup = EDAFC6CD202AFBE000BB9CC2; 141 | productRefGroup = EDAFC6D7202AFBE000BB9CC2 /* Products */; 142 | projectDirPath = ""; 143 | projectRoot = ""; 144 | targets = ( 145 | EDAFC6D5202AFBE000BB9CC2 /* SelUpdateAlert */, 146 | ); 147 | }; 148 | /* End PBXProject section */ 149 | 150 | /* Begin PBXResourcesBuildPhase section */ 151 | EDAFC6D4202AFBE000BB9CC2 /* Resources */ = { 152 | isa = PBXResourcesBuildPhase; 153 | buildActionMask = 2147483647; 154 | files = ( 155 | EDAFC6E6202AFBE000BB9CC2 /* LaunchScreen.storyboard in Resources */, 156 | EDAFC6E3202AFBE000BB9CC2 /* Assets.xcassets in Resources */, 157 | ); 158 | runOnlyForDeploymentPostprocessing = 0; 159 | }; 160 | /* End PBXResourcesBuildPhase section */ 161 | 162 | /* Begin PBXSourcesBuildPhase section */ 163 | EDAFC6D2202AFBE000BB9CC2 /* Sources */ = { 164 | isa = PBXSourcesBuildPhase; 165 | buildActionMask = 2147483647; 166 | files = ( 167 | EDAFC6E9202AFBE000BB9CC2 /* main.m in Sources */, 168 | EDAFC6DB202AFBE000BB9CC2 /* AppDelegate.m in Sources */, 169 | EDAFC702202B3F9A00BB9CC2 /* SELUpdateAlert.m in Sources */, 170 | EDAFC6FF202AFFE600BB9CC2 /* SELUpdateAlertConst.m in Sources */, 171 | EDAFC6FC202AFFAF00BB9CC2 /* SELAlertViewController.m in Sources */, 172 | ); 173 | runOnlyForDeploymentPostprocessing = 0; 174 | }; 175 | /* End PBXSourcesBuildPhase section */ 176 | 177 | /* Begin PBXVariantGroup section */ 178 | EDAFC6E4202AFBE000BB9CC2 /* LaunchScreen.storyboard */ = { 179 | isa = PBXVariantGroup; 180 | children = ( 181 | EDAFC6E5202AFBE000BB9CC2 /* Base */, 182 | ); 183 | name = LaunchScreen.storyboard; 184 | sourceTree = ""; 185 | }; 186 | /* End PBXVariantGroup section */ 187 | 188 | /* Begin XCBuildConfiguration section */ 189 | EDAFC6EA202AFBE000BB9CC2 /* Debug */ = { 190 | isa = XCBuildConfiguration; 191 | buildSettings = { 192 | ALWAYS_SEARCH_USER_PATHS = NO; 193 | CLANG_ANALYZER_NONNULL = YES; 194 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 195 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 196 | CLANG_CXX_LIBRARY = "libc++"; 197 | CLANG_ENABLE_MODULES = YES; 198 | CLANG_ENABLE_OBJC_ARC = YES; 199 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 200 | CLANG_WARN_BOOL_CONVERSION = YES; 201 | CLANG_WARN_COMMA = YES; 202 | CLANG_WARN_CONSTANT_CONVERSION = YES; 203 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 204 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 205 | CLANG_WARN_EMPTY_BODY = YES; 206 | CLANG_WARN_ENUM_CONVERSION = YES; 207 | CLANG_WARN_INFINITE_RECURSION = YES; 208 | CLANG_WARN_INT_CONVERSION = YES; 209 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 210 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 211 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 212 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 213 | CLANG_WARN_STRICT_PROTOTYPES = YES; 214 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 215 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 216 | CLANG_WARN_UNREACHABLE_CODE = YES; 217 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 218 | CODE_SIGN_IDENTITY = "iPhone Developer"; 219 | COPY_PHASE_STRIP = NO; 220 | DEBUG_INFORMATION_FORMAT = dwarf; 221 | ENABLE_STRICT_OBJC_MSGSEND = YES; 222 | ENABLE_TESTABILITY = YES; 223 | GCC_C_LANGUAGE_STANDARD = gnu11; 224 | GCC_DYNAMIC_NO_PIC = NO; 225 | GCC_NO_COMMON_BLOCKS = YES; 226 | GCC_OPTIMIZATION_LEVEL = 0; 227 | GCC_PREPROCESSOR_DEFINITIONS = ( 228 | "DEBUG=1", 229 | "$(inherited)", 230 | ); 231 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 232 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 233 | GCC_WARN_UNDECLARED_SELECTOR = YES; 234 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 235 | GCC_WARN_UNUSED_FUNCTION = YES; 236 | GCC_WARN_UNUSED_VARIABLE = YES; 237 | IPHONEOS_DEPLOYMENT_TARGET = 11.2; 238 | MTL_ENABLE_DEBUG_INFO = YES; 239 | ONLY_ACTIVE_ARCH = YES; 240 | SDKROOT = iphoneos; 241 | }; 242 | name = Debug; 243 | }; 244 | EDAFC6EB202AFBE000BB9CC2 /* Release */ = { 245 | isa = XCBuildConfiguration; 246 | buildSettings = { 247 | ALWAYS_SEARCH_USER_PATHS = NO; 248 | CLANG_ANALYZER_NONNULL = YES; 249 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 250 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 251 | CLANG_CXX_LIBRARY = "libc++"; 252 | CLANG_ENABLE_MODULES = YES; 253 | CLANG_ENABLE_OBJC_ARC = YES; 254 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 255 | CLANG_WARN_BOOL_CONVERSION = YES; 256 | CLANG_WARN_COMMA = YES; 257 | CLANG_WARN_CONSTANT_CONVERSION = YES; 258 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 259 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 260 | CLANG_WARN_EMPTY_BODY = YES; 261 | CLANG_WARN_ENUM_CONVERSION = YES; 262 | CLANG_WARN_INFINITE_RECURSION = YES; 263 | CLANG_WARN_INT_CONVERSION = YES; 264 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 265 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 266 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 267 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 268 | CLANG_WARN_STRICT_PROTOTYPES = YES; 269 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 270 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 271 | CLANG_WARN_UNREACHABLE_CODE = YES; 272 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 273 | CODE_SIGN_IDENTITY = "iPhone Developer"; 274 | COPY_PHASE_STRIP = NO; 275 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 276 | ENABLE_NS_ASSERTIONS = NO; 277 | ENABLE_STRICT_OBJC_MSGSEND = YES; 278 | GCC_C_LANGUAGE_STANDARD = gnu11; 279 | GCC_NO_COMMON_BLOCKS = YES; 280 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 281 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 282 | GCC_WARN_UNDECLARED_SELECTOR = YES; 283 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 284 | GCC_WARN_UNUSED_FUNCTION = YES; 285 | GCC_WARN_UNUSED_VARIABLE = YES; 286 | IPHONEOS_DEPLOYMENT_TARGET = 11.2; 287 | MTL_ENABLE_DEBUG_INFO = NO; 288 | SDKROOT = iphoneos; 289 | VALIDATE_PRODUCT = YES; 290 | }; 291 | name = Release; 292 | }; 293 | EDAFC6ED202AFBE000BB9CC2 /* Debug */ = { 294 | isa = XCBuildConfiguration; 295 | buildSettings = { 296 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 297 | CODE_SIGN_STYLE = Automatic; 298 | DEVELOPMENT_TEAM = 28XRZ273MD; 299 | INFOPLIST_FILE = SelUpdateAlert/Info.plist; 300 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 301 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 302 | PRODUCT_BUNDLE_IDENTIFIER = selwynbee.SelUpdateAlert; 303 | PRODUCT_NAME = "$(TARGET_NAME)"; 304 | TARGETED_DEVICE_FAMILY = 1; 305 | }; 306 | name = Debug; 307 | }; 308 | EDAFC6EE202AFBE000BB9CC2 /* Release */ = { 309 | isa = XCBuildConfiguration; 310 | buildSettings = { 311 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 312 | CODE_SIGN_STYLE = Automatic; 313 | DEVELOPMENT_TEAM = 28XRZ273MD; 314 | INFOPLIST_FILE = SelUpdateAlert/Info.plist; 315 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 316 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 317 | PRODUCT_BUNDLE_IDENTIFIER = selwynbee.SelUpdateAlert; 318 | PRODUCT_NAME = "$(TARGET_NAME)"; 319 | TARGETED_DEVICE_FAMILY = 1; 320 | }; 321 | name = Release; 322 | }; 323 | /* End XCBuildConfiguration section */ 324 | 325 | /* Begin XCConfigurationList section */ 326 | EDAFC6D1202AFBE000BB9CC2 /* Build configuration list for PBXProject "SelUpdateAlert" */ = { 327 | isa = XCConfigurationList; 328 | buildConfigurations = ( 329 | EDAFC6EA202AFBE000BB9CC2 /* Debug */, 330 | EDAFC6EB202AFBE000BB9CC2 /* Release */, 331 | ); 332 | defaultConfigurationIsVisible = 0; 333 | defaultConfigurationName = Release; 334 | }; 335 | EDAFC6EC202AFBE000BB9CC2 /* Build configuration list for PBXNativeTarget "SelUpdateAlert" */ = { 336 | isa = XCConfigurationList; 337 | buildConfigurations = ( 338 | EDAFC6ED202AFBE000BB9CC2 /* Debug */, 339 | EDAFC6EE202AFBE000BB9CC2 /* Release */, 340 | ); 341 | defaultConfigurationIsVisible = 0; 342 | defaultConfigurationName = Release; 343 | }; 344 | /* End XCConfigurationList section */ 345 | }; 346 | rootObject = EDAFC6CE202AFBE000BB9CC2 /* Project object */; 347 | } 348 | -------------------------------------------------------------------------------- /SelUpdateAlert.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SelUpdateAlert.xcodeproj/xcuserdata/zhuku.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SelUpdateAlert.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /SelUpdateAlert/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // SelUpdateAlert 4 | // 5 | // Created by zhuku on 2018/2/7. 6 | // Copyright © 2018年 selwyn. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /SelUpdateAlert/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // SelUpdateAlert 4 | // 5 | // Created by zhuku on 2018/2/7. 6 | // Copyright © 2018年 selwyn. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "SELAlertViewController.h" 11 | #import "SELUpdateAlert.h" 12 | 13 | @interface AppDelegate () 14 | 15 | @end 16 | 17 | @implementation AppDelegate 18 | 19 | 20 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 21 | // Override point for customization after application launch. 22 | 23 | self.window = [[UIWindow alloc]initWithFrame: [UIScreen mainScreen].bounds]; 24 | self.window.backgroundColor = [UIColor whiteColor]; 25 | 26 | SELAlertViewController *alertVC = [[SELAlertViewController alloc]init]; 27 | UINavigationController *alertNav = [[UINavigationController alloc]initWithRootViewController:alertVC]; 28 | self.window.rootViewController = alertNav; 29 | 30 | [self.window makeKeyAndVisible]; 31 | 32 | /** 添加更新提示 */ 33 | //方法一: 34 | [SELUpdateAlert showUpdateAlertWithVersion:@"1.0.0" Descriptions:@[@"1.xxxxxxxxxx",@"2.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",@"3.xxxxxxxxxx",@"4.xxxxxxxxxx"]]; 35 | 36 | //方法二: 37 | //[SELUpdateAlert showUpdateAlertWithVersion:@"1.0.0" Description:@"1.xxxxxxxxxx\n2.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n3.xxxxxxxxx\n4.xxxxxxxxxx"]; 38 | 39 | return YES; 40 | } 41 | 42 | 43 | - (void)applicationWillResignActive:(UIApplication *)application { 44 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 45 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 46 | } 47 | 48 | 49 | - (void)applicationDidEnterBackground:(UIApplication *)application { 50 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 51 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 52 | } 53 | 54 | 55 | - (void)applicationWillEnterForeground:(UIApplication *)application { 56 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 57 | } 58 | 59 | 60 | - (void)applicationDidBecomeActive:(UIApplication *)application { 61 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 62 | } 63 | 64 | 65 | - (void)applicationWillTerminate:(UIApplication *)application { 66 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 67 | } 68 | 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /SelUpdateAlert/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /SelUpdateAlert/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /SelUpdateAlert/Assets.xcassets/VersionUpdate_Cancel.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "VersionUpdate_Cancel@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "VersionUpdate_Cancel@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /SelUpdateAlert/Assets.xcassets/VersionUpdate_Cancel.imageset/VersionUpdate_Cancel@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RockChanel/SELUpdateAlert/3517113a920f58824bd0235a53fa067f4095060c/SelUpdateAlert/Assets.xcassets/VersionUpdate_Cancel.imageset/VersionUpdate_Cancel@2x.png -------------------------------------------------------------------------------- /SelUpdateAlert/Assets.xcassets/VersionUpdate_Cancel.imageset/VersionUpdate_Cancel@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RockChanel/SELUpdateAlert/3517113a920f58824bd0235a53fa067f4095060c/SelUpdateAlert/Assets.xcassets/VersionUpdate_Cancel.imageset/VersionUpdate_Cancel@3x.png -------------------------------------------------------------------------------- /SelUpdateAlert/Assets.xcassets/VersionUpdate_Icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "VersionUpdate_Icon@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "VersionUpdate_Icon@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /SelUpdateAlert/Assets.xcassets/VersionUpdate_Icon.imageset/VersionUpdate_Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RockChanel/SELUpdateAlert/3517113a920f58824bd0235a53fa067f4095060c/SelUpdateAlert/Assets.xcassets/VersionUpdate_Icon.imageset/VersionUpdate_Icon@2x.png -------------------------------------------------------------------------------- /SelUpdateAlert/Assets.xcassets/VersionUpdate_Icon.imageset/VersionUpdate_Icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RockChanel/SELUpdateAlert/3517113a920f58824bd0235a53fa067f4095060c/SelUpdateAlert/Assets.xcassets/VersionUpdate_Icon.imageset/VersionUpdate_Icon@3x.png -------------------------------------------------------------------------------- /SelUpdateAlert/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 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /SelUpdateAlert/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 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIRequiredDeviceCapabilities 26 | 27 | armv7 28 | 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | 33 | UISupportedInterfaceOrientations~ipad 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationPortraitUpsideDown 37 | UIInterfaceOrientationLandscapeLeft 38 | UIInterfaceOrientationLandscapeRight 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /SelUpdateAlert/Main/SELAlertViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SELAlertViewController.h 3 | // SelUpdateAlert 4 | // 5 | // Created by zhuku on 2018/2/7. 6 | // Copyright © 2018年 selwyn. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SELAlertViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /SelUpdateAlert/Main/SELAlertViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SELAlertViewController.m 3 | // SelUpdateAlert 4 | // 5 | // Created by zhuku on 2018/2/7. 6 | // Copyright © 2018年 selwyn. All rights reserved. 7 | // 8 | 9 | #import "SELAlertViewController.h" 10 | 11 | @interface SELAlertViewController () 12 | 13 | @end 14 | 15 | @implementation SELAlertViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | } 20 | 21 | - (void)didReceiveMemoryWarning { 22 | [super didReceiveMemoryWarning]; 23 | // Dispose of any resources that can be recreated. 24 | } 25 | 26 | /* 27 | #pragma mark - Navigation 28 | 29 | // In a storyboard-based application, you will often want to do a little preparation before navigation 30 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 31 | // Get the new view controller using [segue destinationViewController]. 32 | // Pass the selected object to the new view controller. 33 | } 34 | */ 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /SelUpdateAlert/UpdateAlert/SELUpdateAlert.h: -------------------------------------------------------------------------------- 1 | // 2 | // SELUpdateAlert.h 3 | // SelUpdateAlert 4 | // 5 | // Created by zhuku on 2018/2/7. 6 | // Copyright © 2018年 selwyn. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SELUpdateAlert : UIView 12 | 13 | /** 14 | 添加版本更新提示 15 | 16 | @param version 版本号 17 | @param descriptions 版本更新内容(数组) 18 | 19 | descriptions 格式如 @[@"1.xxxxxx",@"2.xxxxxx"] 20 | */ 21 | + (void)showUpdateAlertWithVersion:(NSString *)version Descriptions:(NSArray *)descriptions; 22 | 23 | /** 24 | 添加版本更新提示 25 | 26 | @param version 版本号 27 | @param description 版本更新内容(字符串) 28 | 29 | description 格式如 @"1.xxxxxx\n2.xxxxxx" 30 | */ 31 | + (void)showUpdateAlertWithVersion:(NSString *)version Description:(NSString *)description; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /SelUpdateAlert/UpdateAlert/SELUpdateAlert.m: -------------------------------------------------------------------------------- 1 | // 2 | // SELUpdateAlert.m 3 | // SelUpdateAlert 4 | // 5 | // Created by zhuku on 2018/2/7. 6 | // Copyright © 2018年 selwyn. All rights reserved. 7 | // 8 | 9 | #import "SELUpdateAlert.h" 10 | #import "SELUpdateAlertConst.h" 11 | 12 | #define DEFAULT_MAX_HEIGHT SCREEN_HEIGHT/3*2 13 | 14 | @interface SELUpdateAlert() 15 | 16 | /** 版本号 */ 17 | @property (nonatomic, copy) NSString *version; 18 | /** 版本更新内容 */ 19 | @property (nonatomic, copy) NSString *desc; 20 | 21 | @end 22 | 23 | @implementation SELUpdateAlert 24 | 25 | /** 26 | 添加版本更新提示 27 | 28 | @param version 版本号 29 | @param descriptions 版本更新内容(数组) 30 | 31 | descriptions 格式如 @[@"1.xxxxxx",@"2.xxxxxx"] 32 | */ 33 | + (void)showUpdateAlertWithVersion:(NSString *)version Descriptions:(NSArray *)descriptions 34 | { 35 | if (!descriptions || descriptions.count == 0) { 36 | return; 37 | } 38 | 39 | //数组转换字符串,动态添加换行符\n 40 | NSString *description = @""; 41 | for (NSInteger i = 0; i < descriptions.count; ++i) { 42 | id desc = descriptions[i]; 43 | if (![desc isKindOfClass:[NSString class]]) { 44 | return; 45 | } 46 | description = [description stringByAppendingString:desc]; 47 | if (i != descriptions.count-1) { 48 | description = [description stringByAppendingString:@"\n"]; 49 | } 50 | } 51 | NSLog(@"====%@",description); 52 | SELUpdateAlert *updateAlert = [[SELUpdateAlert alloc]initVersion:version description:description]; 53 | [[UIApplication sharedApplication].delegate.window addSubview:updateAlert]; 54 | } 55 | 56 | /** 57 | 添加版本更新提示 58 | 59 | @param version 版本号 60 | @param description 版本更新内容(字符串) 61 | 62 | description 格式如 @"1.xxxxxx\n2.xxxxxx" 63 | */ 64 | + (void)showUpdateAlertWithVersion:(NSString *)version Description:(NSString *)description 65 | { 66 | SELUpdateAlert *updateAlert = [[SELUpdateAlert alloc]initVersion:version description:description]; 67 | [[UIApplication sharedApplication].delegate.window addSubview:updateAlert]; 68 | } 69 | 70 | - (instancetype)initVersion:(NSString *)version description:(NSString *)description 71 | { 72 | self = [super init]; 73 | if (self) { 74 | self.version = version; 75 | self.desc = description; 76 | 77 | [self _setupUI]; 78 | } 79 | return self; 80 | } 81 | 82 | - (void)_setupUI 83 | { 84 | self.frame = [UIScreen mainScreen].bounds; 85 | self.backgroundColor = [UIColor colorWithRed:0/255.0 green:0/255.0 blue:0/255.0 alpha:0.3/1.0]; 86 | 87 | //获取更新内容高度 88 | CGFloat descHeight = [self _sizeofString:self.desc font:[UIFont systemFontOfSize:SELDescriptionFont] maxSize:CGSizeMake(self.frame.size.width - Ratio(80) - Ratio(56), 1000)].height; 89 | 90 | //bgView实际高度 91 | CGFloat realHeight = descHeight + Ratio(314); 92 | 93 | //bgView最大高度 94 | CGFloat maxHeight = DEFAULT_MAX_HEIGHT; 95 | //更新内容可否滑动显示 96 | BOOL scrollEnabled = NO; 97 | 98 | //重置bgView最大高度 设置更新内容可否滑动显示 99 | if (realHeight > DEFAULT_MAX_HEIGHT) { 100 | scrollEnabled = YES; 101 | descHeight = DEFAULT_MAX_HEIGHT - Ratio(314); 102 | }else 103 | { 104 | maxHeight = realHeight; 105 | } 106 | 107 | //backgroundView 108 | UIView *bgView = [[UIView alloc]init]; 109 | bgView.center = self.center; 110 | bgView.bounds = CGRectMake(0, 0, self.frame.size.width - Ratio(40), maxHeight+Ratio(18)); 111 | [self addSubview:bgView]; 112 | 113 | //添加更新提示 114 | UIView *updateView = [[UIView alloc]initWithFrame:CGRectMake(Ratio(20), Ratio(18), bgView.frame.size.width - Ratio(40), maxHeight)]; 115 | updateView.backgroundColor = [UIColor whiteColor]; 116 | updateView.layer.masksToBounds = YES; 117 | updateView.layer.cornerRadius = 4.0f; 118 | [bgView addSubview:updateView]; 119 | 120 | //20+166+10+28+10+descHeight+20+40+20 = 314+descHeight 内部元素高度计算bgView高度 121 | UIImageView *updateIcon = [[UIImageView alloc]initWithFrame:CGRectMake((updateView.frame.size.width - Ratio(178))/2, Ratio(20), Ratio(178), Ratio(166))]; 122 | updateIcon.image = [UIImage imageNamed:@"VersionUpdate_Icon"]; 123 | [updateView addSubview:updateIcon]; 124 | 125 | //版本号 126 | UILabel *versionLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, Ratio(10) + CGRectGetMaxY(updateIcon.frame), updateView.frame.size.width, Ratio(28))]; 127 | versionLabel.font = [UIFont boldSystemFontOfSize:18]; 128 | versionLabel.textAlignment = NSTextAlignmentCenter; 129 | versionLabel.text = [NSString stringWithFormat:@"发现新版本 V%@",self.version]; 130 | [updateView addSubview:versionLabel]; 131 | 132 | //更新内容 133 | UITextView *descTextView = [[UITextView alloc]initWithFrame:CGRectMake(Ratio(28), Ratio(10) + CGRectGetMaxY(versionLabel.frame), updateView.frame.size.width - Ratio(56), descHeight)]; 134 | descTextView.font = [UIFont systemFontOfSize:SELDescriptionFont]; 135 | descTextView.textContainer.lineFragmentPadding = 0; 136 | descTextView.textContainerInset = UIEdgeInsetsMake(0, 0, 0, 0); 137 | descTextView.text = self.desc; 138 | descTextView.editable = NO; 139 | descTextView.selectable = NO; 140 | descTextView.scrollEnabled = scrollEnabled; 141 | descTextView.showsVerticalScrollIndicator = scrollEnabled; 142 | descTextView.showsHorizontalScrollIndicator = NO; 143 | [updateView addSubview:descTextView]; 144 | 145 | if (scrollEnabled) { 146 | //若显示滑动条,提示可以有滑动条 147 | [descTextView flashScrollIndicators]; 148 | } 149 | 150 | //更新按钮 151 | UIButton *updateButton = [UIButton buttonWithType:UIButtonTypeSystem]; 152 | updateButton.backgroundColor = SELColor(34, 153, 238); 153 | updateButton.frame = CGRectMake(Ratio(25), CGRectGetMaxY(descTextView.frame) + Ratio(20), updateView.frame.size.width - Ratio(50), Ratio(40)); 154 | updateButton.clipsToBounds = YES; 155 | updateButton.layer.cornerRadius = 2.0f; 156 | [updateButton addTarget:self action:@selector(updateVersion) forControlEvents:UIControlEventTouchUpInside]; 157 | [updateButton setTitle:@"立即更新" forState:UIControlStateNormal]; 158 | [updateButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; 159 | [updateView addSubview:updateButton]; 160 | 161 | //取消按钮 162 | UIButton *cancelButton = [UIButton buttonWithType:UIButtonTypeSystem]; 163 | cancelButton.center = CGPointMake(CGRectGetMaxX(updateView.frame), CGRectGetMinY(updateView.frame)); 164 | cancelButton.bounds = CGRectMake(0, 0, Ratio(36), Ratio(36)); 165 | [cancelButton setImage:[[UIImage imageNamed:@"VersionUpdate_Cancel"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] forState:UIControlStateNormal]; 166 | [cancelButton addTarget:self action:@selector(cancelAction) forControlEvents:UIControlEventTouchUpInside]; 167 | [bgView addSubview:cancelButton]; 168 | 169 | //显示更新 170 | [self showWithAlert:bgView]; 171 | } 172 | 173 | /** 更新按钮点击事件 跳转AppStore更新 */ 174 | - (void)updateVersion 175 | { 176 | NSString *str = [NSString stringWithFormat:@"http://itunes.apple.com/us/app/id%@", APP_ID]; 177 | [[UIApplication sharedApplication] openURL:[NSURL URLWithString:str]]; 178 | } 179 | 180 | /** 取消按钮点击事件 */ 181 | - (void)cancelAction 182 | { 183 | [self dismissAlert]; 184 | } 185 | 186 | /** 187 | 添加Alert入场动画 188 | @param alert 添加动画的View 189 | */ 190 | - (void)showWithAlert:(UIView*)alert{ 191 | 192 | CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"]; 193 | animation.duration = SELAnimationTimeInterval; 194 | 195 | NSMutableArray *values = [NSMutableArray array]; 196 | [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(0.1, 0.1, 1.0)]]; 197 | [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(1.2, 1.2, 1.0)]]; 198 | [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(0.9, 0.9, 1.0)]]; 199 | [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(1.0, 1.0, 1.0)]]; 200 | animation.values = values; 201 | [alert.layer addAnimation:animation forKey:nil]; 202 | } 203 | 204 | 205 | /** 添加Alert出场动画 */ 206 | - (void)dismissAlert{ 207 | 208 | [UIView animateWithDuration:SELAnimationTimeInterval animations:^{ 209 | self.transform = (CGAffineTransformMakeScale(1.5, 1.5)); 210 | self.backgroundColor = [UIColor clearColor]; 211 | self.alpha = 0; 212 | }completion:^(BOOL finished) { 213 | [self removeFromSuperview]; 214 | } ]; 215 | 216 | } 217 | 218 | /** 219 | 计算字符串高度 220 | @param string 字符串 221 | @param font 字体大小 222 | @param maxSize 最大Size 223 | @return 计算得到的Size 224 | */ 225 | - (CGSize)_sizeofString:(NSString *)string font:(UIFont *)font maxSize:(CGSize)maxSize 226 | { 227 | return [string boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:nil].size; 228 | } 229 | 230 | 231 | 232 | 233 | @end 234 | -------------------------------------------------------------------------------- /SelUpdateAlert/UpdateAlert/SELUpdateAlertConst.h: -------------------------------------------------------------------------------- 1 | // 2 | // SELUpdateAlertConst.h 3 | // SelUpdateAlert 4 | // 5 | // Created by zhuku on 2018/2/7. 6 | // Copyright © 2018年 selwyn. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /** App id */ 12 | #define APP_ID @"11111111" 13 | 14 | /** RGB */ 15 | #define SELColor(r, g, b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1.0] 16 | /** 屏幕高度 */ 17 | #define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width 18 | /** 屏幕高度 */ 19 | #define SCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height 20 | 21 | //屏幕适配 22 | /**当前设备对应375的比例*/ 23 | #define Ratio_375 (SCREEN_WIDTH/375.0) 24 | /**转换成当前比例的数*/ 25 | #define Ratio(x) ((int)((x) * Ratio_375)) 26 | 27 | /** 入场出场动画时间 */ 28 | UIKIT_EXTERN const CGFloat SELAnimationTimeInterval; 29 | 30 | /** 更新内容显示字体大小 */ 31 | UIKIT_EXTERN const CGFloat SELDescriptionFont; 32 | 33 | /** 更新内容最大显示高度 */ 34 | UIKIT_EXTERN const CGFloat SELMaxDescriptionHeight; 35 | -------------------------------------------------------------------------------- /SelUpdateAlert/UpdateAlert/SELUpdateAlertConst.m: -------------------------------------------------------------------------------- 1 | // 2 | // SELUpdateAlertConst.m 3 | // SelUpdateAlert 4 | // 5 | // Created by zhuku on 2018/2/7. 6 | // Copyright © 2018年 selwyn. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /** 入场出场动画时间 */ 12 | const CGFloat SELAnimationTimeInterval = 0.6f; 13 | 14 | /** 更新内容显示字体大小 */ 15 | const CGFloat SELDescriptionFont = 16; 16 | 17 | /** 更新内容最大显示高度 */ 18 | const CGFloat SELMaxDescriptionHeight; 19 | -------------------------------------------------------------------------------- /SelUpdateAlert/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SelUpdateAlert 4 | // 5 | // Created by zhuku on 2018/2/7. 6 | // Copyright © 2018年 selwyn. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | --------------------------------------------------------------------------------