├── ezgif.com-video-to-gif (1).gif ├── JLAlertView ├── JLAlertView.xcodeproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── JLAlertView.xcscmblueprint │ └── project.pbxproj └── JLAlertView │ ├── JLAlertView │ ├── JLAlertWindow.h │ ├── JLAlertBackGroundController.h │ ├── JLAlertWindow.m │ ├── JLBlureView.h │ ├── JLAlertBackGroundWindow.h │ ├── CusKeyWindowRootViewController.h │ ├── JLAlertViewController.h │ ├── CusKeyWindowRootViewController.m │ ├── CustomKeyWindow.h │ ├── JLAlertView.h │ ├── JLAlertHeader.h │ ├── JLAlertBackGroundWindow.m │ ├── JLBlureView.m │ ├── JLAlertBackGroundController.m │ ├── JLAlertViewController.m │ ├── CustomKeyWindow.m │ └── JLAlertView.m │ ├── ViewController.h │ ├── AppDelegate.h │ ├── main.m │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── Info.plist │ ├── Base.lproj │ ├── Main.storyboard │ └── LaunchScreen.storyboard │ ├── AppDelegate.m │ └── ViewController.m ├── README.md ├── LICENSE └── .gitignore /ezgif.com-video-to-gif (1).gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jianlong108/JLAlertView/HEAD/ezgif.com-video-to-gif (1).gif -------------------------------------------------------------------------------- /JLAlertView/JLAlertView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /JLAlertView/JLAlertView/JLAlertView/JLAlertWindow.h: -------------------------------------------------------------------------------- 1 | // 2 | // JLAlertWindow.h 3 | // JLAlertView 4 | // 5 | // Created by Wangjianlong on 2016/12/29. 6 | // Copyright © 2016年 JL. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface JLAlertWindow : UIWindow 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /JLAlertView/JLAlertView/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // JLAlertView 4 | // 5 | // Created by Wangjianlong on 2016/12/8. 6 | // Copyright © 2016年 JL. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /JLAlertView/JLAlertView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /JLAlertView/JLAlertView/JLAlertView/JLAlertBackGroundController.h: -------------------------------------------------------------------------------- 1 | // 2 | // JLAlertViewBackGroundController.h 3 | // JLAlertView 4 | // 5 | // Created by Wangjianlong on 2016/12/29. 6 | // Copyright © 2016年 JL. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface JLAlertBackGroundController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /JLAlertView/JLAlertView/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // JLAlertView 4 | // 5 | // Created by Wangjianlong on 2016/12/8. 6 | // Copyright © 2016年 JL. 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 | -------------------------------------------------------------------------------- /JLAlertView/JLAlertView/JLAlertView/JLAlertWindow.m: -------------------------------------------------------------------------------- 1 | // 2 | // JLAlertWindow.m 3 | // JLAlertView 4 | // 5 | // Created by Wangjianlong on 2016/12/29. 6 | // Copyright © 2016年 JL. All rights reserved. 7 | // 8 | 9 | #import "JLAlertWindow.h" 10 | 11 | @implementation JLAlertWindow 12 | 13 | - (void)dealloc 14 | { 15 | NSLog(@"JLAlertWindow -- dealloc"); 16 | } 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /JLAlertView/JLAlertView/JLAlertView/JLBlureView.h: -------------------------------------------------------------------------------- 1 | // 2 | // JLBlureView.h 3 | // JLAlertView 4 | // 5 | // Created by Wangjianlong on 2017/2/23. 6 | // Copyright © 2017年 JL. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface JLBlureView : UIView 12 | 13 | @property (nonatomic, weak) UIView *backgroundView; 14 | 15 | - (void)blur; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /JLAlertView/JLAlertView/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // JLAlertView 4 | // 5 | // Created by Wangjianlong on 2016/12/8. 6 | // Copyright © 2016年 JL. 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 | -------------------------------------------------------------------------------- /JLAlertView/JLAlertView/JLAlertView/JLAlertBackGroundWindow.h: -------------------------------------------------------------------------------- 1 | // 2 | // JLAlertBackGroundWindow.h 3 | // JLAlertView 4 | // 5 | // Created by Wangjianlong on 2016/12/29. 6 | // Copyright © 2016年 JL. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "JLAlertBackGroundController.h" 11 | 12 | @interface JLAlertBackGroundWindow : UIWindow 13 | /***/ 14 | //@property (nonatomic, weak)JLAlertBackGroundController *rootVC; 15 | @end 16 | -------------------------------------------------------------------------------- /JLAlertView/JLAlertView/JLAlertView/CusKeyWindowRootViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CXCusKeyWindowRootViewController.h 3 | // CXAlertViewDemo 4 | // 5 | // Created by Wangjianlong on 2018/12/5. 6 | // Copyright © 2018 JL. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CustomKeyWindow.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface CusKeyWindowRootViewController : UIViewController 15 | 16 | @property(nonatomic, readonly) CustomKeyWindow *keyWindow; 17 | @property (nonatomic, assign) BOOL rootViewControllerPrefersStatusBarHidden; 18 | - (instancetype)initWithCustomKeyWindow:(CustomKeyWindow *)customKeyWindow; 19 | 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /JLAlertView/JLAlertView/JLAlertView/JLAlertViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // JLAlertViewController.h 3 | // JLAlertView 4 | // 5 | // Created by Wangjianlong on 2016/12/8. 6 | // Copyright © 2016年 JL. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "JLAlertView.h" 11 | 12 | @interface JLAlertViewController : UIViewController 13 | 14 | 15 | @property (nonatomic, readonly) JLAlertView *alertView; 16 | 17 | @property (nonatomic, assign) BOOL rootViewControllerPrefersStatusBarHidden; 18 | @property (nonatomic, assign) BOOL rootViewControllerCanRoration; 19 | @property (nonatomic, assign) UIInterfaceOrientationMask rootViewControllerInterfaceOrientationMask; 20 | 21 | - (instancetype)initWithAlertView:(JLAlertView *)alertView; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /JLAlertView/JLAlertView/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /JLAlertView/JLAlertView/JLAlertView/CusKeyWindowRootViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // CXCusKeyWindowRootViewController.m 3 | // CXAlertViewDemo 4 | // 5 | // Created by Wangjianlong on 2018/12/5. 6 | // Copyright © 2018 JL. All rights reserved. 7 | // 8 | 9 | #import "CusKeyWindowRootViewController.h" 10 | 11 | @interface CusKeyWindowRootViewController () 12 | 13 | @property(nonatomic, strong) CustomKeyWindow *keyWindow; 14 | 15 | @end 16 | 17 | @implementation CusKeyWindowRootViewController 18 | 19 | - (instancetype)initWithCustomKeyWindow:(CustomKeyWindow *)customKeyWindow 20 | { 21 | if (self = [super init]) { 22 | _keyWindow = customKeyWindow; 23 | } 24 | return self; 25 | } 26 | 27 | - (void)loadView 28 | { 29 | self.view = self.keyWindow; 30 | } 31 | 32 | - (void)viewDidLoad 33 | { 34 | [super viewDidLoad]; 35 | } 36 | 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JLAlertView 2 | very similar with UIAlertView,but JLAlertView is not subclass of UIAlertView 3 | 4 | - (void)entryAPPSTORE{ 5 | UIAlertView *ALERT1 = [[UIAlertView alloc]initWithTitle:@"第一个" message:@"hello" delegate:self cancelButtonTitle:@"ok" otherButtonTitles:nil]; 6 | [ALERT1 show]; 7 | 8 | UIAlertView *ALERT2 = [[UIAlertView alloc]initWithTitle:@"第2个" message:@"ok" delegate:self cancelButtonTitle:@"sure" otherButtonTitles:nil]; 9 | [ALERT2 show]; 10 | } 11 | - (void)entryPhotoReader{ 12 | JLAlertView *alert = [[JLAlertView alloc]initWithTitle:@"第一个" message:@"hello" delegate:nil SureButtonTitle:@"ok" otherButtonTitles:nil]; 13 | [alert show]; 14 | 15 | JLAlertView *alert1 = [[JLAlertView alloc]initWithTitle:@"第2个" message:@"welcome" delegate:nil SureButtonTitle:@"sure" otherButtonTitles:nil]; 16 | [alert1 show]; 17 | } 18 | 19 | ![image](https://github.com/jianlong108/JLAlertView/blob/master/ezgif.com-video-to-gif%20(1).gif) 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 JianLongWang 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 | -------------------------------------------------------------------------------- /JLAlertView/JLAlertView/JLAlertView/CustomKeyWindow.h: -------------------------------------------------------------------------------- 1 | // 2 | // CXCustomKeyWindow.h 3 | // JLAlertView 4 | // 5 | // Created by Wangjianlong on 2018/12/5. 6 | // Copyright © 2018 JL. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @class CusKeyWindowRootViewController; 14 | @class CustomKeyWindow; 15 | typedef void(^CustomKeyWindowHandler)(CustomKeyWindow *alertView); 16 | 17 | @interface CustomKeyWindow : UIView 18 | 19 | @property (nonatomic, copy) CustomKeyWindowHandler willShowHandler; 20 | @property (nonatomic, copy) CustomKeyWindowHandler didShowHandler; 21 | @property (nonatomic, copy) CustomKeyWindowHandler willDismissHandler; 22 | @property (nonatomic, copy) CustomKeyWindowHandler didDismissHandler; 23 | 24 | @property (nonatomic, readonly, getter = isVisible) BOOL visible; 25 | 26 | // AlertView action 27 | - (void)show; 28 | - (void)dismiss; 29 | - (void)shake; 30 | // Operation 31 | - (void)cleanAllPenddingAlert; 32 | 33 | - (CusKeyWindowRootViewController *)getKeyWindowRootViewController; 34 | 35 | - (void)transitionInCompletion:(void(^)(void))completion; 36 | - (void)transitionOutCompletion:(void(^)(void))completion; 37 | - (void)validateLayout; 38 | 39 | - (void)windowDidDisappear; 40 | 41 | @end 42 | 43 | NS_ASSUME_NONNULL_END 44 | -------------------------------------------------------------------------------- /JLAlertView/JLAlertView/JLAlertView/JLAlertView.h: -------------------------------------------------------------------------------- 1 | // 2 | // JLAlertView.h 3 | // JLAlertView 4 | // 5 | // Created by Wangjianlong on 2016/12/8. 6 | // Copyright © 2016年 JL. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class JLAlertView; 12 | 13 | typedef NS_ENUM(NSInteger, JLAlertViewBtnColor) { 14 | JLAlertViewBtnColorGray = 0,//灰色文字 15 | JLAlertViewBtnColorBlue//蓝色文字 16 | }; 17 | 18 | @protocol JLAlertViewDelegate 19 | 20 | @optional 21 | 22 | /** 23 | * 点击索引 24 | * 25 | * @param alertView alertView 26 | * @param buttonIndex 确认按钮是最大的索引 27 | */ 28 | - (void)alertView:(nullable JLAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex; 29 | 30 | @end 31 | 32 | 33 | @interface JLAlertView : UIView 34 | 35 | @property(nullable,nonatomic,weak) id delegate; 36 | 37 | @property(nonatomic,readonly) NSInteger numberOfButtons; 38 | 39 | - (nullable instancetype)initWithTitle:(nullable NSString *)title message:(nullable NSString *)message delegate:(nullable id)delegate SureButtonTitle:(nullable NSString *)sureButtonTitle otherButtonTitles:(nullable NSArray *) otherButtonTitles; 40 | 41 | - (void)addButtonWithTitle:(nullable NSString *)title BtnColorStyle:(JLAlertViewBtnColor)btnColor; 42 | 43 | - (void)show; 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /JLAlertView/JLAlertView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 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 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /JLAlertView/JLAlertView/JLAlertView/JLAlertHeader.h: -------------------------------------------------------------------------------- 1 | // 2 | // JLAlertHeader.h 3 | // JLAlertView 4 | // 5 | // Created by Wangjianlong on 2016/12/29. 6 | // Copyright © 2016年 JL. All rights reserved. 7 | // 8 | 9 | #ifndef JLAlertHeader_h 10 | #define JLAlertHeader_h 11 | 12 | #import "JLAlertBackGroundWindow.h" 13 | #import "JLAlertView.h" 14 | 15 | 16 | //按钮高度 17 | #define JLALERT_BTN_H 46.0f 18 | 19 | //分割线高度 20 | #define JLALERT_SPLITE_H 0.5f 21 | 22 | /**Debug打印*/ 23 | #if DEBUG 24 | #define NSLog(...) NSLog(__VA_ARGS__) 25 | #else 26 | #define NSLog(...) {} 27 | #endif 28 | 29 | 30 | 31 | static NSString const * JLAlertViewTopTitle = @"JLAlertViewTopTitle"; 32 | static NSString const * JLAlertViewSecondTitle = @"JLAlertViewSecondTitle"; 33 | static NSString const * JLAlertViewSureButton = @"JLAlertViewSureButton"; 34 | static NSString const * JLAlertViewOtherButtons = @"JLAlertViewOtherButtons"; 35 | static NSMutableArray *__alert__alertElement; 36 | //static JLAlertBackGroundWindow *_alert__BackGroundView; 37 | static JLAlertView *__alert__currentAlertView; 38 | static BOOL JLAlertView_prefersStatusBarHidden; 39 | static BOOL JLAlertView_canrorate; 40 | static UIInterfaceOrientationMask JLAlertView_InterfaceOrientationMask; 41 | 42 | //static UIWindow *alert__oldKeyWindow; 43 | 44 | 45 | 46 | #endif /* JLAlertHeader_h */ 47 | -------------------------------------------------------------------------------- /JLAlertView/JLAlertView/JLAlertView/JLAlertBackGroundWindow.m: -------------------------------------------------------------------------------- 1 | // 2 | // JLAlertBackGroundWindow.m 3 | // JLAlertView 4 | // 5 | // Created by Wangjianlong on 2016/12/29. 6 | // Copyright © 2016年 JL. All rights reserved. 7 | // 8 | 9 | #import "JLAlertBackGroundWindow.h" 10 | #import "JLAlertBackGroundController.h" 11 | #import "JLBlureView.h" 12 | 13 | 14 | @implementation JLAlertBackGroundWindow 15 | 16 | - (instancetype)initWithFrame:(CGRect)frame 17 | { 18 | if (self = [super initWithFrame:frame]) { 19 | 20 | self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 21 | self.windowLevel = UIWindowLevelAlert - 1; 22 | self.opaque = NO; 23 | 24 | // JLBlureView *blureView = [[JLBlureView alloc]initWithFrame:self.bounds]; 25 | // blureView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 26 | // [self addSubview:blureView]; 27 | 28 | JLAlertBackGroundController *vc = [[JLAlertBackGroundController alloc] init]; 29 | self.rootViewController = vc; 30 | self.rootViewController.view.backgroundColor = [UIColor clearColor]; 31 | } 32 | return self; 33 | } 34 | 35 | - (void)drawRect:(CGRect)rect 36 | { 37 | CGContextRef context = UIGraphicsGetCurrentContext(); 38 | [[UIColor colorWithRed:0 green:0 blue:0 alpha:0.4] set]; 39 | CGContextFillRect(context, self.bounds); 40 | } 41 | 42 | - (void)dealloc 43 | { 44 | NSLog(@"JLAlertViewBackGroundView--dealloc"); 45 | } 46 | 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xcuserstate 23 | 24 | ## Obj-C/Swift specific 25 | *.hmap 26 | *.ipa 27 | *.dSYM.zip 28 | *.dSYM 29 | 30 | # CocoaPods 31 | # 32 | # We recommend against adding the Pods directory to your .gitignore. However 33 | # you should judge for yourself, the pros and cons are mentioned at: 34 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 35 | # 36 | # Pods/ 37 | 38 | # Carthage 39 | # 40 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 41 | # Carthage/Checkouts 42 | 43 | Carthage/Build 44 | 45 | # fastlane 46 | # 47 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 48 | # screenshots whenever they are needed. 49 | # For more information about the recommended setup visit: 50 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 51 | 52 | fastlane/report.xml 53 | fastlane/screenshots 54 | 55 | #Code Injection 56 | # 57 | # After new code Injection tools there's a generated folder /iOSInjectionProject 58 | # https://github.com/johnno1962/injectionforxcode 59 | 60 | iOSInjectionProject/ 61 | -------------------------------------------------------------------------------- /JLAlertView/JLAlertView/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 | -------------------------------------------------------------------------------- /JLAlertView/JLAlertView/JLAlertView/JLBlureView.m: -------------------------------------------------------------------------------- 1 | // 2 | // JLBlureView.m 3 | // JLAlertView 4 | // 5 | // Created by Wangjianlong on 2017/2/23. 6 | // Copyright © 2017年 JL. All rights reserved. 7 | // 8 | 9 | #import "JLBlureView.h" 10 | 11 | 12 | @interface JLBlureView () 13 | 14 | @property (nonatomic, weak) UIToolbar *toolbar; 15 | 16 | - (void)setup; 17 | 18 | @end 19 | 20 | @implementation JLBlureView 21 | 22 | - (id)initWithFrame:(CGRect)frame 23 | { 24 | self = [super initWithFrame:frame]; 25 | if (self) { 26 | [self setup]; 27 | } 28 | return self; 29 | } 30 | 31 | - (id)init 32 | { 33 | self = [super init]; 34 | if (self) { 35 | [self setup]; 36 | } 37 | return self; 38 | } 39 | 40 | - (void)layoutSubviews 41 | { 42 | [super layoutSubviews]; 43 | } 44 | 45 | - (void)setFrame:(CGRect)frame 46 | { 47 | [super setFrame:frame]; 48 | 49 | _toolbar.frame = self.bounds; 50 | _backgroundView.frame = self.bounds; 51 | } 52 | 53 | #pragma mark - PB 54 | - (void)blur 55 | { 56 | [UIView animateWithDuration:0.3 animations:^{ 57 | _backgroundView.alpha = 0.7; 58 | }]; 59 | } 60 | 61 | #pragma - PV 62 | - (void)setup 63 | { 64 | if (!_toolbar) { 65 | UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:self.bounds]; 66 | toolbar.translucent = YES; 67 | toolbar.barStyle = UIBarStyleBlack; 68 | [self.layer insertSublayer:toolbar.layer atIndex:0]; 69 | _toolbar = toolbar; 70 | 71 | UIView *backgroundView = [[UIView alloc] initWithFrame:self.bounds]; 72 | backgroundView.alpha = 0.4; 73 | backgroundView.backgroundColor = [UIColor blackColor]; 74 | [self.layer insertSublayer:backgroundView.layer above:_toolbar.layer]; 75 | _backgroundView = backgroundView; 76 | } 77 | } 78 | @end 79 | -------------------------------------------------------------------------------- /JLAlertView/JLAlertView/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 | 27 | 28 | -------------------------------------------------------------------------------- /JLAlertView/JLAlertView.xcodeproj/project.xcworkspace/xcshareddata/JLAlertView.xcscmblueprint: -------------------------------------------------------------------------------- 1 | { 2 | "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "0677DA52F70047C2E176A43ACC0A76D8940B9637", 3 | "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { 4 | 5 | }, 6 | "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { 7 | "5D15E09480009AF6531426C27CE4CB29E0D1844F" : 9223372036854775807, 8 | "0677DA52F70047C2E176A43ACC0A76D8940B9637" : 9223372036854775807 9 | }, 10 | "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "E9080E54-53AF-472E-ADD9-C91C928811B3", 11 | "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { 12 | "5D15E09480009AF6531426C27CE4CB29E0D1844F" : "..\/autohone_git\/business\/business750", 13 | "0677DA52F70047C2E176A43ACC0A76D8940B9637" : "JLAlertView\/" 14 | }, 15 | "DVTSourceControlWorkspaceBlueprintNameKey" : "JLAlertView", 16 | "DVTSourceControlWorkspaceBlueprintVersion" : 204, 17 | "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "JLAlertView\/JLAlertView.xcodeproj", 18 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ 19 | { 20 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/jianlong108\/JLAlertView.git", 21 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 22 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "0677DA52F70047C2E176A43ACC0A76D8940B9637" 23 | }, 24 | { 25 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/git.corpautohome.com\/GP_APPMAIN_IOS_SUPERTECH\/AHBusiness.git", 26 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 27 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "5D15E09480009AF6531426C27CE4CB29E0D1844F" 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /JLAlertView/JLAlertView/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // JLAlertView 4 | // 5 | // Created by Wangjianlong on 2016/12/8. 6 | // Copyright © 2016年 JL. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // 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. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // 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. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // 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. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // 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. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /JLAlertView/JLAlertView/JLAlertView/JLAlertBackGroundController.m: -------------------------------------------------------------------------------- 1 | // 2 | // JLAlertViewBackGroundController.m 3 | // JLAlertView 4 | // 5 | // Created by Wangjianlong on 2016/12/29. 6 | // Copyright © 2016年 JL. All rights reserved. 7 | // 8 | 9 | #import "JLAlertBackGroundController.h" 10 | #import "JLAlertHeader.h" 11 | 12 | @interface JLAlertView () 13 | 14 | + (UIViewController *)getCurrentViewController:(UIViewController *)vc; 15 | + (UIWindow *)getBusinessWindow; 16 | 17 | @end 18 | 19 | @interface JLAlertBackGroundController () 20 | 21 | @end 22 | 23 | @implementation JLAlertBackGroundController 24 | 25 | - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 26 | { 27 | if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { 28 | self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth; 29 | } 30 | return self; 31 | } 32 | 33 | - (BOOL)prefersStatusBarHidden 34 | { 35 | UIViewController *viewController = [[JLAlertView getBusinessWindow] rootViewController]; 36 | 37 | UIViewController *temViewController = nil; 38 | do { 39 | temViewController = [viewController childViewControllerForStatusBarHidden]; 40 | if (temViewController) 41 | { 42 | viewController = temViewController; 43 | } 44 | 45 | } while (temViewController != nil); 46 | if ([viewController isEqual:self]) { 47 | return NO; 48 | } 49 | return [viewController prefersStatusBarHidden]; 50 | } 51 | - (BOOL)shouldAutorotate 52 | { 53 | UIViewController *viewController = [[JLAlertView getBusinessWindow] rootViewController]; 54 | UIViewController *disPlayVC = [JLAlertView getCurrentViewController:viewController]; 55 | if ([disPlayVC isEqual:self]) { 56 | return YES; 57 | } 58 | return [disPlayVC shouldAutorotate]; 59 | } 60 | 61 | - (UIInterfaceOrientationMask)supportedInterfaceOrientations 62 | { 63 | UIViewController *viewController = [[JLAlertView getBusinessWindow] rootViewController]; 64 | UIViewController *disPlayVC = [JLAlertView getCurrentViewController:viewController]; 65 | if ([disPlayVC isEqual:self]) { 66 | return UIInterfaceOrientationMaskAll; 67 | } 68 | return [disPlayVC supportedInterfaceOrientations]; 69 | } 70 | 71 | - (UIStatusBarStyle)preferredStatusBarStyle 72 | { 73 | UIViewController *viewController = [[JLAlertView getBusinessWindow] rootViewController]; 74 | 75 | UIViewController *temViewController = nil; 76 | do { 77 | temViewController = [viewController childViewControllerForStatusBarStyle]; 78 | if (temViewController) 79 | { 80 | viewController = temViewController; 81 | } 82 | 83 | } while (temViewController != nil); 84 | if ([viewController isEqual:self]) { 85 | return UIStatusBarStyleDefault; 86 | } 87 | return [viewController preferredStatusBarStyle]; 88 | } 89 | 90 | - (void)dealloc 91 | { 92 | NSLog(@"JLAlertBackGroundController--dealloc"); 93 | } 94 | 95 | @end 96 | -------------------------------------------------------------------------------- /JLAlertView/JLAlertView/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // JLAlertView 4 | // 5 | // Created by Wangjianlong on 2016/12/8. 6 | // Copyright © 2016年 JL. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "JLAlertView.h" 11 | 12 | @interface ViewController () 13 | /**<#说明#>*/ 14 | @property (nonatomic, strong)JLAlertView *alert; 15 | @property (nonatomic, strong)JLAlertView *alert1; 16 | 17 | /***/ 18 | @property (nonatomic, weak) CAShapeLayer *shapLayer; 19 | 20 | @end 21 | 22 | @implementation ViewController 23 | 24 | - (void)viewDidLoad { 25 | [super viewDidLoad]; 26 | 27 | CGFloat width = [UIScreen mainScreen].bounds.size.width - 2*30; 28 | 29 | UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; 30 | btn.backgroundColor = [UIColor blackColor]; 31 | btn.frame = CGRectMake(30, 44, width, 50); 32 | [btn setTitle:@"弹alertview" forState:UIControlStateNormal]; 33 | [self.view addSubview:btn]; 34 | [btn addTarget:self action:@selector(entryPhotoReader) forControlEvents:UIControlEventTouchUpInside]; 35 | 36 | UIButton *btn0 = [UIButton buttonWithType:UIButtonTypeCustom]; 37 | btn0.backgroundColor = [UIColor blackColor]; 38 | btn0.frame = CGRectMake(30, 244, width, 50); 39 | [btn0 setTitle:@"弹系统alertview" forState:UIControlStateNormal]; 40 | [self.view addSubview:btn0]; 41 | [btn0 addTarget:self action:@selector(entryAPPSTORE) forControlEvents:UIControlEventTouchUpInside]; 42 | 43 | CAShapeLayer *shapLayer = [CAShapeLayer layer]; 44 | shapLayer.path = [UIBezierPath bezierPathWithRect:CGRectMake(100, 300, 100, 100)].CGPath; 45 | shapLayer.fillColor = [UIColor clearColor].CGColor; 46 | shapLayer.fillRule = @"even-odd"; 47 | shapLayer.strokeColor = [UIColor redColor].CGColor; 48 | 49 | shapLayer.strokeStart = 0.0; 50 | shapLayer.strokeEnd = 0.5; 51 | 52 | //斜接...拐角处的角度. 53 | _shapLayer.miterLimit = 3; 54 | 55 | shapLayer.lineWidth = 5; 56 | 57 | //设置路径上最后一个点的样式 58 | shapLayer.lineCap = kCALineCapSquare; 59 | 60 | //设置路径上拐点的样式 61 | shapLayer.lineJoin = kCALineJoinRound; 62 | 63 | [self.view.layer addSublayer:shapLayer]; 64 | _shapLayer = shapLayer; 65 | 66 | } 67 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ 68 | // [[NSNotificationCenter defaultCenter]postNotificationName:UIDeviceOrientationDidChangeNotification object:[UIDevice currentDevice] userInfo:@{@"UIDeviceOrientation":@3}]; 69 | // [[UIDevice currentDevice] setValue:@(UIDeviceOrientationLandscapeRight) forKey:@"orientation"]; 70 | CGFloat end = _shapLayer.strokeEnd; 71 | end+=0.01; 72 | if (end > 1.0) { 73 | end = 1.0f; 74 | } 75 | _shapLayer.strokeEnd = end; 76 | 77 | 78 | 79 | } 80 | - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator{ 81 | 82 | } 83 | - (UIStatusBarStyle)preferredStatusBarStyle{ 84 | // NSLog(@"preferredStatusBarStyle"); 85 | return UIStatusBarStyleDefault; 86 | } 87 | - (BOOL)prefersStatusBarHidden{ 88 | return NO; 89 | } 90 | - (void)didReceiveMemoryWarning { 91 | [super didReceiveMemoryWarning]; 92 | // Dispose of any resources that can be recreated. 93 | } 94 | - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{ 95 | 96 | } 97 | - (void)entryAPPSTORE{ 98 | UIAlertView *ALERT1 = [[UIAlertView alloc]initWithTitle:@"第一个" message:@"喜欢我就给我个好评吧.谢谢啊,我会努力做得更好!" delegate:self cancelButtonTitle:@"ok" otherButtonTitles:nil]; 99 | [ALERT1 show]; 100 | 101 | UIAlertView *ALERT2 = [[UIAlertView alloc]initWithTitle:@"第2个" message:@"喜欢我就给我个好评吧.谢谢啊,我会努力做得更好!" delegate:self cancelButtonTitle:@"sure" otherButtonTitles:nil]; 102 | [ALERT2 show]; 103 | } 104 | - (void)entryPhotoReader{ 105 | JLAlertView *alert = [[JLAlertView alloc]initWithTitle:@"第一个" message:@"喜欢我就给我个好评吧.谢谢啊,我会努力做得更好!" delegate:nil SureButtonTitle:@"ok" otherButtonTitles:nil]; 106 | [alert show]; 107 | 108 | JLAlertView *alert1 = [[JLAlertView alloc]initWithTitle:@"第2个" message:@"喜欢我就给我个好评吧.谢谢啊,我会努力做得更好!" delegate:nil SureButtonTitle:@"sure" otherButtonTitles:nil]; 109 | [alert1 show]; 110 | } 111 | @end 112 | -------------------------------------------------------------------------------- /JLAlertView/JLAlertView/JLAlertView/JLAlertViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // JLAlertViewController.m 3 | // JLAlertView 4 | // 5 | // Created by Wangjianlong on 2016/12/8. 6 | // Copyright © 2016年 JL. All rights reserved. 7 | // 8 | 9 | #import "JLAlertViewController.h" 10 | #import "JLAlertHeader.h" 11 | 12 | @interface JLAlertView () 13 | 14 | 15 | @property (nonatomic, strong)UIWindow *oldKeyWindow; 16 | @property (nonatomic, strong)UIWindow *alertWindow; 17 | @property (nonatomic, strong)JLAlertBackGroundWindow *alert__BackGroundView; 18 | 19 | - (void)initializeView; 20 | + (UIViewController *)getCurrentViewController:(UIViewController *)vc; 21 | + (UIWindow *)getBusinessWindow; 22 | 23 | @end 24 | 25 | @interface JLAlertViewController () 26 | 27 | @property (nonatomic, strong) JLAlertView *alertView; 28 | 29 | @end 30 | 31 | @implementation JLAlertViewController 32 | 33 | #pragma mark - View life cycle 34 | - (void)dealloc 35 | { 36 | NSLog(@"JLAlertViewConroller--dealloc"); 37 | } 38 | 39 | - (instancetype)initWithAlertView:(JLAlertView *)alertView 40 | { 41 | if (self = [super init]) { 42 | self.alertView = alertView; 43 | } 44 | return self; 45 | } 46 | 47 | - (void)loadView 48 | { 49 | if (self.alertView) { 50 | self.view = self.alertView; 51 | } else { 52 | self.view = [[UIView alloc]init]; 53 | } 54 | } 55 | 56 | - (void)viewDidLoad 57 | { 58 | [super viewDidLoad]; 59 | self.view.backgroundColor = [UIColor clearColor]; 60 | 61 | [self.alertView initializeView]; 62 | 63 | [UIApplication sharedApplication].statusBarHidden = _rootViewControllerPrefersStatusBarHidden; 64 | } 65 | 66 | - (void)viewWillAppear:(BOOL)animated 67 | { 68 | [super viewWillAppear:animated]; 69 | 70 | [UIApplication sharedApplication].statusBarHidden = _rootViewControllerPrefersStatusBarHidden; 71 | } 72 | 73 | - (void)viewDidDisappear:(BOOL)animated 74 | { 75 | [super viewDidDisappear:animated]; 76 | 77 | [UIApplication sharedApplication].statusBarHidden = _rootViewControllerPrefersStatusBarHidden; 78 | } 79 | 80 | - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration 81 | { 82 | [self.alertView setNeedsLayout]; 83 | } 84 | 85 | - (BOOL)prefersStatusBarHidden 86 | { 87 | UIViewController *viewController = [[JLAlertView getBusinessWindow] rootViewController]; 88 | 89 | UIViewController *temViewController = nil; 90 | do { 91 | temViewController = [viewController childViewControllerForStatusBarHidden]; 92 | if (temViewController) 93 | { 94 | viewController = temViewController; 95 | } 96 | 97 | } while (temViewController != nil); 98 | if ([viewController isEqual:self]) { 99 | return NO; 100 | } 101 | return [viewController prefersStatusBarHidden]; 102 | } 103 | - (BOOL)shouldAutorotate 104 | { 105 | UIViewController *viewController = [[JLAlertView getBusinessWindow] rootViewController]; 106 | UIViewController *disPlayVC = [JLAlertView getCurrentViewController:viewController]; 107 | if ([disPlayVC isEqual:self]) { 108 | return YES; 109 | } 110 | return [disPlayVC shouldAutorotate]; 111 | } 112 | 113 | - (UIInterfaceOrientationMask)supportedInterfaceOrientations 114 | { 115 | UIViewController *viewController = [[JLAlertView getBusinessWindow] rootViewController]; 116 | UIViewController *disPlayVC = [JLAlertView getCurrentViewController:viewController]; 117 | if ([disPlayVC isEqual:self]) { 118 | return UIInterfaceOrientationMaskAll; 119 | } 120 | return [disPlayVC supportedInterfaceOrientations]; 121 | } 122 | 123 | - (UIStatusBarStyle)preferredStatusBarStyle 124 | { 125 | UIViewController *viewController = [[JLAlertView getBusinessWindow] rootViewController]; 126 | 127 | UIViewController *temViewController = nil; 128 | do { 129 | temViewController = [viewController childViewControllerForStatusBarStyle]; 130 | if (temViewController) 131 | { 132 | viewController = temViewController; 133 | } 134 | 135 | } while (temViewController != nil); 136 | if ([viewController isEqual:self]) { 137 | return UIStatusBarStyleDefault; 138 | } 139 | return [viewController preferredStatusBarStyle]; 140 | } 141 | 142 | @end 143 | -------------------------------------------------------------------------------- /JLAlertView/JLAlertView/JLAlertView/CustomKeyWindow.m: -------------------------------------------------------------------------------- 1 | // 2 | // CXCustomKeyWindow.m 3 | // JLAlertView 4 | // 5 | // Created by Wangjianlong on 2018/12/5. 6 | // Copyright © 2018 JL. All rights reserved. 7 | // 8 | 9 | #import "CustomKeyWindow.h" 10 | #import "CusKeyWindowRootViewController.h" 11 | 12 | @class CustomKeyWindowBackgroundWindow; 13 | 14 | static NSMutableArray *__customKeyWindow_custom_key_window_queue; 15 | static BOOL __customKeyWindow_key_window_animating; 16 | static CustomKeyWindowBackgroundWindow *__customKeyWindow_key_background_window; 17 | static CustomKeyWindow *__customKeyWindow_key_window_current_view; 18 | static BOOL __customKeyWindow_rootViewController_prefersStatusBarHidden; 19 | 20 | @interface CustomKeyWindowTempViewController : UIViewController 21 | 22 | @end 23 | 24 | @implementation CustomKeyWindowTempViewController 25 | 26 | - (BOOL)prefersStatusBarHidden 27 | { 28 | return __customKeyWindow_rootViewController_prefersStatusBarHidden; 29 | } 30 | 31 | @end 32 | 33 | @interface CustomKeyWindowBackgroundWindow : UIWindow 34 | 35 | @end 36 | 37 | @implementation CustomKeyWindowBackgroundWindow 38 | 39 | - (id)initWithFrame:(CGRect)frame 40 | { 41 | self = [super initWithFrame:frame]; 42 | if (self) { 43 | self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 44 | self.opaque = NO; 45 | self.windowLevel = UIWindowLevelAlert - 1; 46 | self.rootViewController = [[CustomKeyWindowTempViewController alloc] init]; 47 | self.rootViewController.view.backgroundColor = [UIColor clearColor]; 48 | } 49 | return self; 50 | } 51 | 52 | - (void)drawRect:(CGRect)rect 53 | { 54 | CGContextRef context = UIGraphicsGetCurrentContext(); 55 | [[UIColor colorWithWhite:0 alpha:0.5] set]; 56 | CGContextFillRect(context, self.bounds); 57 | } 58 | 59 | @end 60 | 61 | @interface CustomKeyWindow() 62 | 63 | @property (nonatomic, strong) UIWindow *oldKeyWindow; 64 | @property (nonatomic, strong) UIWindow *alertWindow; 65 | @property (nonatomic, assign, getter = isVisible) BOOL visible; 66 | 67 | + (NSMutableArray *)sharedQueue; 68 | + (CustomKeyWindow *)currentAlertView; 69 | 70 | + (BOOL)isAnimating; 71 | + (void)setAnimating:(BOOL)animating; 72 | 73 | + (void)showBackground; 74 | + (void)hideBackgroundAnimated:(BOOL)animated; 75 | 76 | @end 77 | 78 | @implementation CustomKeyWindow 79 | 80 | #pragma mark - interface 81 | 82 | // AlertView action 83 | - (void)show 84 | { 85 | self.oldKeyWindow = [[UIApplication sharedApplication] keyWindow]; 86 | 87 | if (![[CustomKeyWindow sharedQueue] containsObject:self]) { 88 | [[CustomKeyWindow sharedQueue] addObject:self]; 89 | } 90 | 91 | if ([CustomKeyWindow isAnimating]) { 92 | return; // wait for next turn 93 | } 94 | 95 | if (self.isVisible) { 96 | return; 97 | } 98 | 99 | if ([CustomKeyWindow currentAlertView].isVisible) { 100 | CustomKeyWindow *alert = [CustomKeyWindow currentAlertView]; 101 | [alert dismissWithCleanup:NO]; 102 | return; 103 | } 104 | 105 | if (self.willShowHandler) { 106 | self.willShowHandler(self); 107 | } 108 | 109 | self.visible = YES; 110 | 111 | [CustomKeyWindow setAnimating:YES]; 112 | [CustomKeyWindow setCurrentAlertView:self]; 113 | 114 | // transition background 115 | [CustomKeyWindow showBackground]; 116 | 117 | CusKeyWindowRootViewController *viewController = [self getKeyWindowRootViewController]; 118 | 119 | if ([self.oldKeyWindow.rootViewController respondsToSelector:@selector(prefersStatusBarHidden)]) { 120 | viewController.rootViewControllerPrefersStatusBarHidden = self.oldKeyWindow.rootViewController.prefersStatusBarHidden; 121 | __customKeyWindow_rootViewController_prefersStatusBarHidden = self.oldKeyWindow.rootViewController.prefersStatusBarHidden; 122 | } 123 | 124 | if (!self.alertWindow) { 125 | UIWindow *window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 126 | window.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 127 | window.opaque = NO; 128 | window.windowLevel = UIWindowLevelAlert; 129 | window.rootViewController = viewController; 130 | self.alertWindow = window; 131 | } 132 | [self.alertWindow makeKeyAndVisible]; 133 | [self validateLayout]; 134 | 135 | [self transitionInCompletion:^{ 136 | if (self.didShowHandler) { 137 | self.didShowHandler(self); 138 | } 139 | 140 | [CustomKeyWindow setAnimating:NO]; 141 | 142 | NSInteger index = [[CustomKeyWindow sharedQueue] indexOfObject:self]; 143 | if (index < [CustomKeyWindow sharedQueue].count - 1) { 144 | [self dismissWithCleanup:NO]; // dismiss to show next alert view 145 | } 146 | }]; 147 | } 148 | 149 | - (void)validateLayout 150 | { 151 | 152 | } 153 | 154 | - (void)dismiss 155 | { 156 | [self dismissWithCleanup:YES]; 157 | } 158 | 159 | - (CusKeyWindowRootViewController *)getKeyWindowRootViewController 160 | { 161 | return [[CusKeyWindowRootViewController alloc]initWithCustomKeyWindow:self]; 162 | } 163 | 164 | - (void)windowDidDisappear 165 | { 166 | [self.alertWindow removeFromSuperview]; 167 | self.alertWindow = nil; 168 | } 169 | 170 | - (void)shake 171 | { 172 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.translation.x"]; 173 | animation.duration = 0.1; 174 | animation.repeatCount = 3; 175 | animation.autoreverses = YES; 176 | // animation.fromValue = [NSNumber numberWithFloat:0.0]; 177 | animation.toValue = [NSNumber numberWithFloat:10.0]; 178 | [self.layer removeAllAnimations]; 179 | [self.layer addAnimation:animation forKey:@"transform.translation.x"]; 180 | 181 | } 182 | // Operation 183 | - (void)cleanAllPenddingAlert 184 | { 185 | [[CustomKeyWindow sharedQueue] removeAllObjects]; 186 | } 187 | 188 | #pragma mark - CXAlertView PV 189 | + (NSMutableArray *)sharedQueue 190 | { 191 | if (!__customKeyWindow_custom_key_window_queue) { 192 | __customKeyWindow_custom_key_window_queue = [NSMutableArray array]; 193 | } 194 | return __customKeyWindow_custom_key_window_queue; 195 | } 196 | 197 | + (CustomKeyWindow *)currentAlertView 198 | { 199 | return __customKeyWindow_key_window_current_view; 200 | } 201 | 202 | + (void)setCurrentAlertView:(CustomKeyWindow *)alertView 203 | { 204 | __customKeyWindow_key_window_current_view = alertView; 205 | } 206 | 207 | + (BOOL)isAnimating 208 | { 209 | return __customKeyWindow_key_window_animating; 210 | } 211 | 212 | + (void)setAnimating:(BOOL)animating 213 | { 214 | __customKeyWindow_key_window_animating = animating; 215 | } 216 | 217 | + (void)showBackground 218 | { 219 | if (!__customKeyWindow_key_background_window) { 220 | 221 | CGSize screenSize = [self currentScreenSize]; 222 | 223 | __customKeyWindow_key_background_window = [[CustomKeyWindowBackgroundWindow alloc] initWithFrame:CGRectMake(0, 0, screenSize.width, screenSize.height)]; 224 | } 225 | 226 | [__customKeyWindow_key_background_window makeKeyAndVisible]; 227 | __customKeyWindow_key_background_window.alpha = 0; 228 | [UIView animateWithDuration:0.3 229 | animations:^{ 230 | __customKeyWindow_key_background_window.alpha = 1; 231 | }]; 232 | } 233 | 234 | + (CGSize)currentScreenSize 235 | { 236 | CGRect frame; 237 | #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 238 | if ([[UIScreen mainScreen] respondsToSelector:@selector(nativeBounds)]) { 239 | frame = [UIScreen mainScreen].nativeBounds; 240 | } 241 | else { 242 | frame = [UIScreen mainScreen].bounds; 243 | } 244 | #else 245 | frame = [UIScreen mainScreen].bounds; 246 | #endif 247 | 248 | CGFloat screenWidth = frame.size.width; 249 | CGFloat screenHeight = frame.size.height; 250 | 251 | UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation]; 252 | if (UIInterfaceOrientationIsLandscape(interfaceOrientation) && ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)) { 253 | CGFloat tmp = screenWidth; 254 | screenWidth = screenHeight; 255 | screenHeight = tmp; 256 | } 257 | 258 | return CGSizeMake(screenWidth, screenHeight); 259 | } 260 | 261 | 262 | + (void)hideBackgroundAnimated:(BOOL)animated 263 | { 264 | if (!animated) { 265 | [__customKeyWindow_key_background_window removeFromSuperview]; 266 | __customKeyWindow_key_background_window = nil; 267 | return; 268 | } 269 | [UIView animateWithDuration:0.3 270 | animations:^{ 271 | __customKeyWindow_key_background_window.alpha = 0; 272 | } 273 | completion:^(BOOL finished) { 274 | [__customKeyWindow_key_background_window removeFromSuperview]; 275 | __customKeyWindow_key_background_window = nil; 276 | }]; 277 | } 278 | 279 | - (void)dismissWithCleanup:(BOOL)cleanup 280 | { 281 | BOOL isVisible = self.isVisible; 282 | 283 | if (isVisible) { 284 | if (self.willDismissHandler) { 285 | self.willDismissHandler(self); 286 | } 287 | } 288 | 289 | void (^dismissComplete)(void) = ^{ 290 | self.visible = NO; 291 | [self windowDidDisappear]; 292 | 293 | [CustomKeyWindow setCurrentAlertView:nil]; 294 | 295 | // show next alertView 296 | CustomKeyWindow *nextAlertView; 297 | NSInteger index = [[CustomKeyWindow sharedQueue] indexOfObject:self]; 298 | if (index != NSNotFound && index < [CustomKeyWindow sharedQueue].count - 1) { 299 | nextAlertView = [CustomKeyWindow sharedQueue][index + 1]; 300 | } 301 | 302 | if (cleanup) { 303 | [[CustomKeyWindow sharedQueue] removeObject:self]; 304 | } 305 | 306 | [CustomKeyWindow setAnimating:NO]; 307 | 308 | if (isVisible) { 309 | if (self.didDismissHandler) { 310 | self.didDismissHandler(self); 311 | } 312 | } 313 | 314 | // check if we should show next alert 315 | if (!isVisible) { 316 | return; 317 | } 318 | 319 | if (nextAlertView) { 320 | [nextAlertView show]; 321 | } else { 322 | // show last alert view 323 | if ([CustomKeyWindow sharedQueue].count > 0) { 324 | CustomKeyWindow *alert = [[CustomKeyWindow sharedQueue] lastObject]; 325 | [alert show]; 326 | } 327 | } 328 | }; 329 | 330 | if (isVisible) { 331 | [CustomKeyWindow setAnimating:YES]; 332 | [self transitionOutCompletion:dismissComplete]; 333 | 334 | if ([CustomKeyWindow sharedQueue].count == 1) { 335 | [CustomKeyWindow hideBackgroundAnimated:YES]; 336 | } 337 | 338 | } else { 339 | dismissComplete(); 340 | 341 | if ([CustomKeyWindow sharedQueue].count == 0) { 342 | [CustomKeyWindow hideBackgroundAnimated:YES]; 343 | } 344 | } 345 | 346 | [_oldKeyWindow makeKeyWindow]; 347 | _oldKeyWindow.hidden = NO; 348 | } 349 | // Transition 350 | - (void)transitionInCompletion:(void(^)(void))completion 351 | { 352 | // _containerView.alpha = 0; 353 | // _containerView.transform = CGAffineTransformMakeScale(1.2, 1.2); 354 | // 355 | // _blurView.alpha = 0.9; 356 | // _blurView.transform = CGAffineTransformMakeScale(1.2, 1.2); 357 | // 358 | // [UIView animateWithDuration:0.3 359 | // animations:^{ 360 | // _containerView.alpha = 1.; 361 | // _containerView.transform = CGAffineTransformMakeScale(1.0,1.0); 362 | // 363 | // _blurView.alpha = 1.; 364 | // _blurView.transform = CGAffineTransformMakeScale(1.0,1.0); 365 | // } 366 | // completion:^(BOOL finished) { 367 | // [_blurView blur]; 368 | // if (completion) { 369 | // completion(); 370 | // } 371 | // }]; 372 | } 373 | 374 | - (void)transitionOutCompletion:(void(^)(void))completion 375 | { 376 | // [UIView animateWithDuration:0.25 377 | // animations:^{ 378 | // _containerView.alpha = 0; 379 | // _containerView.transform = CGAffineTransformMakeScale(0.9,0.9); 380 | // 381 | // _blurView.alpha = 0.9; 382 | // _blurView.transform = CGAffineTransformMakeScale(0.9,0.9); 383 | // } 384 | // completion:^(BOOL finished) { 385 | // if (completion) { 386 | // completion(); 387 | // } 388 | // }]; 389 | } 390 | @end 391 | -------------------------------------------------------------------------------- /JLAlertView/JLAlertView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 34056A0D1E5E89DA00749226 /* JLBlureView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34056A0C1E5E89DA00749226 /* JLBlureView.m */; }; 11 | 340E6D221E14E87F008862F0 /* JLAlertBackGroundController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340E6D211E14E87F008862F0 /* JLAlertBackGroundController.m */; }; 12 | 340E6D251E14EA17008862F0 /* JLAlertBackGroundWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 340E6D241E14EA17008862F0 /* JLAlertBackGroundWindow.m */; }; 13 | 340E6D281E14EA5F008862F0 /* JLAlertWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 340E6D271E14EA5F008862F0 /* JLAlertWindow.m */; }; 14 | 34DF18401DF9111A0044858C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DF183F1DF9111A0044858C /* main.m */; }; 15 | 34DF18431DF9111A0044858C /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DF18421DF9111A0044858C /* AppDelegate.m */; }; 16 | 34DF18461DF9111A0044858C /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DF18451DF9111A0044858C /* ViewController.m */; }; 17 | 34DF18491DF9111A0044858C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 34DF18471DF9111A0044858C /* Main.storyboard */; }; 18 | 34DF184B1DF9111A0044858C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 34DF184A1DF9111A0044858C /* Assets.xcassets */; }; 19 | 34DF184E1DF9111A0044858C /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 34DF184C1DF9111A0044858C /* LaunchScreen.storyboard */; }; 20 | 34DF18581DF9114D0044858C /* JLAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DF18571DF9114D0044858C /* JLAlertView.m */; }; 21 | 34DF185B1DF92ABC0044858C /* JLAlertViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DF185A1DF92ABC0044858C /* JLAlertViewController.m */; }; 22 | F44023EC21BFFC9E009E5DE9 /* CusKeyWindowRootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F44023E821BFFC9E009E5DE9 /* CusKeyWindowRootViewController.m */; }; 23 | F44023ED21BFFC9E009E5DE9 /* CustomKeyWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = F44023EA21BFFC9E009E5DE9 /* CustomKeyWindow.m */; }; 24 | /* End PBXBuildFile section */ 25 | 26 | /* Begin PBXFileReference section */ 27 | 34056A0B1E5E89DA00749226 /* JLBlureView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JLBlureView.h; sourceTree = ""; }; 28 | 34056A0C1E5E89DA00749226 /* JLBlureView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JLBlureView.m; sourceTree = ""; }; 29 | 340E6D201E14E87F008862F0 /* JLAlertBackGroundController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JLAlertBackGroundController.h; sourceTree = ""; }; 30 | 340E6D211E14E87F008862F0 /* JLAlertBackGroundController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JLAlertBackGroundController.m; sourceTree = ""; }; 31 | 340E6D231E14EA17008862F0 /* JLAlertBackGroundWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JLAlertBackGroundWindow.h; sourceTree = ""; }; 32 | 340E6D241E14EA17008862F0 /* JLAlertBackGroundWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JLAlertBackGroundWindow.m; sourceTree = ""; }; 33 | 340E6D261E14EA5F008862F0 /* JLAlertWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JLAlertWindow.h; sourceTree = ""; }; 34 | 340E6D271E14EA5F008862F0 /* JLAlertWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JLAlertWindow.m; sourceTree = ""; }; 35 | 344722881E1505D700F37F4F /* JLAlertHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JLAlertHeader.h; sourceTree = ""; }; 36 | 34DF183B1DF9111A0044858C /* JLAlertView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = JLAlertView.app; sourceTree = BUILT_PRODUCTS_DIR; }; 37 | 34DF183F1DF9111A0044858C /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 38 | 34DF18411DF9111A0044858C /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 39 | 34DF18421DF9111A0044858C /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 40 | 34DF18441DF9111A0044858C /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 41 | 34DF18451DF9111A0044858C /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 42 | 34DF18481DF9111A0044858C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 43 | 34DF184A1DF9111A0044858C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 44 | 34DF184D1DF9111A0044858C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 45 | 34DF184F1DF9111A0044858C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 46 | 34DF18561DF9114D0044858C /* JLAlertView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JLAlertView.h; sourceTree = ""; }; 47 | 34DF18571DF9114D0044858C /* JLAlertView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JLAlertView.m; sourceTree = ""; }; 48 | 34DF18591DF92ABC0044858C /* JLAlertViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JLAlertViewController.h; sourceTree = ""; }; 49 | 34DF185A1DF92ABC0044858C /* JLAlertViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JLAlertViewController.m; sourceTree = ""; }; 50 | F44023E821BFFC9E009E5DE9 /* CusKeyWindowRootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CusKeyWindowRootViewController.m; sourceTree = ""; }; 51 | F44023E921BFFC9E009E5DE9 /* CusKeyWindowRootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CusKeyWindowRootViewController.h; sourceTree = ""; }; 52 | F44023EA21BFFC9E009E5DE9 /* CustomKeyWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CustomKeyWindow.m; sourceTree = ""; }; 53 | F44023EB21BFFC9E009E5DE9 /* CustomKeyWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomKeyWindow.h; sourceTree = ""; }; 54 | /* End PBXFileReference section */ 55 | 56 | /* Begin PBXFrameworksBuildPhase section */ 57 | 34DF18381DF9111A0044858C /* Frameworks */ = { 58 | isa = PBXFrameworksBuildPhase; 59 | buildActionMask = 2147483647; 60 | files = ( 61 | ); 62 | runOnlyForDeploymentPostprocessing = 0; 63 | }; 64 | /* End PBXFrameworksBuildPhase section */ 65 | 66 | /* Begin PBXGroup section */ 67 | 34DF18321DF9111A0044858C = { 68 | isa = PBXGroup; 69 | children = ( 70 | 34DF183D1DF9111A0044858C /* JLAlertView */, 71 | 34DF183C1DF9111A0044858C /* Products */, 72 | ); 73 | sourceTree = ""; 74 | }; 75 | 34DF183C1DF9111A0044858C /* Products */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | 34DF183B1DF9111A0044858C /* JLAlertView.app */, 79 | ); 80 | name = Products; 81 | sourceTree = ""; 82 | }; 83 | 34DF183D1DF9111A0044858C /* JLAlertView */ = { 84 | isa = PBXGroup; 85 | children = ( 86 | 34DF18551DF9113C0044858C /* JLAlertView */, 87 | 34DF18411DF9111A0044858C /* AppDelegate.h */, 88 | 34DF18421DF9111A0044858C /* AppDelegate.m */, 89 | 34DF18441DF9111A0044858C /* ViewController.h */, 90 | 34DF18451DF9111A0044858C /* ViewController.m */, 91 | 34DF18471DF9111A0044858C /* Main.storyboard */, 92 | 34DF184A1DF9111A0044858C /* Assets.xcassets */, 93 | 34DF184C1DF9111A0044858C /* LaunchScreen.storyboard */, 94 | 34DF184F1DF9111A0044858C /* Info.plist */, 95 | 34DF183E1DF9111A0044858C /* Supporting Files */, 96 | ); 97 | path = JLAlertView; 98 | sourceTree = ""; 99 | }; 100 | 34DF183E1DF9111A0044858C /* Supporting Files */ = { 101 | isa = PBXGroup; 102 | children = ( 103 | 34DF183F1DF9111A0044858C /* main.m */, 104 | ); 105 | name = "Supporting Files"; 106 | sourceTree = ""; 107 | }; 108 | 34DF18551DF9113C0044858C /* JLAlertView */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | F44023E921BFFC9E009E5DE9 /* CusKeyWindowRootViewController.h */, 112 | F44023E821BFFC9E009E5DE9 /* CusKeyWindowRootViewController.m */, 113 | F44023EB21BFFC9E009E5DE9 /* CustomKeyWindow.h */, 114 | F44023EA21BFFC9E009E5DE9 /* CustomKeyWindow.m */, 115 | 34DF18561DF9114D0044858C /* JLAlertView.h */, 116 | 34DF18571DF9114D0044858C /* JLAlertView.m */, 117 | 344722881E1505D700F37F4F /* JLAlertHeader.h */, 118 | 340E6D261E14EA5F008862F0 /* JLAlertWindow.h */, 119 | 340E6D271E14EA5F008862F0 /* JLAlertWindow.m */, 120 | 340E6D231E14EA17008862F0 /* JLAlertBackGroundWindow.h */, 121 | 340E6D241E14EA17008862F0 /* JLAlertBackGroundWindow.m */, 122 | 340E6D201E14E87F008862F0 /* JLAlertBackGroundController.h */, 123 | 340E6D211E14E87F008862F0 /* JLAlertBackGroundController.m */, 124 | 34DF18591DF92ABC0044858C /* JLAlertViewController.h */, 125 | 34DF185A1DF92ABC0044858C /* JLAlertViewController.m */, 126 | 34056A0B1E5E89DA00749226 /* JLBlureView.h */, 127 | 34056A0C1E5E89DA00749226 /* JLBlureView.m */, 128 | ); 129 | path = JLAlertView; 130 | sourceTree = ""; 131 | }; 132 | /* End PBXGroup section */ 133 | 134 | /* Begin PBXNativeTarget section */ 135 | 34DF183A1DF9111A0044858C /* JLAlertView */ = { 136 | isa = PBXNativeTarget; 137 | buildConfigurationList = 34DF18521DF9111A0044858C /* Build configuration list for PBXNativeTarget "JLAlertView" */; 138 | buildPhases = ( 139 | 34DF18371DF9111A0044858C /* Sources */, 140 | 34DF18381DF9111A0044858C /* Frameworks */, 141 | 34DF18391DF9111A0044858C /* Resources */, 142 | ); 143 | buildRules = ( 144 | ); 145 | dependencies = ( 146 | ); 147 | name = JLAlertView; 148 | productName = JLAlertView; 149 | productReference = 34DF183B1DF9111A0044858C /* JLAlertView.app */; 150 | productType = "com.apple.product-type.application"; 151 | }; 152 | /* End PBXNativeTarget section */ 153 | 154 | /* Begin PBXProject section */ 155 | 34DF18331DF9111A0044858C /* Project object */ = { 156 | isa = PBXProject; 157 | attributes = { 158 | LastUpgradeCheck = 0810; 159 | ORGANIZATIONNAME = JL; 160 | TargetAttributes = { 161 | 34DF183A1DF9111A0044858C = { 162 | CreatedOnToolsVersion = 8.1; 163 | DevelopmentTeam = NVAFMDWZJC; 164 | ProvisioningStyle = Automatic; 165 | }; 166 | }; 167 | }; 168 | buildConfigurationList = 34DF18361DF9111A0044858C /* Build configuration list for PBXProject "JLAlertView" */; 169 | compatibilityVersion = "Xcode 3.2"; 170 | developmentRegion = English; 171 | hasScannedForEncodings = 0; 172 | knownRegions = ( 173 | en, 174 | Base, 175 | ); 176 | mainGroup = 34DF18321DF9111A0044858C; 177 | productRefGroup = 34DF183C1DF9111A0044858C /* Products */; 178 | projectDirPath = ""; 179 | projectRoot = ""; 180 | targets = ( 181 | 34DF183A1DF9111A0044858C /* JLAlertView */, 182 | ); 183 | }; 184 | /* End PBXProject section */ 185 | 186 | /* Begin PBXResourcesBuildPhase section */ 187 | 34DF18391DF9111A0044858C /* Resources */ = { 188 | isa = PBXResourcesBuildPhase; 189 | buildActionMask = 2147483647; 190 | files = ( 191 | 34DF184E1DF9111A0044858C /* LaunchScreen.storyboard in Resources */, 192 | 34DF184B1DF9111A0044858C /* Assets.xcassets in Resources */, 193 | 34DF18491DF9111A0044858C /* Main.storyboard in Resources */, 194 | ); 195 | runOnlyForDeploymentPostprocessing = 0; 196 | }; 197 | /* End PBXResourcesBuildPhase section */ 198 | 199 | /* Begin PBXSourcesBuildPhase section */ 200 | 34DF18371DF9111A0044858C /* Sources */ = { 201 | isa = PBXSourcesBuildPhase; 202 | buildActionMask = 2147483647; 203 | files = ( 204 | 340E6D281E14EA5F008862F0 /* JLAlertWindow.m in Sources */, 205 | 34056A0D1E5E89DA00749226 /* JLBlureView.m in Sources */, 206 | F44023EC21BFFC9E009E5DE9 /* CusKeyWindowRootViewController.m in Sources */, 207 | 34DF185B1DF92ABC0044858C /* JLAlertViewController.m in Sources */, 208 | 34DF18461DF9111A0044858C /* ViewController.m in Sources */, 209 | 340E6D251E14EA17008862F0 /* JLAlertBackGroundWindow.m in Sources */, 210 | 34DF18581DF9114D0044858C /* JLAlertView.m in Sources */, 211 | 34DF18431DF9111A0044858C /* AppDelegate.m in Sources */, 212 | F44023ED21BFFC9E009E5DE9 /* CustomKeyWindow.m in Sources */, 213 | 34DF18401DF9111A0044858C /* main.m in Sources */, 214 | 340E6D221E14E87F008862F0 /* JLAlertBackGroundController.m in Sources */, 215 | ); 216 | runOnlyForDeploymentPostprocessing = 0; 217 | }; 218 | /* End PBXSourcesBuildPhase section */ 219 | 220 | /* Begin PBXVariantGroup section */ 221 | 34DF18471DF9111A0044858C /* Main.storyboard */ = { 222 | isa = PBXVariantGroup; 223 | children = ( 224 | 34DF18481DF9111A0044858C /* Base */, 225 | ); 226 | name = Main.storyboard; 227 | sourceTree = ""; 228 | }; 229 | 34DF184C1DF9111A0044858C /* LaunchScreen.storyboard */ = { 230 | isa = PBXVariantGroup; 231 | children = ( 232 | 34DF184D1DF9111A0044858C /* Base */, 233 | ); 234 | name = LaunchScreen.storyboard; 235 | sourceTree = ""; 236 | }; 237 | /* End PBXVariantGroup section */ 238 | 239 | /* Begin XCBuildConfiguration section */ 240 | 34DF18501DF9111A0044858C /* Debug */ = { 241 | isa = XCBuildConfiguration; 242 | buildSettings = { 243 | ALWAYS_SEARCH_USER_PATHS = NO; 244 | CLANG_ANALYZER_NONNULL = YES; 245 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 246 | CLANG_CXX_LIBRARY = "libc++"; 247 | CLANG_ENABLE_MODULES = YES; 248 | CLANG_ENABLE_OBJC_ARC = YES; 249 | CLANG_WARN_BOOL_CONVERSION = YES; 250 | CLANG_WARN_CONSTANT_CONVERSION = YES; 251 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 252 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 253 | CLANG_WARN_EMPTY_BODY = YES; 254 | CLANG_WARN_ENUM_CONVERSION = YES; 255 | CLANG_WARN_INFINITE_RECURSION = YES; 256 | CLANG_WARN_INT_CONVERSION = YES; 257 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 258 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 259 | CLANG_WARN_UNREACHABLE_CODE = YES; 260 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 261 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 262 | COPY_PHASE_STRIP = NO; 263 | DEBUG_INFORMATION_FORMAT = dwarf; 264 | ENABLE_STRICT_OBJC_MSGSEND = YES; 265 | ENABLE_TESTABILITY = YES; 266 | GCC_C_LANGUAGE_STANDARD = gnu99; 267 | GCC_DYNAMIC_NO_PIC = NO; 268 | GCC_NO_COMMON_BLOCKS = YES; 269 | GCC_OPTIMIZATION_LEVEL = 0; 270 | GCC_PREPROCESSOR_DEFINITIONS = ( 271 | "DEBUG=1", 272 | "$(inherited)", 273 | ); 274 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 275 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 276 | GCC_WARN_UNDECLARED_SELECTOR = YES; 277 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 278 | GCC_WARN_UNUSED_FUNCTION = YES; 279 | GCC_WARN_UNUSED_VARIABLE = YES; 280 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 281 | MTL_ENABLE_DEBUG_INFO = YES; 282 | ONLY_ACTIVE_ARCH = YES; 283 | SDKROOT = iphoneos; 284 | }; 285 | name = Debug; 286 | }; 287 | 34DF18511DF9111A0044858C /* Release */ = { 288 | isa = XCBuildConfiguration; 289 | buildSettings = { 290 | ALWAYS_SEARCH_USER_PATHS = NO; 291 | CLANG_ANALYZER_NONNULL = YES; 292 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 293 | CLANG_CXX_LIBRARY = "libc++"; 294 | CLANG_ENABLE_MODULES = YES; 295 | CLANG_ENABLE_OBJC_ARC = YES; 296 | CLANG_WARN_BOOL_CONVERSION = YES; 297 | CLANG_WARN_CONSTANT_CONVERSION = YES; 298 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 299 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 300 | CLANG_WARN_EMPTY_BODY = YES; 301 | CLANG_WARN_ENUM_CONVERSION = YES; 302 | CLANG_WARN_INFINITE_RECURSION = YES; 303 | CLANG_WARN_INT_CONVERSION = YES; 304 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 305 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 306 | CLANG_WARN_UNREACHABLE_CODE = YES; 307 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 308 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 309 | COPY_PHASE_STRIP = NO; 310 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 311 | ENABLE_NS_ASSERTIONS = NO; 312 | ENABLE_STRICT_OBJC_MSGSEND = YES; 313 | GCC_C_LANGUAGE_STANDARD = gnu99; 314 | GCC_NO_COMMON_BLOCKS = YES; 315 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 316 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 317 | GCC_WARN_UNDECLARED_SELECTOR = YES; 318 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 319 | GCC_WARN_UNUSED_FUNCTION = YES; 320 | GCC_WARN_UNUSED_VARIABLE = YES; 321 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 322 | MTL_ENABLE_DEBUG_INFO = NO; 323 | SDKROOT = iphoneos; 324 | VALIDATE_PRODUCT = YES; 325 | }; 326 | name = Release; 327 | }; 328 | 34DF18531DF9111A0044858C /* Debug */ = { 329 | isa = XCBuildConfiguration; 330 | buildSettings = { 331 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 332 | DEVELOPMENT_TEAM = NVAFMDWZJC; 333 | INFOPLIST_FILE = JLAlertView/Info.plist; 334 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 335 | PRODUCT_BUNDLE_IDENTIFIER = com.JL.AlertView.JLAlertView; 336 | PRODUCT_NAME = "$(TARGET_NAME)"; 337 | }; 338 | name = Debug; 339 | }; 340 | 34DF18541DF9111A0044858C /* Release */ = { 341 | isa = XCBuildConfiguration; 342 | buildSettings = { 343 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 344 | DEVELOPMENT_TEAM = NVAFMDWZJC; 345 | INFOPLIST_FILE = JLAlertView/Info.plist; 346 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 347 | PRODUCT_BUNDLE_IDENTIFIER = com.JL.AlertView.JLAlertView; 348 | PRODUCT_NAME = "$(TARGET_NAME)"; 349 | }; 350 | name = Release; 351 | }; 352 | /* End XCBuildConfiguration section */ 353 | 354 | /* Begin XCConfigurationList section */ 355 | 34DF18361DF9111A0044858C /* Build configuration list for PBXProject "JLAlertView" */ = { 356 | isa = XCConfigurationList; 357 | buildConfigurations = ( 358 | 34DF18501DF9111A0044858C /* Debug */, 359 | 34DF18511DF9111A0044858C /* Release */, 360 | ); 361 | defaultConfigurationIsVisible = 0; 362 | defaultConfigurationName = Release; 363 | }; 364 | 34DF18521DF9111A0044858C /* Build configuration list for PBXNativeTarget "JLAlertView" */ = { 365 | isa = XCConfigurationList; 366 | buildConfigurations = ( 367 | 34DF18531DF9111A0044858C /* Debug */, 368 | 34DF18541DF9111A0044858C /* Release */, 369 | ); 370 | defaultConfigurationIsVisible = 0; 371 | defaultConfigurationName = Release; 372 | }; 373 | /* End XCConfigurationList section */ 374 | }; 375 | rootObject = 34DF18331DF9111A0044858C /* Project object */; 376 | } 377 | -------------------------------------------------------------------------------- /JLAlertView/JLAlertView/JLAlertView/JLAlertView.m: -------------------------------------------------------------------------------- 1 | // 2 | // JLAlertView.h 3 | // JLAlertView 4 | // 5 | // Created by Wangjianlong on 2016/12/8. 6 | // Copyright © 2016年 JL. All rights reserved. 7 | // 8 | 9 | #import "JLAlertView.h" 10 | #import "AppDelegate.h" 11 | #import "JLAlertViewController.h" 12 | #import "JLAlertWindow.h" 13 | #import "JLAlertBackGroundWindow.h" 14 | #import "JLAlertHeader.h" 15 | 16 | 17 | static UIWindow *__customKeyWindow__oldKeyWindow; 18 | static UIWindow *__customKeyWindow__backgroundWindow; 19 | @interface JLAlertView () 20 | 21 | 22 | /**内容背景视图 覆盖 标题 和 副标题*/ 23 | @property (nonatomic, strong)UIView *whiteBackView; 24 | 25 | /**mainView*/ 26 | @property (nonatomic, strong)UIView *mainView; 27 | 28 | /**topTitle*/ 29 | @property (nonatomic, strong)UILabel *topTitleLabel; 30 | 31 | /**second title*/ 32 | @property (nonatomic, strong)UILabel *secondDescription; 33 | 34 | /**显示内容队列*/ 35 | @property (nonatomic, strong)NSMutableArray *contentDatas; 36 | 37 | /**确定按钮*/ 38 | @property (nonatomic, strong)UIButton *sureBtn; 39 | 40 | /**按钮数组*/ 41 | @property (nonatomic, strong)NSMutableArray *btns; 42 | 43 | /**是否为两个按钮*/ 44 | @property (nonatomic, assign)BOOL isDouble; 45 | 46 | /**contentW*/ 47 | @property (nonatomic, assign)CGFloat contentW; 48 | 49 | /**contentW*/ 50 | @property (nonatomic, assign)UIEdgeInsets contentInsets; 51 | 52 | /**widndow*/ 53 | @property (nonatomic, strong)UIWindow *oldKeyWindow; 54 | 55 | @property (nonatomic, strong)UIWindow *alertWindow; 56 | 57 | @property (nonatomic, strong)JLAlertBackGroundWindow *alert__BackGroundView; 58 | 59 | /**是否可见*/ 60 | @property (nonatomic, assign,getter=isVisible)BOOL visible; 61 | 62 | /**ge */ 63 | @property (nonatomic, weak)UIViewController *associatedViewController; 64 | 65 | 66 | @end 67 | 68 | 69 | @implementation JLAlertView 70 | 71 | #pragma mark - interface 72 | 73 | - (void)show 74 | { 75 | _oldKeyWindow = [UIApplication sharedApplication].keyWindow; 76 | 77 | [JLAlertView getOldKeyWindow]; 78 | 79 | if (![[JLAlertView allAlerts]containsObject:self]) { 80 | [[JLAlertView allAlerts] addObject:self]; 81 | } 82 | 83 | if (self.isVisible) { 84 | return; 85 | } 86 | 87 | if ([JLAlertView currentAlertView].isVisible) { 88 | // [self transitionOutCompletion:^{ 89 | JLAlertView *alertView = [JLAlertView currentAlertView]; 90 | [alertView dismissWithClean:NO]; 91 | // }]; 92 | 93 | return; 94 | } 95 | 96 | 97 | self.visible = YES; 98 | [JLAlertView setCurrentAlertView:self]; 99 | [JLAlertView showBackground]; 100 | 101 | if (self.associatedViewController == nil) { 102 | JLAlertViewController *viewController = [[JLAlertViewController alloc] initWithAlertView:self]; 103 | viewController.rootViewControllerPrefersStatusBarHidden = JLAlertView_prefersStatusBarHidden; 104 | viewController.rootViewControllerCanRoration = JLAlertView_canrorate; 105 | viewController.rootViewControllerInterfaceOrientationMask = JLAlertView_InterfaceOrientationMask; 106 | 107 | JLAlertWindow *window = [[JLAlertWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 108 | window.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 109 | window.opaque = NO; 110 | window.windowLevel = UIWindowLevelAlert; 111 | window.rootViewController = viewController; 112 | self.associatedViewController = viewController; 113 | self.alertWindow = window; 114 | } 115 | 116 | // [UIView animateWithDuration:0.3 animations:^{ 117 | // // _alertWindow.hidden = NO; 118 | // _alertWindow.alpha = 1; 119 | // }]; 120 | [self.alertWindow makeKeyAndVisible]; 121 | 122 | [self transitionInCompletion:^{ 123 | // if (self.didShowHandler) { 124 | // self.didShowHandler(self); 125 | // } 126 | 127 | // [JLAlertView setAnimating:NO]; 128 | 129 | NSInteger index = [[JLAlertView allAlerts] indexOfObject:self]; 130 | if (index < [JLAlertView allAlerts].count - 1) { 131 | [self dismissWithClean:NO]; // dismiss to show next alert view 132 | } 133 | }]; 134 | 135 | } 136 | 137 | - (void)dismissWithClean:(BOOL)clean 138 | { 139 | self.visible = NO; 140 | [JLAlertView setCurrentAlertView:nil]; 141 | [self tearDown:clean]; 142 | 143 | JLAlertView *nextAlertView; 144 | NSInteger index = [[JLAlertView allAlerts] indexOfObject:self]; 145 | if (index != NSNotFound && index < [JLAlertView allAlerts].count - 1) { 146 | nextAlertView = [JLAlertView allAlerts][index + 1]; 147 | } 148 | 149 | if (clean) { 150 | if (self.superview) { 151 | [self removeFromSuperview]; 152 | } 153 | [[JLAlertView allAlerts]removeObject:self]; 154 | 155 | } 156 | 157 | if (nextAlertView) { 158 | [nextAlertView show]; 159 | return; 160 | } else { 161 | // show last alert view 162 | if ([JLAlertView allAlerts].count > 0) { 163 | JLAlertView *alert = [[JLAlertView allAlerts] lastObject]; 164 | 165 | [alert show]; 166 | return; 167 | } 168 | } 169 | [_oldKeyWindow makeKeyAndVisible]; 170 | _oldKeyWindow.hidden = NO; 171 | 172 | __alert__currentAlertView = nil; 173 | __customKeyWindow__oldKeyWindow = nil; 174 | __alert__alertElement = nil; 175 | } 176 | 177 | 178 | + (void)showBackground 179 | { 180 | if (!__customKeyWindow__backgroundWindow) { 181 | 182 | CGSize screenSize = [self currentScreenSize]; 183 | 184 | __customKeyWindow__backgroundWindow = [[JLAlertBackGroundWindow alloc] initWithFrame:CGRectMake(0, 0, screenSize.width, screenSize.height)]; 185 | } 186 | 187 | [__customKeyWindow__backgroundWindow makeKeyAndVisible]; 188 | __customKeyWindow__backgroundWindow.alpha = 0; 189 | [UIView animateWithDuration:0.3 190 | animations:^{ 191 | __customKeyWindow__backgroundWindow.alpha = 1; 192 | }]; 193 | } 194 | 195 | + (void)hideBackgroundAnimated:(BOOL)animated 196 | { 197 | if (!animated) { 198 | [__customKeyWindow__backgroundWindow removeFromSuperview]; 199 | __customKeyWindow__backgroundWindow = nil; 200 | return; 201 | } 202 | [UIView animateWithDuration:0.3 203 | animations:^{ 204 | __customKeyWindow__backgroundWindow.alpha = 0; 205 | } 206 | completion:^(BOOL finished) { 207 | [__customKeyWindow__backgroundWindow removeFromSuperview]; 208 | __customKeyWindow__backgroundWindow = nil; 209 | }]; 210 | } 211 | 212 | - (void)dealloc 213 | { 214 | NSLog(@"JLAlertView -- dealloc"); 215 | } 216 | 217 | 218 | - (instancetype)initWithTitle:(nullable NSString *)title message:(nullable NSString *)message delegate:(nullable id)delegate SureButtonTitle:(nullable NSString *)sureButtonTitle otherButtonTitles:(NSArray *) otherButtonTitles 219 | { 220 | if (self = [self initWithFrame:[UIScreen mainScreen].bounds]) { 221 | 222 | self.delegate = delegate; 223 | [self initializeDataWithTitle:title Message:message SureButtonTitle:sureButtonTitle otherButtonTitles:otherButtonTitles]; 224 | 225 | [self setUpViews]; 226 | 227 | [self initializeView]; 228 | 229 | } 230 | return self; 231 | } 232 | 233 | - (instancetype)initWithFrame:(CGRect)frame 234 | { 235 | if (self = [super initWithFrame:frame]) { 236 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willregin) name:UIApplicationDidEnterBackgroundNotification object:nil]; 237 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(becomeregin) name:UIApplicationDidBecomeActiveNotification object:nil]; 238 | } 239 | return self; 240 | } 241 | 242 | - (void)willregin 243 | { 244 | if (self.visible) { 245 | [self.oldKeyWindow makeKeyAndVisible]; 246 | [self tearDown:NO]; 247 | _alert__BackGroundView = nil; 248 | for (JLAlertView *view in [JLAlertView allAlerts]) { 249 | view.associatedViewController = nil; 250 | view.visible = NO; 251 | view.alertWindow = nil; 252 | } 253 | } 254 | } 255 | 256 | - (void)becomeregin 257 | { 258 | JLAlertView *alert = [[JLAlertView allAlerts] lastObject]; 259 | [alert show]; 260 | 261 | } 262 | 263 | #pragma mark - UI 264 | 265 | - (void)initializeDataWithTitle:(NSString *)title Message:(NSString *)seconTitle SureButtonTitle:(nullable NSString *)sureButtonTitle otherButtonTitles:(NSArray *) otherButtonTitles 266 | { 267 | _contentInsets = UIEdgeInsetsMake(20, 20, 20, 20); 268 | 269 | NSMutableDictionary *title_Dic = [NSMutableDictionary dictionary]; 270 | [title_Dic setObject:title?title:@"" forKey:JLAlertViewTopTitle]; 271 | [title_Dic setObject:seconTitle?seconTitle:@"" forKey:JLAlertViewSecondTitle]; 272 | [title_Dic setObject:sureButtonTitle?sureButtonTitle:@"" forKey:JLAlertViewSureButton]; 273 | [title_Dic setObject:otherButtonTitles?otherButtonTitles:@[] forKey:JLAlertViewOtherButtons]; 274 | 275 | 276 | 277 | [self.contentDatas addObject:title_Dic]; 278 | 279 | [self.btns removeAllObjects]; 280 | 281 | [self creatBtn]; 282 | } 283 | 284 | - (void)setUpViews 285 | { 286 | _mainView = [[UIView alloc]init]; 287 | _mainView.clipsToBounds = YES; 288 | _mainView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; 289 | 290 | _mainView.backgroundColor = [UIColor colorWithRed:221/255.0 green:221/255.0 blue:221/255.0 alpha:1.0f]; 291 | _mainView.layer.cornerRadius = 10; 292 | 293 | _topTitleLabel = [[UILabel alloc]init]; 294 | _topTitleLabel.backgroundColor = [UIColor clearColor]; 295 | _topTitleLabel.numberOfLines = 1; 296 | // [UIColor colorWithHexString:@"#333333"] 297 | _topTitleLabel.textColor = [UIColor blackColor]; 298 | _topTitleLabel.font = [UIFont boldSystemFontOfSize:18]; 299 | _topTitleLabel.textAlignment = NSTextAlignmentCenter; 300 | 301 | 302 | _secondDescription = [[UILabel alloc]init]; 303 | _secondDescription.backgroundColor = [UIColor clearColor]; 304 | _secondDescription.textColor = [UIColor blackColor]; 305 | _secondDescription.numberOfLines = 0; 306 | _secondDescription.font = [UIFont systemFontOfSize:14.]; 307 | _secondDescription.textAlignment = NSTextAlignmentLeft; 308 | } 309 | 310 | - (void)addButtonWithTitle:(nullable NSString *)title BtnColorStyle:(JLAlertViewBtnColor)btnColor 311 | { 312 | if (title && [title isEqualToString:@""] == NO) { 313 | UIButton *otherBtn = [UIButton buttonWithType:UIButtonTypeCustom]; 314 | [otherBtn addTarget:self action:@selector(cancleBtnClick:) forControlEvents:UIControlEventTouchUpInside]; 315 | UIColor *color = [UIColor colorWithRed:65/255.0 green:131/255.0 blue:1.0 alpha:1.0]; 316 | if (btnColor == JLAlertViewBtnColorGray) { 317 | color = [UIColor colorWithRed:85/255.0 green:85/255.0 blue:85/255.0 alpha:1.0]; 318 | } 319 | [otherBtn setTitleColor:color forState:UIControlStateNormal]; 320 | [otherBtn setTitle:title forState:UIControlStateNormal]; 321 | otherBtn.backgroundColor = [UIColor whiteColor]; 322 | [otherBtn.titleLabel setFont:[UIFont systemFontOfSize:16]]; 323 | 324 | if (self.contentDatas.count > 0) 325 | { 326 | NSDictionary *dic = self.contentDatas[0]; 327 | NSString *sureBtn = dic[JLAlertViewSureButton]; 328 | //如果有sureBtn,就与这个按钮交换,始终保持 sureBtn 在最大索引处 329 | if ([sureBtn isEqualToString:@""] == NO) { 330 | NSUInteger count; 331 | if (self.btns.count > 0) { 332 | count = _btns.count - 1; 333 | }else { 334 | count = 0; 335 | } 336 | [self.btns insertObject:otherBtn atIndex:count]; 337 | }else { 338 | [self.btns addObject:otherBtn]; 339 | } 340 | } 341 | 342 | [self initializeView]; 343 | } 344 | 345 | } 346 | 347 | - (void)initializeView 348 | { 349 | self.frame = [UIScreen mainScreen].bounds; 350 | self.backgroundColor = [UIColor clearColor]; 351 | self.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; 352 | 353 | 354 | if (!self.mainView.superview) { 355 | [self addSubview:self.mainView]; 356 | } 357 | if (!_whiteBackView.superview) { 358 | _whiteBackView = [[UIView alloc]init]; 359 | _whiteBackView.backgroundColor = [UIColor whiteColor]; 360 | [self.mainView addSubview:_whiteBackView]; 361 | } 362 | 363 | if (!self.topTitleLabel.superview) { 364 | [self.mainView addSubview:self.topTitleLabel]; 365 | } 366 | if (!self.secondDescription.superview) { 367 | [self.mainView addSubview:self.secondDescription]; 368 | } 369 | 370 | __block typeof(self)weakSelf = self; 371 | [self.btns enumerateObjectsUsingBlock:^(UIButton *obj, NSUInteger idx, BOOL * _Nonnull stop) { 372 | if (!obj.superview) { 373 | [weakSelf.mainView addSubview:obj]; 374 | } 375 | }]; 376 | } 377 | 378 | - (void)creatBtn 379 | { 380 | if (self.contentDatas.count > 0) 381 | { 382 | NSDictionary *dic = self.contentDatas[0]; 383 | NSArray *array = dic[JLAlertViewOtherButtons]; 384 | 385 | NSString *str = dic[JLAlertViewSureButton]; 386 | 387 | 388 | if (array && array.count > 0) { 389 | NSMutableArray *arr_m = [NSMutableArray arrayWithCapacity:array.count]; 390 | [array enumerateObjectsUsingBlock:^(NSString *obj, NSUInteger idx, BOOL * _Nonnull stop) { 391 | UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; 392 | [btn.titleLabel setFont:[UIFont systemFontOfSize:16]]; 393 | [btn addTarget:self action:@selector(cancleBtnClick:) forControlEvents:UIControlEventTouchUpInside]; 394 | [btn setTitle:obj forState:UIControlStateNormal]; 395 | btn.backgroundColor = [UIColor whiteColor]; 396 | [btn setTitleColor:[UIColor colorWithRed:85/255.0 green:85/255.0 blue:85/255.0 alpha:1.0] forState:UIControlStateNormal]; 397 | [arr_m addObject:btn]; 398 | 399 | }]; 400 | 401 | [self.btns addObjectsFromArray:arr_m]; 402 | } 403 | 404 | //只有主动传入 确认按钮标题.才会创建确认按钮 405 | if ([str isEqualToString:@""] == NO) { 406 | UIButton *sureBtn = [UIButton buttonWithType:UIButtonTypeCustom]; 407 | [sureBtn addTarget:self action:@selector(cancleBtnClick:) forControlEvents:UIControlEventTouchUpInside]; 408 | [sureBtn setTitleColor:[UIColor colorWithRed:65/255.0 green:131/255.0 blue:1.0 alpha:1.0] forState:UIControlStateNormal]; 409 | [sureBtn setTitle:str forState:UIControlStateNormal]; 410 | sureBtn.backgroundColor = [UIColor whiteColor]; 411 | [sureBtn.titleLabel setFont:[UIFont systemFontOfSize:16]]; 412 | [self.btns addObject:sureBtn]; 413 | } 414 | 415 | } 416 | 417 | 418 | } 419 | 420 | - (void)layoutSubviews 421 | { 422 | _alert__BackGroundView.frame = [UIScreen mainScreen].bounds; 423 | _alert__BackGroundView.rootViewController.view.frame = [UIScreen mainScreen].bounds; 424 | [super layoutSubviews]; 425 | 426 | if (self.contentDatas.count == 0) return; 427 | if (self.btns.count == 2) { 428 | _isDouble = YES; 429 | } 430 | CGSize screenSize = [JLAlertView currentScreenSize]; 431 | CGFloat w = screenSize.width; 432 | CGFloat h = screenSize.height; 433 | 434 | _contentW = MIN(w, h) * 0.65; 435 | 436 | NSMutableDictionary *title_dic = self.contentDatas.firstObject; 437 | NSString *topStr = title_dic[JLAlertViewTopTitle]; 438 | NSString *secondStr = title_dic[JLAlertViewSecondTitle]; 439 | 440 | CGSize topSize = CGSizeZero; 441 | if (![topStr isEqualToString:@""]) { 442 | topSize = [self stringSizeStr:topStr Width:_contentW - 2*_contentInsets.left TopTitle:YES]; 443 | } 444 | 445 | 446 | CGSize secondSize = CGSizeZero; 447 | if (![secondStr isEqualToString:@""]) { 448 | secondSize = [self stringSizeStr:secondStr Width:_contentW - 2*_contentInsets.left TopTitle:NO]; 449 | } 450 | 451 | self.topTitleLabel.text = topStr; 452 | self.secondDescription.text = secondStr; 453 | 454 | self.topTitleLabel.frame = CGRectZero; 455 | if (![topStr isEqualToString:@""]) { 456 | self.topTitleLabel.frame = CGRectMake(_contentInsets.left, _contentInsets.top, _contentW - 2*_contentInsets.left, topSize.height); 457 | } 458 | 459 | self.secondDescription.frame = CGRectZero; 460 | if (![secondStr isEqualToString:@""]) { 461 | if (CGRectEqualToRect(CGRectZero, self.topTitleLabel.frame)) { 462 | self.secondDescription.frame = CGRectMake((_contentW - secondSize.width)/2 , CGRectGetMaxY(self.topTitleLabel.frame) + _contentInsets.top, secondSize.width, secondSize.height); 463 | }else { 464 | self.secondDescription.frame = CGRectMake((_contentW - secondSize.width)/2 , CGRectGetMaxY(self.topTitleLabel.frame) + _contentInsets.top/2, secondSize.width, secondSize.height); 465 | } 466 | 467 | } 468 | 469 | if (CGRectEqualToRect(CGRectZero, self.secondDescription.frame)) { 470 | self.secondDescription.frame = self.topTitleLabel.frame; 471 | } 472 | 473 | _whiteBackView.frame = CGRectMake(0, 0, _contentW, ceil(CGRectGetMaxY(self.secondDescription.frame))+_contentInsets.top); 474 | 475 | // NSLog(@"%f",_whiteBackView.frame.size.height); 476 | __block typeof(self)weakSelf = self; 477 | __block UIView *preView; 478 | [self.btns enumerateObjectsUsingBlock:^(UIView *obj, NSUInteger idx, BOOL * _Nonnull stop) { 479 | 480 | if (weakSelf.isDouble) {//两个按钮的情况 481 | CGFloat x = CGRectGetMaxX(preView.frame); 482 | 483 | obj.frame = CGRectMake(idx*JLALERT_SPLITE_H + x, floorf(CGRectGetMaxY(weakSelf.whiteBackView.frame))+JLALERT_SPLITE_H, [weakSelf cacluteBtnWWithContetn], JLALERT_BTN_H); 484 | // NSLog(@"%lu--%f",idx,obj.frame.origin.y); 485 | }else { 486 | CGFloat y = CGRectGetMaxY(preView.frame); 487 | if (y == 0) { 488 | y = CGRectGetMaxY(weakSelf.whiteBackView.frame); 489 | } 490 | obj.frame = CGRectMake(0, y+JLALERT_SPLITE_H, [weakSelf cacluteBtnWWithContetn], JLALERT_BTN_H); 491 | [obj setNeedsLayout]; 492 | // NSLog(@"%lu--%f",idx,obj.frame.origin.y); 493 | } 494 | preView = obj; 495 | if (idx == weakSelf.btns.count-1) { 496 | weakSelf.sureBtn = (UIButton *)obj; 497 | } 498 | }]; 499 | preView = nil; 500 | UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation]; 501 | if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) { 502 | self.mainView.frame = CGRectMake((MAX(w, h)- _contentW)/2, (MIN(w, h)- CGRectGetMaxY(self.sureBtn.frame))/2, _contentW, CGRectGetMaxY(self.sureBtn.frame)); 503 | }else { 504 | self.mainView.frame = CGRectMake((MIN(w, h)- _contentW)/2, (MAX(w, h)- CGRectGetMaxY(self.sureBtn.frame))/2, _contentW, CGRectGetMaxY(self.sureBtn.frame)); 505 | } 506 | 507 | } 508 | 509 | - (CGFloat)cacluteBtnWWithContetn 510 | { 511 | NSUInteger count = self.btns.count; 512 | if (count != 2 && _isDouble == NO) { 513 | return _contentW; 514 | }else { 515 | return _contentW/2; 516 | } 517 | } 518 | 519 | - (NSMutableArray *)btns 520 | { 521 | if (_btns == nil) { 522 | _btns = [NSMutableArray array]; 523 | } 524 | return _btns; 525 | } 526 | 527 | - (NSMutableArray *)contentDatas 528 | { 529 | if (_contentDatas == nil) { 530 | _contentDatas = [NSMutableArray array]; 531 | } 532 | return _contentDatas; 533 | } 534 | 535 | - (NSInteger)numberOfButtons 536 | { 537 | return self.btns.count; 538 | } 539 | 540 | #pragma mark click 541 | - (void)cancleBtnClick:(UIButton *)sender 542 | { 543 | 544 | if ([self.delegate respondsToSelector:@selector(alertView:clickedButtonAtIndex:)]) { 545 | 546 | NSUInteger index = [self.btns indexOfObject:sender]; 547 | 548 | [self.delegate alertView:self clickedButtonAtIndex:index]; 549 | } 550 | 551 | [self dismissWithClean:YES]; 552 | } 553 | 554 | 555 | // Transition 556 | - (void)transitionInCompletion:(void(^)(void))completion 557 | { 558 | _mainView.alpha = 0; 559 | _mainView.transform = CGAffineTransformMakeScale(1.2, 1.2); 560 | 561 | // _blurView.alpha = 0.9; 562 | // _blurView.transform = CGAffineTransformMakeScale(1.2, 1.2); 563 | 564 | [UIView animateWithDuration:0.3 565 | animations:^{ 566 | _mainView.alpha = 1.; 567 | _mainView.transform = CGAffineTransformMakeScale(1.0,1.0); 568 | 569 | // _blurView.alpha = 1.; 570 | // _blurView.transform = CGAffineTransformMakeScale(1.0,1.0); 571 | } 572 | completion:^(BOOL finished) { 573 | // [_blurView blur]; 574 | if (completion) { 575 | completion(); 576 | } 577 | }]; 578 | } 579 | 580 | - (void)transitionOutCompletion:(void(^)(void))completion 581 | { 582 | [UIView animateWithDuration:0.25 583 | animations:^{ 584 | _mainView.alpha = 0; 585 | _mainView.transform = CGAffineTransformMakeScale(0.9,0.9); 586 | 587 | // _blurView.alpha = 0.9; 588 | // _blurView.transform = CGAffineTransformMakeScale(0.9,0.9); 589 | } 590 | completion:^(BOOL finished) { 591 | if (completion) { 592 | completion(); 593 | } 594 | }]; 595 | } 596 | 597 | - (CGSize)stringSizeStr:(NSString *)str Width:(CGFloat)width TopTitle:(BOOL)isTopTitle 598 | { 599 | NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc]init]; 600 | paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping; 601 | 602 | UIFont *font = [UIFont systemFontOfSize:14.]; 603 | if (isTopTitle) { 604 | font = [UIFont boldSystemFontOfSize:18]; 605 | } 606 | 607 | 608 | NSDictionary *attributes = @{NSFontAttributeName:font, NSParagraphStyleAttributeName:paragraphStyle.copy}; 609 | 610 | 611 | CGSize tempSize = [str boundingRectWithSize:CGSizeMake(width, 120) options: 612 | NSStringDrawingUsesLineFragmentOrigin | 613 | NSStringDrawingUsesFontLeading attributes:attributes context:nil].size; 614 | tempSize = CGSizeMake(ceil(tempSize.width), ceil(tempSize.height)); 615 | return tempSize; 616 | } 617 | 618 | - (void)tearDown:(BOOL)clean 619 | { 620 | if (clean) { 621 | [_alertWindow removeFromSuperview]; 622 | _alertWindow = nil; 623 | 624 | [_alert__BackGroundView removeFromSuperview]; 625 | _alert__BackGroundView = nil; 626 | }else{ 627 | [UIView animateWithDuration:0.3 animations:^{ 628 | // _alertWindow.hidden = YES; 629 | _alertWindow.alpha = 0; 630 | _alert__BackGroundView.alpha = 0; 631 | }]; 632 | } 633 | } 634 | 635 | 636 | #pragma mark - Tool 637 | 638 | 639 | + (JLAlertView *)currentAlertView 640 | { 641 | return __alert__currentAlertView; 642 | } 643 | 644 | + (void)setCurrentAlertView:(JLAlertView *)alertView 645 | { 646 | __alert__currentAlertView = alertView; 647 | } 648 | 649 | + (UIWindow *)getBusinessWindow 650 | { 651 | return __customKeyWindow__oldKeyWindow; 652 | } 653 | 654 | //获取当前屏幕显示的viewcontroller 655 | + (UIViewController *)getCurrentViewController:(UIViewController *)vc 656 | { 657 | 658 | if ([vc isKindOfClass:[UITabBarController class]]) 659 | { 660 | UITabBarController *svc = (UITabBarController *) vc; 661 | if (svc.viewControllers.count > 0) 662 | return [self getCurrentViewController:svc.selectedViewController]; 663 | else 664 | return vc; 665 | 666 | } 667 | else if ([vc isKindOfClass:[UISplitViewController class]]) 668 | { 669 | // Return right hand side 670 | UISplitViewController *svc = (UISplitViewController *) vc; 671 | if (svc.viewControllers.count > 0){ 672 | return [self getCurrentViewController:svc.viewControllers.lastObject]; 673 | } 674 | 675 | else{ 676 | return vc; 677 | } 678 | 679 | } 680 | else if ([vc isKindOfClass:[UINavigationController class]]) 681 | { 682 | // Return top view 683 | UINavigationController *svc = (UINavigationController *) vc; 684 | if (svc.viewControllers.count > 0) 685 | return [self getCurrentViewController:svc.topViewController]; 686 | else 687 | return vc; 688 | } 689 | else if (vc.presentedViewController) 690 | { 691 | // Return visible view 692 | // Return presented view controller 693 | return [self getCurrentViewController:vc.presentedViewController]; 694 | } 695 | else 696 | { 697 | // Unknown view controller type, return last child view controller 698 | return vc; 699 | } 700 | 701 | } 702 | 703 | + (void)getOldKeyWindow 704 | { 705 | if (__customKeyWindow__oldKeyWindow == nil) { 706 | __customKeyWindow__oldKeyWindow = [UIApplication sharedApplication].keyWindow; 707 | NSLog(@"获取到业务window%@",__customKeyWindow__oldKeyWindow); 708 | } 709 | 710 | } 711 | 712 | + (CGSize)currentScreenSize 713 | { 714 | CGRect frame = [UIScreen mainScreen].bounds; 715 | 716 | CGFloat screenWidth = frame.size.width; 717 | CGFloat screenHeight = frame.size.height; 718 | 719 | UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation]; 720 | if (UIInterfaceOrientationIsLandscape(interfaceOrientation) && ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)) { 721 | CGFloat tmp = screenWidth; 722 | screenWidth = screenHeight; 723 | screenHeight = tmp; 724 | } 725 | 726 | return CGSizeMake(screenWidth, screenHeight); 727 | } 728 | 729 | + (NSMutableArray *)allAlerts 730 | { 731 | if (__alert__alertElement == nil) { 732 | __alert__alertElement = [NSMutableArray array]; 733 | } 734 | return __alert__alertElement; 735 | } 736 | 737 | 738 | @end 739 | --------------------------------------------------------------------------------