├── SXAlertViewDemo ├── SXAlertViewDemo │ ├── Assets.xcassets │ │ ├── Contents.json │ │ ├── pic1.imageset │ │ │ ├── pic1.jpg │ │ │ └── Contents.json │ │ ├── pic2.imageset │ │ │ ├── pic2.jpg │ │ │ └── Contents.json │ │ ├── pic3.imageset │ │ │ ├── pic3.jpg │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── ViewController.h │ ├── AppDelegate.h │ ├── main.m │ ├── Info.plist │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── AppDelegate.m │ └── ViewController.m └── SXAlertViewDemo.xcodeproj │ └── project.pbxproj ├── SXAlertView.xcodeproj ├── project.xcworkspace │ └── contents.xcworkspacedata ├── xcshareddata │ └── xcschemes │ │ └── SXAlertView.xcscheme └── project.pbxproj ├── CHANGELOG.md ├── SXAlertView.podspec ├── .gitignore ├── SXAlertView.xcworkspace └── contents.xcworkspacedata ├── LICENSE ├── README.md └── SXAlertView ├── SXAlertView.h └── SXAlertView.m /SXAlertViewDemo/SXAlertViewDemo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /SXAlertViewDemo/SXAlertViewDemo/Assets.xcassets/pic1.imageset/pic1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szlsay/STAlertView/HEAD/SXAlertViewDemo/SXAlertViewDemo/Assets.xcassets/pic1.imageset/pic1.jpg -------------------------------------------------------------------------------- /SXAlertViewDemo/SXAlertViewDemo/Assets.xcassets/pic2.imageset/pic2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szlsay/STAlertView/HEAD/SXAlertViewDemo/SXAlertViewDemo/Assets.xcassets/pic2.imageset/pic2.jpg -------------------------------------------------------------------------------- /SXAlertViewDemo/SXAlertViewDemo/Assets.xcassets/pic3.imageset/pic3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szlsay/STAlertView/HEAD/SXAlertViewDemo/SXAlertViewDemo/Assets.xcassets/pic3.imageset/pic3.jpg -------------------------------------------------------------------------------- /SXAlertView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 版本控制 2 | 3 | ### 2.1 4 | 1. 优化代码 5 | 2. 添加多行输入显示效果 6 | 7 | ### 2.1 8 | 1. 添加图片显示效果 9 | 10 | ### 2.0 11 | 1. 添加文本输入 12 | 2. 对多文本数据处理 13 | 14 | ### 1.1 15 | 1. 添加visual接口,不想使用虚化可以设置为NO 16 | 2. 添加一行代码处理 17 | 18 | ### 1.0 19 | 1. 支持iOS8以上 20 | 2. 添加动画,Zoom和TopToCenter动画 21 | 3. 支持虚化背景 22 | 23 | 24 | -------------------------------------------------------------------------------- /SXAlertViewDemo/SXAlertViewDemo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // SXAlertViewDemo 4 | // 5 | // Created by 沈兆良 on 2017/10/10. 6 | // Copyright © 2017年 沈兆良. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /SXAlertViewDemo/SXAlertViewDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // SXAlertViewDemo 4 | // 5 | // Created by 沈兆良 on 2017/10/10. 6 | // Copyright © 2017年 沈兆良. 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 | -------------------------------------------------------------------------------- /SXAlertViewDemo/SXAlertViewDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SXAlertViewDemo 4 | // 5 | // Created by 沈兆良 on 2017/10/10. 6 | // Copyright © 2017年 沈兆良. 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 | -------------------------------------------------------------------------------- /SXAlertViewDemo/SXAlertViewDemo/Assets.xcassets/pic1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "pic1.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /SXAlertViewDemo/SXAlertViewDemo/Assets.xcassets/pic2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "pic2.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /SXAlertViewDemo/SXAlertViewDemo/Assets.xcassets/pic3.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "pic3.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /SXAlertView.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'SXAlertView' 3 | s.version = '2.2' 4 | s.license = { :type => 'MIT', :file => 'LICENSE'} 5 | s.summary = '600行代码实现的简易UIAlertView,添加动画,虚化效果。接口文件中没有对视图的更多的视图属性开放接口,使用过程中可以根据自己的需求进行自定义接口' 6 | s.homepage = 'https://github.com/STShenZhaoliang' 7 | s.author = { 'STShenZhaoliang' => '409178030@qq.com' } 8 | s.source = { 9 | :git => 'https://github.com/STShenZhaoliang/STAlertView.git', 10 | :tag => s.version.to_s 11 | } 12 | s.ios.deployment_target = '8.0' 13 | s.source_files = "SXAlertView/*.{h,m}" 14 | s.requires_arc = true 15 | end 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | *.xccheckout 14 | *.moved-aside 15 | DerivedData 16 | *.hmap 17 | *.ipa 18 | *.xcuserstate 19 | 20 | # CocoaPods 21 | # 22 | # We recommend against adding the Pods directory to your .gitignore. However 23 | # you should judge for yourself, the pros and cons are mentioned at: 24 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 25 | # 26 | #Pods/ 27 | -------------------------------------------------------------------------------- /SXAlertView.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 12 | 13 | 15 | 16 | 18 | 19 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 沈天 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 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SXAlertView 2 | 3 | ![License MIT](https://img.shields.io/github/license/mashape/apistatus.svg?maxAge=2592000) 4 | ![Pod version](https://img.shields.io/cocoapods/v/SXAlertView.svg?style=flat) 5 | [![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 6 | [![Platform info](https://img.shields.io/cocoapods/p/SXAlertView.svg?style=flat)](http://cocoadocs.org/docsets/SXAlertView) 7 | 8 | 600行代码实现的简易UIAlertView,添加动画,虚化效果。接口文件中没有对视图的更多的视图属性开放接口,使用过程中可以根据自己的需求进行自定义接口。由于Pod中STAlertView已有,所以使用SXAlertView命名代码。 9 | 10 | ## 一、使用 11 | 12 | 1. 使用POD方式 `pod 'SXAlertView', '2.2'` 13 | 2. 使用carthage方式 `github "STShenzhaoliang/STAlertView" "2.2"` 14 | 15 | ## 二、显示效果 16 | ### 2.1 多种动画效果 17 | ![image](https://github.com/STShenZhaoliang/STImage/blob/master/SXAlertView/gif1.gif) 18 | ### 2.2 多个按钮或多文本效果 19 | ![image](https://github.com/STShenZhaoliang/STImage/blob/master/SXAlertView/gif2.gif) 20 | ### 2.3 文本输入显示效果 21 | ![image](https://github.com/STShenZhaoliang/STImage/blob/master/SXAlertView/gif3.gif) 22 | ### 2.4 虚化效果 23 | ![image](https://github.com/STShenZhaoliang/STImage/blob/master/SXAlertView/gif4.gif) 24 | ### 2.5 图片显示效果 25 | ![image](https://github.com/STShenZhaoliang/STImage/blob/master/SXAlertView/gif5.gif) 26 | ### 2.6 多行输入显示效果 27 | ![image](https://github.com/STShenZhaoliang/STImage/blob/master/SXAlertView/gif6.gif) 28 | 29 | ## 三、TODO 30 | 3.1 需要完成多个按钮或多文本效果下的自动布局 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /SXAlertViewDemo/SXAlertViewDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /SXAlertViewDemo/SXAlertViewDemo/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 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /SXAlertViewDemo/SXAlertViewDemo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /SXAlertViewDemo/SXAlertViewDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // SXAlertViewDemo 4 | // 5 | // Created by 沈兆良 on 2017/10/10. 6 | // Copyright © 2017年 沈兆良. 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 | -------------------------------------------------------------------------------- /SXAlertView.xcodeproj/xcshareddata/xcschemes/SXAlertView.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 35 | 36 | 47 | 48 | 54 | 55 | 56 | 57 | 58 | 59 | 65 | 66 | 72 | 73 | 74 | 75 | 77 | 78 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /SXAlertView/SXAlertView.h: -------------------------------------------------------------------------------- 1 | // 2 | // SXAlertView.h 3 | // SXAlertView 4 | // 5 | // Created by 沈兆良 on 2017/10/10. 6 | // Copyright © 2017年 沈兆良. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | typedef NS_ENUM(NSUInteger, SXAlertAnimationOptions) { 14 | SXAlertAnimationOptionNone = 0, 15 | SXAlertAnimationOptionZoom , // First zoom in, and then shrink, in the reduction 16 | SXAlertAnimationOptionTopToCenter, // From top to center 17 | }; 18 | 19 | @protocol SXAlertViewDelegate; 20 | @class UILabel, UIButton, UIWindow; 21 | 22 | @interface SXAlertView : UIView 23 | - (instancetype)initWithTitle:(nullable NSString *)title message:(nullable NSString *)message delegate:(nullable id )delegate cancelButtonTitle:(nullable NSString *)cancelButtonTitle otherButtonTitles:(nullable NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION; 24 | 25 | + (void)showWithTitle:(nullable NSString *)title message:(nullable NSString *)message cancelButtonTitle:(nullable NSString *)cancelButtonTitle otherButtonTitle:(nullable NSString *)otherButtonTitle clickButtonBlock:(nullable void (^)(SXAlertView *alertView, NSInteger buttonIndex))block; 26 | 27 | // Used to enter text information,When the text is monitored in real time, buttonIndex = -1,if click the cancel button,buttonIndex = 0, if click the other button, buttonIndex = 1 28 | - (instancetype)initWithTitle:(nullable NSString *)title placeholder:(nullable NSString *)placeholder cancelButtonTitle:(nullable NSString *)cancelButtonTitle otherButtonTitle:(nullable NSString *)otherButtonTitle clickButtonBlock:(nullable void (^)(SXAlertView *alertView, NSInteger buttonIndex, NSString *text))block; 29 | 30 | + (void)showWithTitle:(nullable NSString *)title placeholder:(nullable NSString *)placeholder cancelButtonTitle:(nullable NSString *)cancelButtonTitle otherButtonTitle:(nullable NSString *)otherButtonTitle clickButtonBlock:(nullable void (^)(SXAlertView *alertView, NSInteger buttonIndex, NSString *text))block; 31 | 32 | - (instancetype)initWithTitle:(nullable NSString *)title image:(nullable UIImage *)image cancelButtonTitle:(nullable NSString *)cancelButtonTitle otherButtonTitle:(nullable NSString *)otherButtonTitle clickButtonBlock:(nullable void (^)(SXAlertView *alertView, NSInteger buttonIndex))block; 33 | 34 | + (void)showWithTitle:(nullable NSString *)title image:(nullable UIImage *)image cancelButtonTitle:(nullable NSString *)cancelButtonTitle otherButtonTitle:(nullable NSString *)otherButtonTitle clickButtonBlock:(nullable void (^)(SXAlertView *alertView, NSInteger buttonIndex))block; 35 | 36 | - (instancetype)initTextViewWithTitle:(nullable NSString *)title placeholder:(nullable NSString *)placeholder cancelButtonTitle:(nullable NSString *)cancelButtonTitle otherButtonTitle:(nullable NSString *)otherButtonTitle clickButtonBlock:(nullable void (^)(SXAlertView *alertView, NSInteger buttonIndex, NSString *text))block; 37 | 38 | + (void)showTextViewWithTitle:(nullable NSString *)title placeholder:(nullable NSString *)placeholder cancelButtonTitle:(nullable NSString *)cancelButtonTitle otherButtonTitle:(nullable NSString *)otherButtonTitle clickButtonBlock:(nullable void (^)(SXAlertView *alertView, NSInteger buttonIndex, NSString *text))block; 39 | 40 | // shows popup alert animated. 41 | - (void)show; 42 | @property(nullable,nonatomic,weak)id delegate; 43 | @property(nonatomic)SXAlertAnimationOptions animationOption; 44 | // default is NSTextAlignmentCenter 45 | @property(nonatomic)NSTextAlignment textAlignment; 46 | // background visual 47 | @property(nonatomic, assign)BOOL visual; 48 | // Only Used to enter text information 49 | @property(nonatomic, strong)UITextField *textField; 50 | // default is 88 51 | @property(nonatomic, assign)CGFloat widthImage; 52 | @end 53 | 54 | @protocol SXAlertViewDelegate 55 | @optional 56 | 57 | // Called when a button is clicked. The view will be automatically dismissed after this call returns 58 | - (void)alertView:(SXAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex; 59 | 60 | @end 61 | 62 | NS_ASSUME_NONNULL_END 63 | 64 | 65 | -------------------------------------------------------------------------------- /SXAlertViewDemo/SXAlertViewDemo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // SXAlertViewDemo 4 | // 5 | // Created by 沈兆良 on 2017/10/10. 6 | // Copyright © 2017年 沈兆良. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "SXAlertView.h" 11 | 12 | @interface ViewController () 13 | @property (weak, nonatomic) IBOutlet UITextView *textResult; 14 | 15 | @end 16 | 17 | @implementation ViewController 18 | 19 | - (IBAction)clickNone:(UIButton *)sender { 20 | SXAlertView *alertView = [[SXAlertView alloc]initWithTitle:@"用户调研" message:@"当客户拜访及业务轮岗形成良好的机制,同时产品发展到一定规模后,用户调研问卷就成为更加高效的获取用户声音的重要手段了。不同于C端产品,B端产品的调研问卷内容应该更加详细,更加坦诚的询问产品功能与用户的使用体验。定期的进行客户问卷调研,能够建立良好、有效的客户沟通机制,加深产品与客户之间的相互理解。" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil]; 21 | alertView.animationOption = SXAlertAnimationOptionNone; 22 | [alertView show]; 23 | } 24 | 25 | - (IBAction)clickZoom:(UIButton *)sender { 26 | SXAlertView *alertView = [[SXAlertView alloc]initWithTitle:@"用户调研" message:@"当客户拜访及业务轮岗形成良好的机制,同时产品发展到一定规模后,用户调研问卷就成为更加高效的获取用户声音的重要手段了。不同于C端产品,B端产品的调研问卷内容应该更加详细,更加坦诚的询问产品功能与用户的使用体验。定期的进行客户问卷调研,能够建立良好、有效的客户沟通机制,加深产品与客户之间的相互理解。" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil]; 27 | alertView.animationOption = SXAlertAnimationOptionZoom; 28 | [alertView show]; 29 | } 30 | 31 | - (IBAction)clickTop:(UIButton *)sender { 32 | SXAlertView *alertView = [[SXAlertView alloc]initWithTitle:@"用户调研" message:@"当客户拜访及业务轮岗形成良好的机制,同时产品发展到一定规模后,用户调研问卷就成为更加高效的获取用户声音的重要手段了。不同于C端产品,B端产品的调研问卷内容应该更加详细,更加坦诚的询问产品功能与用户的使用体验。定期的进行客户问卷调研,能够建立良好、有效的客户沟通机制,加深产品与客户之间的相互理解。" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil]; 33 | alertView.animationOption = SXAlertAnimationOptionTopToCenter; 34 | [alertView show]; 35 | } 36 | 37 | - (IBAction)clickButton:(UIButton *)sender { 38 | SXAlertView *alertView = [[SXAlertView alloc]initWithTitle:@"用户调研" message:@"当客户拜访及业务轮岗形成良好的机制,同时产品发展到一定规模后,用户调研问卷就成为更加高效的获取用户声音的重要手段了。不同于C端产品,B端产品的调研问卷内容应该更加详细,更加坦诚的询问产品功能与用户的使用体验。定期的进行客户问卷调研,能够建立良好、有效的客户沟通机制,加深产品与客户之间的相互理解。" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"button1", @"button2", @"button3", @"button4", @"button5", nil]; 39 | alertView.animationOption = SXAlertAnimationOptionTopToCenter; 40 | [alertView show]; 41 | } 42 | - (IBAction)clickText:(UIButton *)sender { 43 | [SXAlertView showWithTitle:@"用户调研" message:@"当客户拜访及业务轮岗形成良好的机制,同时产品发展到一定规模后,用户调研问卷就成为更加高效的获取用户声音的重要手段了。不同于C端产品,B端产品的调研问卷内容应该更加详细,更加坦诚的询问产品功能与用户的使用体验。定期的进行客户问卷调研,能够建立良好、有效的客户沟通机制,加深产品与客户之间的相互理解。\n当客户拜访及业务轮岗形成良好的机制,同时产品发展到一定规模后,用户调研问卷就成为更加高效的获取用户声音的重要手段了。不同于C端产品,B端产品的调研问卷内容应该更加详细,更加坦诚的询问产品功能与用户的使用体验。定期的进行客户问卷调研,能够建立良好、有效的客户沟通机制,加深产品与客户之间的相互理解。\n当客户拜访及业务轮岗形成良好的机制,同时产品发展到一定规模后,用户调研问卷就成为更加高效的获取用户声音的重要手段了。不同于C端产品,B端产品的调研问卷内容应该更加详细,更加坦诚的询问产品功能与用户的使用体验。定期的进行客户问卷调研,能够建立良好、有效的客户沟通机制,加深产品与客户之间的相互理解。" cancelButtonTitle:@"取消" otherButtonTitle:@"确定" clickButtonBlock:^(SXAlertView * _Nonnull alertView, NSInteger buttonIndex) { 44 | NSLog(@"%s %zd", __FUNCTION__, buttonIndex); 45 | }]; 46 | 47 | } 48 | - (IBAction)clickTextField:(UIButton *)sender { 49 | [SXAlertView showWithTitle:@"用户调研" placeholder:@"请输入内容" cancelButtonTitle:@"取消" otherButtonTitle:@"确定" clickButtonBlock:^(SXAlertView * _Nonnull alertView, NSInteger buttonIndex, NSString * _Nonnull text) { 50 | NSLog(@"%s %zd %@", __FUNCTION__, buttonIndex, text); 51 | self.textResult.text = text; 52 | }]; 53 | } 54 | 55 | - (IBAction)clickTextView:(UIButton *)sender { 56 | [SXAlertView showTextViewWithTitle:@"用户调研" placeholder:@"请输入内容" cancelButtonTitle:@"取消" otherButtonTitle:@"确定" clickButtonBlock:^(SXAlertView * _Nonnull alertView, NSInteger buttonIndex, NSString * _Nonnull text) { 57 | NSLog(@"%s %zd %@", __FUNCTION__, buttonIndex, text); 58 | self.textResult.text = text; 59 | }]; 60 | } 61 | - (IBAction)clickVisual:(UIButton *)sender { 62 | SXAlertView *alertView = [[SXAlertView alloc]initWithTitle:@"用户调研" message:@"当客户拜访及业务轮岗形成良好的机制,同时产品发展到一定规模后,用户调研问卷就成为更加高效的获取用户声音的重要手段了。不同于C端产品,B端产品的调研问卷内容应该更加详细,更加坦诚的询问产品功能与用户的使用体验。定期的进行客户问卷调研,能够建立良好、有效的客户沟通机制,加深产品与客户之间的相互理解。" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil]; 63 | alertView.animationOption = SXAlertAnimationOptionTopToCenter; 64 | alertView.visual = YES; 65 | [alertView show]; 66 | } 67 | 68 | - (IBAction)clickWLessH:(UIButton *)sender { 69 | [SXAlertView showWithTitle:@"发送图片给:哈哈哈" image:[UIImage imageNamed:@"pic1"] cancelButtonTitle:@"取消" otherButtonTitle:@"确定" clickButtonBlock:^(SXAlertView * _Nonnull alertView, NSInteger buttonIndex) { 70 | NSLog(@"%s %zd", __FUNCTION__, buttonIndex); 71 | }]; 72 | 73 | } 74 | - (IBAction)clickWEqualH:(UIButton *)sender { 75 | [SXAlertView showWithTitle:@"发送图片给:哈哈哈" image:[UIImage imageNamed:@"pic3"] cancelButtonTitle:@"取消" otherButtonTitle:@"确定" clickButtonBlock:^(SXAlertView * _Nonnull alertView, NSInteger buttonIndex) { 76 | NSLog(@"%s %zd", __FUNCTION__, buttonIndex); 77 | }]; 78 | 79 | } 80 | - (IBAction)clickWGreaterH:(UIButton *)sender { 81 | [SXAlertView showWithTitle:@"发送图片给:哈哈哈" image:[UIImage imageNamed:@"pic2"] cancelButtonTitle:@"取消" otherButtonTitle:@"确定" clickButtonBlock:^(SXAlertView * _Nonnull alertView, NSInteger buttonIndex) { 82 | NSLog(@"%s %zd", __FUNCTION__, buttonIndex); 83 | }]; 84 | 85 | } 86 | 87 | 88 | - (void)alertView:(SXAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{ 89 | NSLog(@"%s %zd", __FUNCTION__, buttonIndex); 90 | } 91 | @end 92 | -------------------------------------------------------------------------------- /SXAlertView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 67F4B5001F8CE5ED00267023 /* SXAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = 67F4B4FF1F8CE5ED00267023 /* SXAlertView.m */; }; 11 | 67F4B5011F8CE5ED00267023 /* SXAlertView.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 67F4B4FE1F8CE5ED00267023 /* SXAlertView.h */; }; 12 | /* End PBXBuildFile section */ 13 | 14 | /* Begin PBXCopyFilesBuildPhase section */ 15 | 67F4B4F91F8CE5ED00267023 /* CopyFiles */ = { 16 | isa = PBXCopyFilesBuildPhase; 17 | buildActionMask = 2147483647; 18 | dstPath = "include/$(PRODUCT_NAME)"; 19 | dstSubfolderSpec = 16; 20 | files = ( 21 | 67F4B5011F8CE5ED00267023 /* SXAlertView.h in CopyFiles */, 22 | ); 23 | runOnlyForDeploymentPostprocessing = 0; 24 | }; 25 | /* End PBXCopyFilesBuildPhase section */ 26 | 27 | /* Begin PBXFileReference section */ 28 | 67F4B4FB1F8CE5ED00267023 /* libSXAlertView.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSXAlertView.a; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | 67F4B4FE1F8CE5ED00267023 /* SXAlertView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SXAlertView.h; sourceTree = ""; }; 30 | 67F4B4FF1F8CE5ED00267023 /* SXAlertView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SXAlertView.m; sourceTree = ""; }; 31 | /* End PBXFileReference section */ 32 | 33 | /* Begin PBXFrameworksBuildPhase section */ 34 | 67F4B4F81F8CE5ED00267023 /* Frameworks */ = { 35 | isa = PBXFrameworksBuildPhase; 36 | buildActionMask = 2147483647; 37 | files = ( 38 | ); 39 | runOnlyForDeploymentPostprocessing = 0; 40 | }; 41 | /* End PBXFrameworksBuildPhase section */ 42 | 43 | /* Begin PBXGroup section */ 44 | 67F4B4F21F8CE5ED00267023 = { 45 | isa = PBXGroup; 46 | children = ( 47 | 67F4B4FD1F8CE5ED00267023 /* SXAlertView */, 48 | 67F4B4FC1F8CE5ED00267023 /* Products */, 49 | ); 50 | sourceTree = ""; 51 | }; 52 | 67F4B4FC1F8CE5ED00267023 /* Products */ = { 53 | isa = PBXGroup; 54 | children = ( 55 | 67F4B4FB1F8CE5ED00267023 /* libSXAlertView.a */, 56 | ); 57 | name = Products; 58 | sourceTree = ""; 59 | }; 60 | 67F4B4FD1F8CE5ED00267023 /* SXAlertView */ = { 61 | isa = PBXGroup; 62 | children = ( 63 | 67F4B4FE1F8CE5ED00267023 /* SXAlertView.h */, 64 | 67F4B4FF1F8CE5ED00267023 /* SXAlertView.m */, 65 | ); 66 | path = SXAlertView; 67 | sourceTree = ""; 68 | }; 69 | /* End PBXGroup section */ 70 | 71 | /* Begin PBXNativeTarget section */ 72 | 67F4B4FA1F8CE5ED00267023 /* SXAlertView */ = { 73 | isa = PBXNativeTarget; 74 | buildConfigurationList = 67F4B5041F8CE5ED00267023 /* Build configuration list for PBXNativeTarget "SXAlertView" */; 75 | buildPhases = ( 76 | 67F4B4F71F8CE5ED00267023 /* Sources */, 77 | 67F4B4F81F8CE5ED00267023 /* Frameworks */, 78 | 67F4B4F91F8CE5ED00267023 /* CopyFiles */, 79 | ); 80 | buildRules = ( 81 | ); 82 | dependencies = ( 83 | ); 84 | name = SXAlertView; 85 | productName = SXAlertView; 86 | productReference = 67F4B4FB1F8CE5ED00267023 /* libSXAlertView.a */; 87 | productType = "com.apple.product-type.library.static"; 88 | }; 89 | /* End PBXNativeTarget section */ 90 | 91 | /* Begin PBXProject section */ 92 | 67F4B4F31F8CE5ED00267023 /* Project object */ = { 93 | isa = PBXProject; 94 | attributes = { 95 | LastUpgradeCheck = 0900; 96 | ORGANIZATIONNAME = "沈兆良"; 97 | TargetAttributes = { 98 | 67F4B4FA1F8CE5ED00267023 = { 99 | CreatedOnToolsVersion = 9.0; 100 | ProvisioningStyle = Automatic; 101 | }; 102 | }; 103 | }; 104 | buildConfigurationList = 67F4B4F61F8CE5ED00267023 /* Build configuration list for PBXProject "SXAlertView" */; 105 | compatibilityVersion = "Xcode 8.0"; 106 | developmentRegion = en; 107 | hasScannedForEncodings = 0; 108 | knownRegions = ( 109 | en, 110 | ); 111 | mainGroup = 67F4B4F21F8CE5ED00267023; 112 | productRefGroup = 67F4B4FC1F8CE5ED00267023 /* Products */; 113 | projectDirPath = ""; 114 | projectRoot = ""; 115 | targets = ( 116 | 67F4B4FA1F8CE5ED00267023 /* SXAlertView */, 117 | ); 118 | }; 119 | /* End PBXProject section */ 120 | 121 | /* Begin PBXSourcesBuildPhase section */ 122 | 67F4B4F71F8CE5ED00267023 /* Sources */ = { 123 | isa = PBXSourcesBuildPhase; 124 | buildActionMask = 2147483647; 125 | files = ( 126 | 67F4B5001F8CE5ED00267023 /* SXAlertView.m in Sources */, 127 | ); 128 | runOnlyForDeploymentPostprocessing = 0; 129 | }; 130 | /* End PBXSourcesBuildPhase section */ 131 | 132 | /* Begin XCBuildConfiguration section */ 133 | 67F4B5021F8CE5ED00267023 /* Debug */ = { 134 | isa = XCBuildConfiguration; 135 | buildSettings = { 136 | ALWAYS_SEARCH_USER_PATHS = NO; 137 | CLANG_ANALYZER_NONNULL = YES; 138 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 139 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 140 | CLANG_CXX_LIBRARY = "libc++"; 141 | CLANG_ENABLE_MODULES = YES; 142 | CLANG_ENABLE_OBJC_ARC = YES; 143 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 144 | CLANG_WARN_BOOL_CONVERSION = YES; 145 | CLANG_WARN_COMMA = YES; 146 | CLANG_WARN_CONSTANT_CONVERSION = YES; 147 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 148 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 149 | CLANG_WARN_EMPTY_BODY = YES; 150 | CLANG_WARN_ENUM_CONVERSION = YES; 151 | CLANG_WARN_INFINITE_RECURSION = YES; 152 | CLANG_WARN_INT_CONVERSION = YES; 153 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 154 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 155 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 156 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 157 | CLANG_WARN_STRICT_PROTOTYPES = YES; 158 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 159 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 160 | CLANG_WARN_UNREACHABLE_CODE = YES; 161 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 162 | CODE_SIGN_IDENTITY = "iPhone Developer"; 163 | COPY_PHASE_STRIP = NO; 164 | DEBUG_INFORMATION_FORMAT = dwarf; 165 | ENABLE_STRICT_OBJC_MSGSEND = YES; 166 | ENABLE_TESTABILITY = YES; 167 | GCC_C_LANGUAGE_STANDARD = gnu11; 168 | GCC_DYNAMIC_NO_PIC = NO; 169 | GCC_NO_COMMON_BLOCKS = YES; 170 | GCC_OPTIMIZATION_LEVEL = 0; 171 | GCC_PREPROCESSOR_DEFINITIONS = ( 172 | "DEBUG=1", 173 | "$(inherited)", 174 | ); 175 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 176 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 177 | GCC_WARN_UNDECLARED_SELECTOR = YES; 178 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 179 | GCC_WARN_UNUSED_FUNCTION = YES; 180 | GCC_WARN_UNUSED_VARIABLE = YES; 181 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 182 | MTL_ENABLE_DEBUG_INFO = YES; 183 | ONLY_ACTIVE_ARCH = YES; 184 | SDKROOT = iphoneos; 185 | }; 186 | name = Debug; 187 | }; 188 | 67F4B5031F8CE5ED00267023 /* Release */ = { 189 | isa = XCBuildConfiguration; 190 | buildSettings = { 191 | ALWAYS_SEARCH_USER_PATHS = NO; 192 | CLANG_ANALYZER_NONNULL = YES; 193 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 194 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 195 | CLANG_CXX_LIBRARY = "libc++"; 196 | CLANG_ENABLE_MODULES = YES; 197 | CLANG_ENABLE_OBJC_ARC = YES; 198 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 199 | CLANG_WARN_BOOL_CONVERSION = YES; 200 | CLANG_WARN_COMMA = YES; 201 | CLANG_WARN_CONSTANT_CONVERSION = YES; 202 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 203 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 204 | CLANG_WARN_EMPTY_BODY = YES; 205 | CLANG_WARN_ENUM_CONVERSION = YES; 206 | CLANG_WARN_INFINITE_RECURSION = YES; 207 | CLANG_WARN_INT_CONVERSION = YES; 208 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 209 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 210 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 211 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 212 | CLANG_WARN_STRICT_PROTOTYPES = YES; 213 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 214 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 215 | CLANG_WARN_UNREACHABLE_CODE = YES; 216 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 217 | CODE_SIGN_IDENTITY = "iPhone Developer"; 218 | COPY_PHASE_STRIP = NO; 219 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 220 | ENABLE_NS_ASSERTIONS = NO; 221 | ENABLE_STRICT_OBJC_MSGSEND = YES; 222 | GCC_C_LANGUAGE_STANDARD = gnu11; 223 | GCC_NO_COMMON_BLOCKS = YES; 224 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 225 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 226 | GCC_WARN_UNDECLARED_SELECTOR = YES; 227 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 228 | GCC_WARN_UNUSED_FUNCTION = YES; 229 | GCC_WARN_UNUSED_VARIABLE = YES; 230 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 231 | MTL_ENABLE_DEBUG_INFO = NO; 232 | SDKROOT = iphoneos; 233 | VALIDATE_PRODUCT = YES; 234 | }; 235 | name = Release; 236 | }; 237 | 67F4B5051F8CE5ED00267023 /* Debug */ = { 238 | isa = XCBuildConfiguration; 239 | buildSettings = { 240 | CODE_SIGN_STYLE = Automatic; 241 | DEVELOPMENT_TEAM = Z25J3BA353; 242 | OTHER_LDFLAGS = "-ObjC"; 243 | PRODUCT_NAME = "$(TARGET_NAME)"; 244 | SKIP_INSTALL = YES; 245 | TARGETED_DEVICE_FAMILY = "1,2"; 246 | }; 247 | name = Debug; 248 | }; 249 | 67F4B5061F8CE5ED00267023 /* Release */ = { 250 | isa = XCBuildConfiguration; 251 | buildSettings = { 252 | CODE_SIGN_STYLE = Automatic; 253 | DEVELOPMENT_TEAM = Z25J3BA353; 254 | OTHER_LDFLAGS = "-ObjC"; 255 | PRODUCT_NAME = "$(TARGET_NAME)"; 256 | SKIP_INSTALL = YES; 257 | TARGETED_DEVICE_FAMILY = "1,2"; 258 | }; 259 | name = Release; 260 | }; 261 | /* End XCBuildConfiguration section */ 262 | 263 | /* Begin XCConfigurationList section */ 264 | 67F4B4F61F8CE5ED00267023 /* Build configuration list for PBXProject "SXAlertView" */ = { 265 | isa = XCConfigurationList; 266 | buildConfigurations = ( 267 | 67F4B5021F8CE5ED00267023 /* Debug */, 268 | 67F4B5031F8CE5ED00267023 /* Release */, 269 | ); 270 | defaultConfigurationIsVisible = 0; 271 | defaultConfigurationName = Release; 272 | }; 273 | 67F4B5041F8CE5ED00267023 /* Build configuration list for PBXNativeTarget "SXAlertView" */ = { 274 | isa = XCConfigurationList; 275 | buildConfigurations = ( 276 | 67F4B5051F8CE5ED00267023 /* Debug */, 277 | 67F4B5061F8CE5ED00267023 /* Release */, 278 | ); 279 | defaultConfigurationIsVisible = 0; 280 | defaultConfigurationName = Release; 281 | }; 282 | /* End XCConfigurationList section */ 283 | }; 284 | rootObject = 67F4B4F31F8CE5ED00267023 /* Project object */; 285 | } 286 | -------------------------------------------------------------------------------- /SXAlertViewDemo/SXAlertViewDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 67F4B5151F8CE6AB00267023 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 67F4B5141F8CE6AB00267023 /* AppDelegate.m */; }; 11 | 67F4B5181F8CE6AB00267023 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 67F4B5171F8CE6AB00267023 /* ViewController.m */; }; 12 | 67F4B51B1F8CE6AB00267023 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 67F4B5191F8CE6AB00267023 /* Main.storyboard */; }; 13 | 67F4B51D1F8CE6AB00267023 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 67F4B51C1F8CE6AB00267023 /* Assets.xcassets */; }; 14 | 67F4B5201F8CE6AB00267023 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 67F4B51E1F8CE6AB00267023 /* LaunchScreen.storyboard */; }; 15 | 67F4B5231F8CE6AB00267023 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 67F4B5221F8CE6AB00267023 /* main.m */; }; 16 | 67F4B52C1F8CE74500267023 /* SXAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = 67F4B52B1F8CE74500267023 /* SXAlertView.m */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXFileReference section */ 20 | 67F4B5101F8CE6AB00267023 /* SXAlertViewDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SXAlertViewDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 21 | 67F4B5131F8CE6AB00267023 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 22 | 67F4B5141F8CE6AB00267023 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 23 | 67F4B5161F8CE6AB00267023 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 24 | 67F4B5171F8CE6AB00267023 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 25 | 67F4B51A1F8CE6AB00267023 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 26 | 67F4B51C1F8CE6AB00267023 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 27 | 67F4B51F1F8CE6AB00267023 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 28 | 67F4B5211F8CE6AB00267023 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 29 | 67F4B5221F8CE6AB00267023 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 30 | 67F4B52A1F8CE74500267023 /* SXAlertView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SXAlertView.h; sourceTree = ""; }; 31 | 67F4B52B1F8CE74500267023 /* SXAlertView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SXAlertView.m; sourceTree = ""; }; 32 | /* End PBXFileReference section */ 33 | 34 | /* Begin PBXFrameworksBuildPhase section */ 35 | 67F4B50D1F8CE6AB00267023 /* Frameworks */ = { 36 | isa = PBXFrameworksBuildPhase; 37 | buildActionMask = 2147483647; 38 | files = ( 39 | ); 40 | runOnlyForDeploymentPostprocessing = 0; 41 | }; 42 | /* End PBXFrameworksBuildPhase section */ 43 | 44 | /* Begin PBXGroup section */ 45 | 67F4B5071F8CE6AB00267023 = { 46 | isa = PBXGroup; 47 | children = ( 48 | 67F4B5121F8CE6AB00267023 /* SXAlertViewDemo */, 49 | 67F4B5111F8CE6AB00267023 /* Products */, 50 | ); 51 | sourceTree = ""; 52 | }; 53 | 67F4B5111F8CE6AB00267023 /* Products */ = { 54 | isa = PBXGroup; 55 | children = ( 56 | 67F4B5101F8CE6AB00267023 /* SXAlertViewDemo.app */, 57 | ); 58 | name = Products; 59 | sourceTree = ""; 60 | }; 61 | 67F4B5121F8CE6AB00267023 /* SXAlertViewDemo */ = { 62 | isa = PBXGroup; 63 | children = ( 64 | 67F4B5291F8CE74500267023 /* SXAlertView */, 65 | 67F4B5131F8CE6AB00267023 /* AppDelegate.h */, 66 | 67F4B5141F8CE6AB00267023 /* AppDelegate.m */, 67 | 67F4B5161F8CE6AB00267023 /* ViewController.h */, 68 | 67F4B5171F8CE6AB00267023 /* ViewController.m */, 69 | 67F4B5191F8CE6AB00267023 /* Main.storyboard */, 70 | 67F4B51C1F8CE6AB00267023 /* Assets.xcassets */, 71 | 67F4B51E1F8CE6AB00267023 /* LaunchScreen.storyboard */, 72 | 67F4B5211F8CE6AB00267023 /* Info.plist */, 73 | 67F4B5221F8CE6AB00267023 /* main.m */, 74 | ); 75 | path = SXAlertViewDemo; 76 | sourceTree = ""; 77 | }; 78 | 67F4B5291F8CE74500267023 /* SXAlertView */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | 67F4B52A1F8CE74500267023 /* SXAlertView.h */, 82 | 67F4B52B1F8CE74500267023 /* SXAlertView.m */, 83 | ); 84 | name = SXAlertView; 85 | path = ../../SXAlertView; 86 | sourceTree = ""; 87 | }; 88 | /* End PBXGroup section */ 89 | 90 | /* Begin PBXNativeTarget section */ 91 | 67F4B50F1F8CE6AB00267023 /* SXAlertViewDemo */ = { 92 | isa = PBXNativeTarget; 93 | buildConfigurationList = 67F4B5261F8CE6AB00267023 /* Build configuration list for PBXNativeTarget "SXAlertViewDemo" */; 94 | buildPhases = ( 95 | 67F4B50C1F8CE6AB00267023 /* Sources */, 96 | 67F4B50D1F8CE6AB00267023 /* Frameworks */, 97 | 67F4B50E1F8CE6AB00267023 /* Resources */, 98 | ); 99 | buildRules = ( 100 | ); 101 | dependencies = ( 102 | ); 103 | name = SXAlertViewDemo; 104 | productName = SXAlertViewDemo; 105 | productReference = 67F4B5101F8CE6AB00267023 /* SXAlertViewDemo.app */; 106 | productType = "com.apple.product-type.application"; 107 | }; 108 | /* End PBXNativeTarget section */ 109 | 110 | /* Begin PBXProject section */ 111 | 67F4B5081F8CE6AB00267023 /* Project object */ = { 112 | isa = PBXProject; 113 | attributes = { 114 | LastUpgradeCheck = 0900; 115 | ORGANIZATIONNAME = "沈兆良"; 116 | TargetAttributes = { 117 | 67F4B50F1F8CE6AB00267023 = { 118 | CreatedOnToolsVersion = 9.0; 119 | ProvisioningStyle = Automatic; 120 | }; 121 | }; 122 | }; 123 | buildConfigurationList = 67F4B50B1F8CE6AB00267023 /* Build configuration list for PBXProject "SXAlertViewDemo" */; 124 | compatibilityVersion = "Xcode 8.0"; 125 | developmentRegion = en; 126 | hasScannedForEncodings = 0; 127 | knownRegions = ( 128 | en, 129 | Base, 130 | ); 131 | mainGroup = 67F4B5071F8CE6AB00267023; 132 | productRefGroup = 67F4B5111F8CE6AB00267023 /* Products */; 133 | projectDirPath = ""; 134 | projectRoot = ""; 135 | targets = ( 136 | 67F4B50F1F8CE6AB00267023 /* SXAlertViewDemo */, 137 | ); 138 | }; 139 | /* End PBXProject section */ 140 | 141 | /* Begin PBXResourcesBuildPhase section */ 142 | 67F4B50E1F8CE6AB00267023 /* Resources */ = { 143 | isa = PBXResourcesBuildPhase; 144 | buildActionMask = 2147483647; 145 | files = ( 146 | 67F4B5201F8CE6AB00267023 /* LaunchScreen.storyboard in Resources */, 147 | 67F4B51D1F8CE6AB00267023 /* Assets.xcassets in Resources */, 148 | 67F4B51B1F8CE6AB00267023 /* Main.storyboard in Resources */, 149 | ); 150 | runOnlyForDeploymentPostprocessing = 0; 151 | }; 152 | /* End PBXResourcesBuildPhase section */ 153 | 154 | /* Begin PBXSourcesBuildPhase section */ 155 | 67F4B50C1F8CE6AB00267023 /* Sources */ = { 156 | isa = PBXSourcesBuildPhase; 157 | buildActionMask = 2147483647; 158 | files = ( 159 | 67F4B5181F8CE6AB00267023 /* ViewController.m in Sources */, 160 | 67F4B5231F8CE6AB00267023 /* main.m in Sources */, 161 | 67F4B52C1F8CE74500267023 /* SXAlertView.m in Sources */, 162 | 67F4B5151F8CE6AB00267023 /* AppDelegate.m in Sources */, 163 | ); 164 | runOnlyForDeploymentPostprocessing = 0; 165 | }; 166 | /* End PBXSourcesBuildPhase section */ 167 | 168 | /* Begin PBXVariantGroup section */ 169 | 67F4B5191F8CE6AB00267023 /* Main.storyboard */ = { 170 | isa = PBXVariantGroup; 171 | children = ( 172 | 67F4B51A1F8CE6AB00267023 /* Base */, 173 | ); 174 | name = Main.storyboard; 175 | sourceTree = ""; 176 | }; 177 | 67F4B51E1F8CE6AB00267023 /* LaunchScreen.storyboard */ = { 178 | isa = PBXVariantGroup; 179 | children = ( 180 | 67F4B51F1F8CE6AB00267023 /* Base */, 181 | ); 182 | name = LaunchScreen.storyboard; 183 | sourceTree = ""; 184 | }; 185 | /* End PBXVariantGroup section */ 186 | 187 | /* Begin XCBuildConfiguration section */ 188 | 67F4B5241F8CE6AB00267023 /* Debug */ = { 189 | isa = XCBuildConfiguration; 190 | buildSettings = { 191 | ALWAYS_SEARCH_USER_PATHS = NO; 192 | CLANG_ANALYZER_NONNULL = YES; 193 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 194 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 195 | CLANG_CXX_LIBRARY = "libc++"; 196 | CLANG_ENABLE_MODULES = YES; 197 | CLANG_ENABLE_OBJC_ARC = YES; 198 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 199 | CLANG_WARN_BOOL_CONVERSION = YES; 200 | CLANG_WARN_COMMA = YES; 201 | CLANG_WARN_CONSTANT_CONVERSION = YES; 202 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 203 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 204 | CLANG_WARN_EMPTY_BODY = YES; 205 | CLANG_WARN_ENUM_CONVERSION = YES; 206 | CLANG_WARN_INFINITE_RECURSION = YES; 207 | CLANG_WARN_INT_CONVERSION = YES; 208 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 209 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 210 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 211 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 212 | CLANG_WARN_STRICT_PROTOTYPES = YES; 213 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 214 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 215 | CLANG_WARN_UNREACHABLE_CODE = YES; 216 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 217 | CODE_SIGN_IDENTITY = "iPhone Developer"; 218 | COPY_PHASE_STRIP = NO; 219 | DEBUG_INFORMATION_FORMAT = dwarf; 220 | ENABLE_STRICT_OBJC_MSGSEND = YES; 221 | ENABLE_TESTABILITY = YES; 222 | GCC_C_LANGUAGE_STANDARD = gnu11; 223 | GCC_DYNAMIC_NO_PIC = NO; 224 | GCC_NO_COMMON_BLOCKS = YES; 225 | GCC_OPTIMIZATION_LEVEL = 0; 226 | GCC_PREPROCESSOR_DEFINITIONS = ( 227 | "DEBUG=1", 228 | "$(inherited)", 229 | ); 230 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 231 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 232 | GCC_WARN_UNDECLARED_SELECTOR = YES; 233 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 234 | GCC_WARN_UNUSED_FUNCTION = YES; 235 | GCC_WARN_UNUSED_VARIABLE = YES; 236 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 237 | MTL_ENABLE_DEBUG_INFO = YES; 238 | ONLY_ACTIVE_ARCH = YES; 239 | SDKROOT = iphoneos; 240 | }; 241 | name = Debug; 242 | }; 243 | 67F4B5251F8CE6AB00267023 /* Release */ = { 244 | isa = XCBuildConfiguration; 245 | buildSettings = { 246 | ALWAYS_SEARCH_USER_PATHS = NO; 247 | CLANG_ANALYZER_NONNULL = YES; 248 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 249 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 250 | CLANG_CXX_LIBRARY = "libc++"; 251 | CLANG_ENABLE_MODULES = YES; 252 | CLANG_ENABLE_OBJC_ARC = YES; 253 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 254 | CLANG_WARN_BOOL_CONVERSION = YES; 255 | CLANG_WARN_COMMA = YES; 256 | CLANG_WARN_CONSTANT_CONVERSION = YES; 257 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 258 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 259 | CLANG_WARN_EMPTY_BODY = YES; 260 | CLANG_WARN_ENUM_CONVERSION = YES; 261 | CLANG_WARN_INFINITE_RECURSION = YES; 262 | CLANG_WARN_INT_CONVERSION = YES; 263 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 264 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 265 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 266 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 267 | CLANG_WARN_STRICT_PROTOTYPES = YES; 268 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 269 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 270 | CLANG_WARN_UNREACHABLE_CODE = YES; 271 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 272 | CODE_SIGN_IDENTITY = "iPhone Developer"; 273 | COPY_PHASE_STRIP = NO; 274 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 275 | ENABLE_NS_ASSERTIONS = NO; 276 | ENABLE_STRICT_OBJC_MSGSEND = YES; 277 | GCC_C_LANGUAGE_STANDARD = gnu11; 278 | GCC_NO_COMMON_BLOCKS = YES; 279 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 280 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 281 | GCC_WARN_UNDECLARED_SELECTOR = YES; 282 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 283 | GCC_WARN_UNUSED_FUNCTION = YES; 284 | GCC_WARN_UNUSED_VARIABLE = YES; 285 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 286 | MTL_ENABLE_DEBUG_INFO = NO; 287 | SDKROOT = iphoneos; 288 | VALIDATE_PRODUCT = YES; 289 | }; 290 | name = Release; 291 | }; 292 | 67F4B5271F8CE6AB00267023 /* Debug */ = { 293 | isa = XCBuildConfiguration; 294 | buildSettings = { 295 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 296 | CODE_SIGN_STYLE = Automatic; 297 | DEVELOPMENT_TEAM = Z25J3BA353; 298 | INFOPLIST_FILE = SXAlertViewDemo/Info.plist; 299 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 300 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 301 | PRODUCT_BUNDLE_IDENTIFIER = com.st.cn.st3; 302 | PRODUCT_NAME = "$(TARGET_NAME)"; 303 | TARGETED_DEVICE_FAMILY = "1,2"; 304 | }; 305 | name = Debug; 306 | }; 307 | 67F4B5281F8CE6AB00267023 /* Release */ = { 308 | isa = XCBuildConfiguration; 309 | buildSettings = { 310 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 311 | CODE_SIGN_STYLE = Automatic; 312 | DEVELOPMENT_TEAM = Z25J3BA353; 313 | INFOPLIST_FILE = SXAlertViewDemo/Info.plist; 314 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 315 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 316 | PRODUCT_BUNDLE_IDENTIFIER = com.st.cn.st3; 317 | PRODUCT_NAME = "$(TARGET_NAME)"; 318 | TARGETED_DEVICE_FAMILY = "1,2"; 319 | }; 320 | name = Release; 321 | }; 322 | /* End XCBuildConfiguration section */ 323 | 324 | /* Begin XCConfigurationList section */ 325 | 67F4B50B1F8CE6AB00267023 /* Build configuration list for PBXProject "SXAlertViewDemo" */ = { 326 | isa = XCConfigurationList; 327 | buildConfigurations = ( 328 | 67F4B5241F8CE6AB00267023 /* Debug */, 329 | 67F4B5251F8CE6AB00267023 /* Release */, 330 | ); 331 | defaultConfigurationIsVisible = 0; 332 | defaultConfigurationName = Release; 333 | }; 334 | 67F4B5261F8CE6AB00267023 /* Build configuration list for PBXNativeTarget "SXAlertViewDemo" */ = { 335 | isa = XCConfigurationList; 336 | buildConfigurations = ( 337 | 67F4B5271F8CE6AB00267023 /* Debug */, 338 | 67F4B5281F8CE6AB00267023 /* Release */, 339 | ); 340 | defaultConfigurationIsVisible = 0; 341 | defaultConfigurationName = Release; 342 | }; 343 | /* End XCConfigurationList section */ 344 | }; 345 | rootObject = 67F4B5081F8CE6AB00267023 /* Project object */; 346 | } 347 | -------------------------------------------------------------------------------- /SXAlertViewDemo/SXAlertViewDemo/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 | 36 | 48 | 60 | 72 | 84 | 96 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 132 | 144 | 156 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | -------------------------------------------------------------------------------- /SXAlertView/SXAlertView.m: -------------------------------------------------------------------------------- 1 | // 2 | // SXAlertView.m 3 | // SXAlertView 4 | // 5 | // Created by 沈兆良 on 2017/10/10. 6 | // Copyright © 2017年 沈兆良. All rights reserved. 7 | // 8 | 9 | #import "SXAlertView.h" 10 | 11 | typedef void (^SXAlertViewClickButtonBlock) (SXAlertView *alertView, NSInteger buttonIndex); 12 | typedef void (^SXAlertViewClickTextFieldBlock) (SXAlertView *alertView, NSInteger buttonIndex, NSString *text); 13 | 14 | CGFloat const marginX = 16; 15 | CGFloat const marginY = 20; 16 | @interface SXAlertView() 17 | 18 | /** 1.视图的宽高 */ 19 | @property(nonatomic, assign, readonly)CGFloat screenWidth; 20 | @property(nonatomic, assign, readonly)CGFloat screenHeight; 21 | @property(nonatomic, assign, readonly)CGFloat contentWidth; 22 | @property(nonatomic, assign, readonly)CGFloat contentHeight; 23 | 24 | /** 2.视图容器 */ 25 | @property(nonatomic, strong)UIView *contentView; 26 | /** 3.标题视图 */ 27 | @property(nonatomic, strong)UITextView *labelTitle; 28 | /** 4.内容视图 */ 29 | @property(nonatomic, strong)UITextView *labelMessage; 30 | /** 5.图片视图 */ 31 | @property(nonatomic, strong)UIImageView *imageIcon; 32 | /** 5.处理delegate传值 */ 33 | @property(nonatomic, strong)NSMutableArray *arrayButton; 34 | /** 6.虚化视图 */ 35 | @property(nonatomic, strong)UIVisualEffectView *effectView; 36 | 37 | @property(nonatomic, strong)UITextView *textView; 38 | @property(nonatomic, strong)UITextField *textFieldContent; 39 | 40 | /** 7.显示的数据 */ 41 | @property(nonatomic, strong, nullable)NSString *title; 42 | @property(nonatomic, strong, nullable)NSString *message; 43 | @property(nonatomic, strong, nullable)UIImage *image; 44 | @property(nonatomic, strong, nullable)NSString *placeholder; 45 | @property(nonatomic, strong, nullable)NSString *cancelButtonTitle; 46 | @property(nonatomic, strong, nullable)NSMutableArray *otherButtonTitles; 47 | 48 | @property(nonatomic, copy)SXAlertViewClickButtonBlock clickButtonBlock; 49 | @property(nonatomic, copy)SXAlertViewClickTextFieldBlock clickTextFieldBlock; 50 | @end 51 | 52 | @implementation SXAlertView 53 | 54 | #pragma mark - --- 1.lift cycle 生命周期 --- 55 | 56 | - (instancetype)initWithTitle:(nullable NSString *)title message:(nullable NSString *)message delegate:(nullable id )delegate cancelButtonTitle:(nullable NSString *)cancelButtonTitle otherButtonTitles:(nullable NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION{ 57 | if (self = [super init]) { 58 | 59 | // 1.设置数据 60 | self.title = title; 61 | self.message = message; 62 | self.delegate = delegate; 63 | 64 | _cancelButtonTitle = cancelButtonTitle; 65 | NSString * eachObject; 66 | va_list argumentList; 67 | if (otherButtonTitles) 68 | { 69 | [self.otherButtonTitles addObject:otherButtonTitles]; 70 | va_start(argumentList, otherButtonTitles); 71 | while ((eachObject = va_arg(argumentList, NSString *))) 72 | [self.otherButtonTitles addObject:eachObject]; 73 | va_end(argumentList); 74 | } 75 | 76 | // 2.初始化UI 77 | [self setupDefault]; 78 | 79 | // 3.添加子视图 80 | [self.contentView addSubview:self.labelTitle]; 81 | [self.contentView addSubview:self.labelMessage]; 82 | 83 | // 4.初始化Button 84 | [self setupButton]; 85 | } 86 | return self; 87 | } 88 | 89 | + (void)showWithTitle:(nullable NSString *)title message:(nullable NSString *)message cancelButtonTitle:(nullable NSString *)cancelButtonTitle otherButtonTitle:(nullable NSString *)otherButtonTitle clickButtonBlock:(nullable void (^)(SXAlertView * _Nonnull, NSInteger))block{ 90 | SXAlertView *alertView = [[SXAlertView alloc]initWithTitle:title message:message delegate:nil cancelButtonTitle:cancelButtonTitle otherButtonTitles:otherButtonTitle, nil]; 91 | alertView.clickButtonBlock = block; 92 | [alertView show]; 93 | } 94 | 95 | - (instancetype)initWithTitle:(nullable NSString *)title placeholder:(nullable NSString *)placeholder cancelButtonTitle:(nullable NSString *)cancelButtonTitle otherButtonTitle:(nullable NSString *)otherButtonTitle clickButtonBlock:(nullable void (^)(SXAlertView *alertView, NSInteger buttonIndex, NSString *text))block{ 96 | if (self = [super init]) { 97 | // 1.设置数据 98 | self.title = title; 99 | self.placeholder = placeholder; 100 | self.clickTextFieldBlock = block; 101 | // 2.初始化UI 102 | [self setupDefault]; 103 | // 3.添加子视图 104 | [self.contentView addSubview:self.labelTitle]; 105 | [self.contentView addSubview:self.textField]; 106 | // 4.初始化Button 107 | CGFloat buttonY = CGRectGetMaxY(self.textField.frame) + 20; 108 | [self setupButtonWithbuttonY:buttonY cancelButtonTitle:cancelButtonTitle otherButtonTitle:otherButtonTitle]; 109 | // 5.添加通知 110 | [self addObserverKeyboardNotification]; 111 | } 112 | return self; 113 | } 114 | 115 | + (void)showWithTitle:(nullable NSString *)title placeholder:(nullable NSString *)placeholder cancelButtonTitle:(nullable NSString *)cancelButtonTitle otherButtonTitle:(nullable NSString *)otherButtonTitle clickButtonBlock:(nullable void (^)(SXAlertView *alertView, NSInteger buttonIndex, NSString *text))block{ 116 | SXAlertView *alertView = [[SXAlertView alloc]initWithTitle:title placeholder:placeholder cancelButtonTitle:cancelButtonTitle otherButtonTitle:otherButtonTitle clickButtonBlock:block]; 117 | [alertView show]; 118 | } 119 | 120 | - (instancetype)initWithTitle:(nullable NSString *)title image:(nullable UIImage *)image cancelButtonTitle:(nullable NSString *)cancelButtonTitle otherButtonTitle:(nullable NSString *)otherButtonTitle clickButtonBlock:(nullable void (^)(SXAlertView *alertView, NSInteger buttonIndex))block{ 121 | if (self = [super init]) { 122 | // 1.设置数据 123 | self.widthImage = 88; 124 | self.title = title; 125 | _cancelButtonTitle = cancelButtonTitle; 126 | [self.otherButtonTitles addObject:otherButtonTitle]; 127 | self.image = image; 128 | self.clickButtonBlock = block; 129 | // 2.初始化UI 130 | [self setupDefault]; 131 | // 3.添加子视图 132 | [self.contentView addSubview:self.labelTitle]; 133 | [self.contentView addSubview:self.self.imageIcon]; 134 | // 4.初始化Button 135 | CGFloat buttonY = CGRectGetMaxY(self.imageIcon.frame) + 20; 136 | [self setupButtonWithbuttonY:buttonY cancelButtonTitle:cancelButtonTitle otherButtonTitle:otherButtonTitle]; 137 | 138 | } 139 | return self; 140 | } 141 | 142 | + (void)showWithTitle:(nullable NSString *)title image:(nullable UIImage *)image cancelButtonTitle:(nullable NSString *)cancelButtonTitle otherButtonTitle:(nullable NSString *)otherButtonTitle clickButtonBlock:(nullable void (^)(SXAlertView *alertView, NSInteger buttonIndex))block{ 143 | SXAlertView *alertView = [[SXAlertView alloc]initWithTitle:title image:image cancelButtonTitle:cancelButtonTitle otherButtonTitle:otherButtonTitle clickButtonBlock:block]; 144 | [alertView show]; 145 | } 146 | 147 | - (instancetype)initTextViewWithTitle:(nullable NSString *)title placeholder:(nullable NSString *)placeholder cancelButtonTitle:(nullable NSString *)cancelButtonTitle otherButtonTitle:(nullable NSString *)otherButtonTitle clickButtonBlock:(nullable void (^)(SXAlertView *alertView, NSInteger buttonIndex, NSString *text))block{ 148 | if (self = [super init]) { 149 | // 1.设置数据 150 | self.title = title; 151 | self.textFieldContent.placeholder = placeholder; 152 | self.clickTextFieldBlock = block; 153 | // 2.初始化UI 154 | [self setupDefault]; 155 | // 3.添加子视图 156 | [self.contentView addSubview:self.labelTitle]; 157 | [self.contentView addSubview:self.textView]; 158 | // 4.初始化Button 159 | CGFloat buttonY = CGRectGetMaxY(self.textView.frame) + 20; 160 | [self setupButtonWithbuttonY:buttonY cancelButtonTitle:cancelButtonTitle otherButtonTitle:otherButtonTitle]; 161 | // 5.添加通知 162 | [self addObserverKeyboardNotification]; 163 | } 164 | return self; 165 | } 166 | 167 | + (void)showTextViewWithTitle:(nullable NSString *)title placeholder:(nullable NSString *)placeholder cancelButtonTitle:(nullable NSString *)cancelButtonTitle otherButtonTitle:(nullable NSString *)otherButtonTitle clickButtonBlock:(nullable void (^)(SXAlertView *alertView, NSInteger buttonIndex, NSString *text))block{ 168 | SXAlertView *alertView = [[SXAlertView alloc]initTextViewWithTitle:title placeholder:placeholder cancelButtonTitle:cancelButtonTitle otherButtonTitle:otherButtonTitle clickButtonBlock:block]; 169 | [alertView show]; 170 | } 171 | 172 | - (void)dealloc{ 173 | [self removeObserverKeyboardNotification]; 174 | } 175 | 176 | - (void)setupDefault{ 177 | self.frame = CGRectMake(0, 0, self.screenWidth, self.screenHeight); 178 | self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 179 | self.backgroundColor = [UIColor clearColor]; 180 | self.visual = NO; 181 | self.animationOption = SXAlertAnimationOptionZoom; 182 | [self addSubview:self.effectView]; 183 | [self addSubview:self.contentView]; 184 | self.contentView.backgroundColor = [UIColor whiteColor]; 185 | } 186 | 187 | - (void)setupButton{ 188 | CGFloat buttonY = CGRectGetMaxY(self.labelMessage.frame) + 20; 189 | 190 | NSInteger countRow = 0; 191 | if (self.cancelButtonTitle) { 192 | countRow = 1; 193 | } 194 | countRow += self.otherButtonTitles.count; 195 | 196 | switch (countRow) { 197 | case 0:{ 198 | [self.contentView addSubview:[self buttonWithFrame:CGRectMake(0,buttonY, self.contentWidth, self.contentHeight/2) title:@"" target:self action:@selector(clickCancel:)]]; 199 | 200 | CGFloat height = self.contentHeight/2 + buttonY; 201 | self.contentView.frame = CGRectMake(0, 0, self.contentWidth, height); 202 | self.contentView.center = self.center; 203 | } 204 | break; 205 | case 2:{ 206 | NSString *titleCancel, *titleOther; 207 | if (self.cancelButtonTitle) { 208 | titleCancel = self.cancelButtonTitle; 209 | titleOther = self.otherButtonTitles.firstObject; 210 | }else { 211 | titleCancel = self.otherButtonTitles.firstObject; 212 | titleOther = self.otherButtonTitles.lastObject; 213 | } 214 | 215 | UIButton *buttonCancel = [self buttonWithFrame:CGRectMake(0,buttonY, self.contentWidth/2, self.contentHeight/2) title:titleCancel target:self action:@selector(clickCancel:)]; 216 | UIButton *buttonOther = [self buttonWithFrame:CGRectMake(self.contentWidth/2, buttonY, self.contentWidth/2, self.contentHeight/2) title:titleOther target:self action:@selector(clickOther:)]; 217 | [self.contentView addSubview:buttonOther]; 218 | [self.contentView addSubview:buttonCancel]; 219 | 220 | CGFloat height = self.contentHeight/2 + buttonY; 221 | self.contentView.frame = CGRectMake(0, 0, self.contentWidth, height); 222 | self.contentView.center = self.center; 223 | 224 | } 225 | break; 226 | default:{ 227 | for ( NSInteger number = 0; number < countRow ; number++) { 228 | NSString *title = @""; 229 | SEL selector; 230 | if (self.otherButtonTitles.count > number) { 231 | title = self.otherButtonTitles[number]; 232 | selector = @selector(clickOther:); 233 | }else { 234 | title = self.cancelButtonTitle; 235 | selector = @selector(clickCancel:); 236 | } 237 | 238 | UIButton *button = [self buttonWithFrame:CGRectMake(0, number * self.contentHeight/2 + buttonY, self.contentWidth, self.contentHeight/2) title:title target:self action:selector]; 239 | [self.arrayButton addObject:button]; 240 | [self.contentView addSubview:button]; 241 | } 242 | 243 | CGFloat height = self.contentHeight/2 + buttonY; 244 | if (countRow > 2) { 245 | height = countRow * self.contentHeight/2 + buttonY; 246 | } 247 | self.contentView.frame = CGRectMake(0, 0, self.contentWidth, height); 248 | self.contentView.center = self.center; 249 | } 250 | break; 251 | } 252 | } 253 | 254 | - (void)setupButtonWithbuttonY:(CGFloat)buttonY cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitle:(NSString *)otherButtonTitle{ 255 | UIButton *buttonCancel = [self buttonWithFrame:CGRectMake(0,buttonY, self.contentWidth/2, self.contentHeight/2) title:cancelButtonTitle target:self action:@selector(clickCancel:)]; 256 | UIButton *buttonOther = [self buttonWithFrame:CGRectMake(self.contentWidth/2, buttonY, self.contentWidth/2, self.contentHeight/2) title:otherButtonTitle target:self action:@selector(clickOther:)]; 257 | [self.contentView addSubview:buttonOther]; 258 | [self.contentView addSubview:buttonCancel]; 259 | 260 | CGFloat height = self.contentHeight/2 + buttonY; 261 | self.contentView.frame = CGRectMake(0, 0, self.contentWidth, height); 262 | self.contentView.center = self.center; 263 | } 264 | 265 | #pragma mark - --- 2.delegate 视图委托 --- 266 | - (void)textViewDidChange:(UITextView *)textView{ 267 | NSLog(@"%s %@", __FUNCTION__, textView); 268 | if (textView.text.length > 0) { 269 | self.textFieldContent.hidden = YES; 270 | }else { 271 | self.textFieldContent.hidden = NO; 272 | } 273 | 274 | if (self.clickTextFieldBlock) { 275 | self.clickTextFieldBlock(self, -1, textView.text); 276 | } 277 | } 278 | #pragma mark - --- 3.event response 事件相应 --- 279 | #pragma mark - --- 3.1.1 点击 - 取消按钮事件 --- 280 | - (void)clickCancel:(UIButton *)button{ 281 | if ([self.delegate respondsToSelector:@selector(alertView:clickedButtonAtIndex:)]) { 282 | [self.delegate alertView:self clickedButtonAtIndex:0]; 283 | } 284 | 285 | if (self.clickButtonBlock) { 286 | self.clickButtonBlock(self, 0); 287 | } 288 | 289 | if (self.textField.text.length > 0) { 290 | if (self.clickTextFieldBlock) { 291 | self.clickTextFieldBlock(self, 0, self.textField.text); 292 | } 293 | }else if (self.textView.text.length > 0){ 294 | if (self.clickTextFieldBlock) { 295 | self.clickTextFieldBlock(self,0, self.textView.text); 296 | } 297 | }else { 298 | if (self.clickTextFieldBlock) { 299 | self.clickTextFieldBlock(self,0, @""); 300 | } 301 | } 302 | [self remove]; 303 | } 304 | 305 | #pragma mark - --- 3.1.2 点击 - 其他按钮事件 --- 306 | - (void)clickOther:(UIButton *)button{ 307 | NSInteger buttonIndex = 0; 308 | if (self.cancelButtonTitle) { 309 | buttonIndex = 1; 310 | } 311 | if (self.arrayButton.count) { 312 | buttonIndex += [self.arrayButton indexOfObject:button]; 313 | } 314 | if ([self.delegate respondsToSelector:@selector(alertView:clickedButtonAtIndex:)]) { 315 | [self.delegate alertView:self clickedButtonAtIndex:buttonIndex]; 316 | } 317 | 318 | if (self.clickButtonBlock) { 319 | self.clickButtonBlock(self, buttonIndex); 320 | } 321 | 322 | if (self.textField.text.length > 0) { 323 | if (self.clickTextFieldBlock) { 324 | self.clickTextFieldBlock(self, 1, self.textField.text); 325 | } 326 | }else if (self.textView.text.length > 0){ 327 | if (self.clickTextFieldBlock) { 328 | self.clickTextFieldBlock(self, 1, self.textView.text); 329 | } 330 | }else { 331 | if (self.clickTextFieldBlock) { 332 | self.clickTextFieldBlock(self, 1, @""); 333 | } 334 | } 335 | 336 | [self remove]; 337 | } 338 | 339 | #pragma mark - --- 3.2 UITextField - 编辑事件 --- 340 | - (void)clickTextChanged:(UITextField *)textField{ 341 | if (self.clickTextFieldBlock) { 342 | self.clickTextFieldBlock(self, -1, textField.text); 343 | } 344 | } 345 | 346 | #pragma mark - --- 3.3 视图展示与隐藏 --- 347 | - (void)show { 348 | // 用于隐藏已显示的键盘 349 | [[[UIInputViewController alloc] init] dismissKeyboard]; 350 | 351 | [[UIApplication sharedApplication].delegate.window addSubview:self]; 352 | 353 | switch (self.animationOption) { 354 | case SXAlertAnimationOptionNone:{ 355 | self.contentView.alpha = 0.0; 356 | [UIView animateWithDuration:0.34 animations:^{ 357 | if (self.visual) { 358 | self.effectView.effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark]; 359 | } 360 | self.contentView.alpha = 1.0; 361 | }]; 362 | }break; 363 | case SXAlertAnimationOptionZoom:{ 364 | [self.contentView.layer setValue:@(0) forKeyPath:@"transform.scale"]; 365 | [UIView animateWithDuration:0.75 delay:0 usingSpringWithDamping:0.5 initialSpringVelocity:1.0 366 | options:UIViewAnimationOptionCurveEaseIn 367 | animations:^{ 368 | if (self.visual) { 369 | self.effectView.effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark]; 370 | } 371 | [self.contentView.layer setValue:@(1.0) forKeyPath:@"transform.scale"]; 372 | } completion:nil]; 373 | }break; 374 | case SXAlertAnimationOptionTopToCenter:{ 375 | CGPoint startPoint = CGPointMake(self.center.x, - CGRectGetHeight(self.contentView.frame)); 376 | self.contentView.layer.position = startPoint; 377 | [UIView animateWithDuration:0.75 delay:0 usingSpringWithDamping:0.5 initialSpringVelocity:1.0 378 | options:UIViewAnimationOptionCurveEaseIn 379 | animations:^{ 380 | if (self.visual) { 381 | self.effectView.effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark]; 382 | } 383 | self.contentView.layer.position = self.center; 384 | } completion:nil]; 385 | }break; 386 | default: 387 | break; 388 | } 389 | } 390 | 391 | - (void)remove{ 392 | switch (self.animationOption) { 393 | case SXAlertAnimationOptionNone:{ 394 | [UIView animateWithDuration:0.3 animations:^{ 395 | if (self.visual) { 396 | self.effectView.effect = nil; 397 | } 398 | self.contentView.alpha = 0.0; 399 | } completion:^(BOOL finished) { 400 | [self removeFromSuperview]; 401 | }]; 402 | }break; 403 | case SXAlertAnimationOptionZoom:{ 404 | [UIView animateWithDuration:0.3 animations:^{ 405 | self.contentView.alpha = 0.0; 406 | if (self.visual) { 407 | self.effectView.effect = nil; 408 | } 409 | } completion:^(BOOL finished) { 410 | [self removeFromSuperview]; 411 | }]; 412 | }break; 413 | case SXAlertAnimationOptionTopToCenter:{ 414 | CGPoint endPoint = CGPointMake(self.center.x, CGRectGetHeight(self.frame) + CGRectGetHeight(self.contentView.frame)); 415 | [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ 416 | if (self.visual) { 417 | self.effectView.effect = nil; 418 | } 419 | self.contentView.layer.position = endPoint; 420 | } completion:^(BOOL finished) { 421 | [self removeFromSuperview]; 422 | }]; 423 | }break; 424 | default: 425 | break; 426 | } 427 | } 428 | 429 | #pragma mark - --- 3.4 键盘通知事件 --- 430 | - (void)addObserverKeyboardNotification{ 431 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; 432 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; 433 | } 434 | 435 | - (void)removeObserverKeyboardNotification{ 436 | [[NSNotificationCenter defaultCenter]removeObserver:self name:UIKeyboardWillShowNotification object:nil]; 437 | [[NSNotificationCenter defaultCenter]removeObserver:self name:UIKeyboardWillHideNotification object:nil]; 438 | } 439 | 440 | - (void)keyboardWillShow:(NSNotification *)noti{ 441 | CGRect rect = [noti.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; 442 | CGFloat height = rect.size.height; 443 | CGPoint center = self.center; 444 | center.y -= height/2; 445 | [UIView animateWithDuration:0.3 animations:^{ 446 | self.contentView.center = center; 447 | }]; 448 | } 449 | 450 | - (void)keyboardWillHide:(NSNotification *)noti{ 451 | CGPoint center = self.center; 452 | [UIView animateWithDuration:0.3 animations:^{ 453 | self.contentView.center = center; 454 | }]; 455 | } 456 | #pragma mark - --- 4.private methods 私有方法 --- 457 | 458 | - (UIImage *)imageWithColor:(UIColor *)color { 459 | CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f); 460 | UIGraphicsBeginImageContext(rect.size); 461 | CGContextRef context = UIGraphicsGetCurrentContext(); 462 | CGContextSetFillColorWithColor(context, [color CGColor]); 463 | CGContextFillRect(context, rect); 464 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 465 | UIGraphicsEndImageContext(); 466 | return image; 467 | } 468 | 469 | - (UIButton *)buttonWithFrame:(CGRect)frame title:(NSString *)title target:(nullable id)target action:(nullable SEL)action{ 470 | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 471 | button.frame = frame; 472 | [button setTitleColor:[UIColor colorWithRed:(70.0/255) green:(130.0/255) blue:(233.0/255) alpha:1.0] forState:UIControlStateNormal]; 473 | [button setTitle:title forState:UIControlStateNormal]; 474 | [button setBackgroundImage:[self imageWithColor:[UIColor colorWithRed:(235.0/255) green:(235.0/255) blue:(235.0/255) alpha:1.0]] forState:UIControlStateHighlighted]; 475 | button.titleLabel.adjustsFontSizeToFitWidth = YES; 476 | [button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside]; 477 | UIView *lineUp = [[UIView alloc]initWithFrame:CGRectMake(0, 0, frame.size.width, 0.5)]; 478 | lineUp.backgroundColor = [UIColor colorWithRed:(219.0/255) green:(219.0/255) blue:(219.0/255) alpha:1.0]; 479 | 480 | UIView *lineRight = [[UIView alloc]initWithFrame:CGRectMake(frame.size.width, 0, 0.5, frame.size.height)]; 481 | lineRight.backgroundColor = [UIColor colorWithRed:(219.0/255) green:(219.0/255) blue:(219.0/255) alpha:1.0]; 482 | 483 | [button addSubview:lineUp]; 484 | [button addSubview:lineRight]; 485 | return button; 486 | } 487 | 488 | #pragma mark - --- 5.setters 属性 --- 489 | 490 | - (void)setTitle:(NSString *)title{ 491 | _title = title; 492 | self.labelTitle.text = title; 493 | 494 | CGFloat labelX = marginX; 495 | CGFloat labelY = marginY; 496 | CGFloat labelW = self.contentWidth - 2*labelX; 497 | 498 | [self.labelTitle sizeToFit]; 499 | CGSize sizeTitle = self.labelTitle.frame.size; 500 | if (sizeTitle.height > self.screenHeight/2) { 501 | sizeTitle.height = self.screenHeight/2; 502 | } 503 | CGFloat labelH = sizeTitle.height; 504 | if (!title) { 505 | labelH = 0; 506 | } 507 | self.labelTitle.frame = CGRectMake(labelX, labelY, labelW, labelH); 508 | self.textView.frame = CGRectMake(labelX, labelY+labelH+5, labelW, 75); 509 | } 510 | 511 | - (void)setMessage:(NSString *)message{ 512 | 513 | _message = message; 514 | 515 | CGFloat labelX = marginX; 516 | CGFloat labelY = CGRectGetMaxY(self.labelTitle.frame) + 5; 517 | CGFloat labelW = self.contentWidth - 2*labelX; 518 | 519 | self.labelMessage.text = message; 520 | [self.labelMessage sizeToFit]; 521 | CGSize sizeMessage = self.labelMessage.frame.size; 522 | if (sizeMessage.height > self.screenHeight/2) { 523 | sizeMessage.height = self.screenHeight/2; 524 | } 525 | CGFloat labelH = sizeMessage.height; 526 | if (!message) { 527 | labelH = 0; 528 | } 529 | self.labelMessage.frame = CGRectMake(labelX, labelY, labelW, labelH); 530 | } 531 | 532 | - (void)setPlaceholder:(NSString *)placeholder{ 533 | _placeholder = placeholder; 534 | 535 | CGFloat tfX = marginX; 536 | CGFloat tfY = CGRectGetMaxY(self.labelTitle.frame) + 5; 537 | CGFloat tfW = self.contentWidth - 2*tfX; 538 | 539 | self.textField.placeholder = placeholder; 540 | [self.textField sizeToFit]; 541 | CGSize sizeMessage = self.textField.frame.size; 542 | if (sizeMessage.height > self.screenHeight/2) { 543 | sizeMessage.height = self.screenHeight/2; 544 | } 545 | CGFloat tfH = sizeMessage.height; 546 | self.textField.frame = CGRectMake(tfX, tfY, tfW, tfH); 547 | } 548 | 549 | - (void)setImage:(UIImage *)image{ 550 | _image = image; 551 | CGFloat labelY = CGRectGetMaxY(self.labelTitle.frame) + 5; 552 | self.imageIcon.image = image; 553 | [self.imageIcon sizeToFit]; 554 | CGFloat imageW = self.imageIcon.frame.size.width; 555 | CGFloat imageH = self.imageIcon.frame.size.height; 556 | 557 | if (imageW > imageH) { 558 | CGFloat h = imageH; 559 | imageH = self.widthImage; 560 | imageW = imageW / h * self.widthImage; 561 | 562 | if (imageW > self.contentWidth - 2*marginX) { 563 | imageW = self.contentWidth - 2*marginX; 564 | } 565 | }else if (imageW == imageH){ 566 | imageW = self.widthImage; 567 | imageH = self.widthImage; 568 | }else { 569 | CGFloat w = imageW; 570 | imageW = self.widthImage; 571 | imageH = imageH / w * self.widthImage; 572 | 573 | if (imageH > self.contentWidth - 2*marginX) { 574 | imageH = self.contentWidth - 2*marginX; 575 | } 576 | } 577 | 578 | CGFloat labelX = (self.contentWidth - imageW)/2; 579 | self.imageIcon.frame = CGRectMake(labelX, labelY, imageW, imageH); 580 | } 581 | 582 | - (void)setTextAlignment:(NSTextAlignment)textAlignment{ 583 | _textAlignment = textAlignment; 584 | self.labelMessage.textAlignment = textAlignment; 585 | } 586 | 587 | - (void)setVisual:(BOOL)visual{ 588 | _visual = visual; 589 | if (visual) { 590 | self.effectView.backgroundColor = [UIColor clearColor]; 591 | }else { 592 | self.effectView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:102.0/255]; 593 | } 594 | } 595 | #pragma mark - --- 6.getters 属性 —-- 596 | - (CGFloat)screenWidth{ 597 | return CGRectGetWidth([UIScreen mainScreen].bounds); 598 | } 599 | 600 | - (CGFloat)screenHeight{ 601 | return CGRectGetHeight([UIScreen mainScreen].bounds); 602 | } 603 | 604 | - (CGFloat)contentWidth{ 605 | return 270; 606 | } 607 | 608 | - (CGFloat)contentHeight{ 609 | return 88; 610 | } 611 | 612 | - (NSMutableArray *)otherButtonTitles{ 613 | if (!_otherButtonTitles) { 614 | _otherButtonTitles = @[].mutableCopy; 615 | } 616 | return _otherButtonTitles; 617 | } 618 | 619 | - (UIView *)contentView{ 620 | if (!_contentView) { 621 | _contentView = [[UIView alloc]init]; 622 | _contentView.frame = CGRectMake(0, 0, self.contentWidth, self.contentHeight); 623 | _contentView.center = CGPointMake(self.screenWidth/2, self.screenHeight/2); 624 | 625 | _contentView.backgroundColor = [UIColor whiteColor]; 626 | [_contentView.layer setCornerRadius:10]; 627 | [_contentView.layer setMasksToBounds:YES]; 628 | _contentView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; 629 | } 630 | return _contentView; 631 | } 632 | 633 | - (UITextView *)labelTitle 634 | { 635 | if (!_labelTitle) { 636 | _labelTitle = [[UITextView alloc]init]; 637 | _labelTitle.frame = CGRectMake(marginX, marginY, self.contentWidth-2*marginX, 0); 638 | _labelTitle.textColor = [UIColor blackColor]; 639 | _labelTitle.textAlignment = NSTextAlignmentCenter; 640 | _labelTitle.font = [UIFont boldSystemFontOfSize:17]; 641 | [_labelTitle setEditable:NO]; 642 | [_labelTitle setSelectable:NO]; 643 | } 644 | return _labelTitle; 645 | } 646 | 647 | - (UITextView *)labelMessage 648 | { 649 | if (!_labelMessage) { 650 | _labelMessage = [[UITextView alloc]init]; 651 | _labelMessage.frame = CGRectMake(marginX, marginY, self.contentWidth-2*marginX, 0); 652 | _labelMessage.textColor = [UIColor blackColor]; 653 | _labelMessage.textAlignment = NSTextAlignmentCenter; 654 | _labelMessage.font = [UIFont systemFontOfSize:13]; 655 | [_labelMessage setEditable:NO]; 656 | [_labelMessage setSelectable:NO]; 657 | } 658 | return _labelMessage; 659 | } 660 | 661 | - (UITextField *)textField 662 | { 663 | if (!_textField) { 664 | _textField = [[UITextField alloc]init]; 665 | _textField.frame = CGRectMake(marginX, marginY, self.contentWidth-2*marginX, 0); 666 | _textField.textColor = [UIColor blackColor]; 667 | _textField.font = [UIFont systemFontOfSize:15]; 668 | _textField.borderStyle = UITextBorderStyleRoundedRect; 669 | [_textField addTarget:self action:@selector(clickTextChanged:) forControlEvents:UIControlEventEditingChanged]; 670 | } 671 | return _textField; 672 | } 673 | 674 | - (UIImageView *)imageIcon{ 675 | if (!_imageIcon) { 676 | _imageIcon = [[UIImageView alloc]init]; 677 | } 678 | return _imageIcon; 679 | 680 | } 681 | 682 | - (UIVisualEffectView *)effectView 683 | { 684 | if (!_effectView) { 685 | _effectView = [[UIVisualEffectView alloc]init]; 686 | _effectView.effect = nil; 687 | _effectView.frame = self.frame; 688 | _effectView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 689 | } 690 | return _effectView; 691 | } 692 | 693 | - (UITextView *)textView 694 | { 695 | if (!_textView) { 696 | _textView = [[UITextView alloc]init]; 697 | _textView.frame = CGRectMake(marginX, marginY, self.contentWidth-2*marginX, 75); 698 | _textView.textColor = [UIColor blackColor]; 699 | _textView.font = [UIFont systemFontOfSize:15]; 700 | [_textView.layer setBorderColor:[UIColor colorWithRed:220.0/255 green:220.0/255 blue:220.0/255 alpha:1].CGColor]; 701 | [_textView.layer setBorderWidth:0.5]; 702 | [_textView.layer setMasksToBounds:YES]; 703 | [_textView.layer setCornerRadius:4]; 704 | [_textView addSubview:self.textFieldContent]; 705 | [_textView setDelegate:self]; 706 | } 707 | return _textView; 708 | } 709 | 710 | - (UITextField *)textFieldContent 711 | { 712 | if (!_textFieldContent) { 713 | _textFieldContent = [[UITextField alloc]init]; 714 | _textFieldContent.frame = CGRectMake(4, -6, self.contentWidth-2*marginX, 44); 715 | _textFieldContent.font = [UIFont systemFontOfSize:15]; 716 | _textFieldContent.borderStyle = UITextBorderStyleNone; 717 | [_textFieldContent setEnabled:NO]; 718 | } 719 | return _textFieldContent; 720 | } 721 | 722 | - (NSMutableArray *)arrayButton 723 | { 724 | if (!_arrayButton) { 725 | _arrayButton = @[].mutableCopy; 726 | } 727 | return _arrayButton; 728 | } 729 | 730 | @end 731 | 732 | --------------------------------------------------------------------------------