├── TYAlertControllerDemo ├── screen.jpg ├── Images.xcassets │ ├── Contents.json │ ├── btn_share_QQ.imageset │ │ ├── btn_share_QQ@2x.png │ │ └── Contents.json │ ├── btn_share_del.imageset │ │ ├── btn_share_del@2x.png │ │ └── Contents.json │ ├── btn_share_sina.imageset │ │ ├── btn_share_sina@2x.png │ │ └── Contents.json │ ├── btn_share_weixin.imageset │ │ ├── btn_share_weixin@2x.png │ │ └── Contents.json │ ├── btn_share_QQhaoyou.imageset │ │ ├── btn_share_QQhaoyou@2x.png │ │ └── Contents.json │ ├── btn_share_pengyouquan.imageset │ │ ├── btn_share_pengyouquan@2x.png │ │ └── Contents.json │ └── AppIcon.appiconset │ │ └── Contents.json ├── ShareView.h ├── SettingModelView.h ├── ViewController.h ├── TYAlertController │ ├── TYAlertFadeAnimation.h │ ├── TYAlertDropDownAnimation.h │ ├── TYAlertScaleFadeAnimation.h │ ├── TYShowAlertView.h │ ├── TYBaseAnimation.h │ ├── UIView+TYAutoLayout.h │ ├── TYBaseAnimation.m │ ├── UIView+TYAlertView.h │ ├── TYAlertController+TransitionAnimate.m │ ├── TYAlertView.h │ ├── TYAlertDropDownAnimation.m │ ├── TYAlertController.h │ ├── TYAlertScaleFadeAnimation.m │ ├── TYAlertFadeAnimation.m │ ├── UIView+TYAlertView.m │ ├── UIView+TYAutoLayout.m │ ├── TYShowAlertView.m │ ├── TYAlertController.m │ └── TYAlertView.m ├── AppDelegate.h ├── main.m ├── SettingModelView.m ├── ShareView.m ├── Blur Effects │ ├── TYAlertController+BlurEffects.h │ ├── UIImage+ImageEffects.h │ ├── TYAlertController+BlurEffects.m │ └── UIImage+ImageEffects.m ├── Info.plist ├── AppDelegate.m ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard ├── ViewController.m ├── SettingModelView.xib └── ShareView.xib ├── screenshot └── TYAlertControllerDemo.gif ├── TYAlertControllerDemo.xcodeproj ├── xcuserdata │ ├── tanyang.xcuserdatad │ │ ├── xcdebugger │ │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ │ ├── xcschememanagement.plist │ │ │ └── TYAlertControllerDemo.xcscheme │ └── 233wangxiao.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ ├── xcschememanagement.plist │ │ └── TYAlertControllerDemo.xcscheme ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ ├── tanyang.xcuserdatad │ │ └── UserInterfaceState.xcuserstate │ │ └── 233wangxiao.xcuserdatad │ │ └── WorkspaceSettings.xcsettings └── project.pbxproj ├── TYAlertControllerDemoTests ├── Info.plist └── TYAlertControllerDemoTests.m ├── TYAlertController.podspec ├── LICENSE └── README.md /TYAlertControllerDemo/screen.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/12207480/TYAlertController/HEAD/TYAlertControllerDemo/screen.jpg -------------------------------------------------------------------------------- /TYAlertControllerDemo/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /screenshot/TYAlertControllerDemo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/12207480/TYAlertController/HEAD/screenshot/TYAlertControllerDemo.gif -------------------------------------------------------------------------------- /TYAlertControllerDemo.xcodeproj/xcuserdata/tanyang.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /TYAlertControllerDemo.xcodeproj/xcuserdata/233wangxiao.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/Images.xcassets/btn_share_QQ.imageset/btn_share_QQ@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/12207480/TYAlertController/HEAD/TYAlertControllerDemo/Images.xcassets/btn_share_QQ.imageset/btn_share_QQ@2x.png -------------------------------------------------------------------------------- /TYAlertControllerDemo/Images.xcassets/btn_share_del.imageset/btn_share_del@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/12207480/TYAlertController/HEAD/TYAlertControllerDemo/Images.xcassets/btn_share_del.imageset/btn_share_del@2x.png -------------------------------------------------------------------------------- /TYAlertControllerDemo/Images.xcassets/btn_share_sina.imageset/btn_share_sina@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/12207480/TYAlertController/HEAD/TYAlertControllerDemo/Images.xcassets/btn_share_sina.imageset/btn_share_sina@2x.png -------------------------------------------------------------------------------- /TYAlertControllerDemo/Images.xcassets/btn_share_weixin.imageset/btn_share_weixin@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/12207480/TYAlertController/HEAD/TYAlertControllerDemo/Images.xcassets/btn_share_weixin.imageset/btn_share_weixin@2x.png -------------------------------------------------------------------------------- /TYAlertControllerDemo/Images.xcassets/btn_share_QQhaoyou.imageset/btn_share_QQhaoyou@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/12207480/TYAlertController/HEAD/TYAlertControllerDemo/Images.xcassets/btn_share_QQhaoyou.imageset/btn_share_QQhaoyou@2x.png -------------------------------------------------------------------------------- /TYAlertControllerDemo/Images.xcassets/btn_share_pengyouquan.imageset/btn_share_pengyouquan@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/12207480/TYAlertController/HEAD/TYAlertControllerDemo/Images.xcassets/btn_share_pengyouquan.imageset/btn_share_pengyouquan@2x.png -------------------------------------------------------------------------------- /TYAlertControllerDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /TYAlertControllerDemo.xcodeproj/project.xcworkspace/xcuserdata/tanyang.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/12207480/TYAlertController/HEAD/TYAlertControllerDemo.xcodeproj/project.xcworkspace/xcuserdata/tanyang.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /TYAlertControllerDemo/ShareView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ShareView.h 3 | // TYAlertControllerDemo 4 | // 5 | // Created by tanyang on 15/10/26. 6 | // Copyright © 2015年 tanyang. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ShareView : UIView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/SettingModelView.h: -------------------------------------------------------------------------------- 1 | // 2 | // SettingModelView.h 3 | // TYAlertControllerDemo 4 | // 5 | // Created by tanyang on 15/10/26. 6 | // Copyright © 2015年 tanyang. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SettingModelView : UIView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // TYAlertControllerDemo 4 | // 5 | // Created by tanyang on 15/9/1. 6 | // Copyright (c) 2015年 tanyang. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/TYAlertController/TYAlertFadeAnimation.h: -------------------------------------------------------------------------------- 1 | // 2 | // TYAlertDefaultAnimation.h 3 | // TYAlertControllerDemo 4 | // 5 | // Created by SunYong on 15/9/1. 6 | // Copyright (c) 2015年 tanyang. All rights reserved. 7 | // 8 | 9 | #import "TYBaseAnimation.h" 10 | 11 | @interface TYAlertFadeAnimation : TYBaseAnimation 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/TYAlertController/TYAlertDropDownAnimation.h: -------------------------------------------------------------------------------- 1 | // 2 | // TYAlertDropDownAnimation.h 3 | // TYAlertControllerDemo 4 | // 5 | // Created by tanyang on 15/10/27. 6 | // Copyright © 2015年 tanyang. All rights reserved. 7 | // 8 | 9 | #import "TYBaseAnimation.h" 10 | 11 | @interface TYAlertDropDownAnimation : TYBaseAnimation 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/TYAlertController/TYAlertScaleFadeAnimation.h: -------------------------------------------------------------------------------- 1 | // 2 | // TYAlertScaleFadeAnimation.h 3 | // TYAlertControllerDemo 4 | // 5 | // Created by SunYong on 15/9/2. 6 | // Copyright (c) 2015年 tanyang. All rights reserved. 7 | // 8 | 9 | #import "TYBaseAnimation.h" 10 | 11 | @interface TYAlertScaleFadeAnimation : TYBaseAnimation 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // TYAlertControllerDemo 4 | // 5 | // Created by tanyang on 15/9/1. 6 | // Copyright (c) 2015年 tanyang. 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 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // TYAlertControllerDemo 4 | // 5 | // Created by SunYong on 15/9/1. 6 | // Copyright (c) 2015年 tanyang. 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 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/Images.xcassets/btn_share_QQ.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "btn_share_QQ@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TYAlertControllerDemo/Images.xcassets/btn_share_del.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "btn_share_del@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TYAlertControllerDemo/Images.xcassets/btn_share_sina.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "btn_share_sina@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TYAlertControllerDemo.xcodeproj/project.xcworkspace/xcuserdata/233wangxiao.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges 6 | 7 | SnapshotAutomaticallyBeforeSignificantChanges 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/Images.xcassets/btn_share_QQhaoyou.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "btn_share_QQhaoyou@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TYAlertControllerDemo/Images.xcassets/btn_share_weixin.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "btn_share_weixin@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TYAlertControllerDemo/Images.xcassets/btn_share_pengyouquan.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "btn_share_pengyouquan@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TYAlertControllerDemo/SettingModelView.m: -------------------------------------------------------------------------------- 1 | // 2 | // SettingModelView.m 3 | // TYAlertControllerDemo 4 | // 5 | // Created by tanyang on 15/10/26. 6 | // Copyright © 2015年 tanyang. All rights reserved. 7 | // 8 | 9 | #import "SettingModelView.h" 10 | 11 | @implementation SettingModelView 12 | 13 | /* 14 | // Only override drawRect: if you perform custom drawing. 15 | // An empty implementation adversely affects performance during animation. 16 | - (void)drawRect:(CGRect)rect { 17 | // Drawing code 18 | } 19 | */ 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/ShareView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ShareView.m 3 | // TYAlertControllerDemo 4 | // 5 | // Created by tanyang on 15/10/26. 6 | // Copyright © 2015年 tanyang. All rights reserved. 7 | // 8 | 9 | #import "ShareView.h" 10 | #import "UIView+TYAlertView.h" 11 | 12 | @implementation ShareView 13 | 14 | - (IBAction)cancelAction:(id)sender { 15 | // hide view,or dismiss controller 16 | [self hideView]; 17 | } 18 | 19 | /* 20 | // Only override drawRect: if you perform custom drawing. 21 | // An empty implementation adversely affects performance during animation. 22 | - (void)drawRect:(CGRect)rect { 23 | // Drawing code 24 | } 25 | */ 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/Blur Effects/TYAlertController+BlurEffects.h: -------------------------------------------------------------------------------- 1 | // 2 | // TYAlertController+BlurEffects.h 3 | // TYAlertControllerDemo 4 | // 5 | // Created by tanyang on 15/10/26. 6 | // Copyright © 2015年 tanyang. All rights reserved. 7 | // 8 | 9 | #import "TYAlertController.h" 10 | 11 | typedef NS_ENUM(NSUInteger, BlurEffectStyle) { 12 | BlurEffectStyleLight, 13 | BlurEffectStyleExtraLight, 14 | BlurEffectStyleDarkEffect, 15 | }; 16 | 17 | @interface TYAlertController (BlurEffects) 18 | 19 | - (void)setBlurEffectWithView:(UIView *)view; 20 | 21 | - (void)setBlurEffectWithView:(UIView *)view style:(BlurEffectStyle)blurStyle; 22 | 23 | - (void)setBlurEffectWithView:(UIView *)view effectTintColor:(UIColor *)effectTintColor; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /TYAlertControllerDemo.xcodeproj/xcuserdata/tanyang.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | TYAlertControllerDemo.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | D358541D1B9532D700B5FA1F 16 | 17 | primary 18 | 19 | 20 | D35854361B9532D700B5FA1F 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /TYAlertControllerDemo.xcodeproj/xcuserdata/233wangxiao.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | TYAlertControllerDemo.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | D358541D1B9532D700B5FA1F 16 | 17 | primary 18 | 19 | 20 | D35854361B9532D700B5FA1F 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /TYAlertControllerDemoTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.tanyang.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/Blur Effects/UIImage+ImageEffects.h: -------------------------------------------------------------------------------- 1 | /* 2 | File: UIImage+ImageEffects.h 3 | Abstract: This is a category of UIImage that adds methods to apply blur and tint effects to an image. This is the code you’ll want to look out to find out how to use vImage to efficiently calculate a blur. 4 | Version: 1.0 5 | */ 6 | 7 | @import UIKit; 8 | 9 | @interface UIImage (ImageEffects) 10 | 11 | - (UIImage *)applyLightEffect; 12 | - (UIImage *)applyExtraLightEffect; 13 | - (UIImage *)applyDarkEffect; 14 | - (UIImage *)applyTintEffectWithColor:(UIColor *)tintColor; 15 | 16 | - (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage; 17 | 18 | @end 19 | 20 | @interface UIImage (SnapshotImage) 21 | 22 | + (UIImage *)snapshotImageWithView:(UIView *)view; 23 | 24 | @end 25 | 26 | -------------------------------------------------------------------------------- /TYAlertController.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | # 名称 使用的时候pod search [name] 3 | s.name = "TYAlertController" 4 | # 代码库的版本 5 | s.version = "1.2.0" 6 | # 简介 7 | s.summary = "Powerful, Easy to use alertview or popup view on controller and window, support blur effects,custom view and animation." 8 | # 主页 9 | s.homepage = "https://github.com/12207480/TYAlertController" 10 | # 许可证书类型,要和仓库的LICENSE 的类型一致 11 | s.license = { :type => 'MIT', :file => 'LICENSE' } 12 | # 作者名称 和 邮箱 13 | s.author = { "tany" => "122074809@qq.com" } 14 | # 作者主页 s.social_media_url ="" 15 | # 代码库最低支持的版本 16 | s.platform = :ios, "7.0" 17 | # 代码的Clone 地址 和 tag 版本 18 | s.source = { :git => "https://github.com/12207480/TYAlertController.git", :tag => s.version.to_s } 19 | # 如果使用pod 需要导入哪些资源 20 | s.source_files = "TYAlertControllerDemo/TYAlertController/**/*.{h,m}" 21 | # s.resources = "**/*/*.bundle" 22 | # 框架是否使用的ARC 23 | s.requires_arc = true 24 | end 25 | -------------------------------------------------------------------------------- /TYAlertControllerDemoTests/TYAlertControllerDemoTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // TYAlertControllerDemoTests.m 3 | // TYAlertControllerDemoTests 4 | // 5 | // Created by SunYong on 15/9/1. 6 | // Copyright (c) 2015年 tanyang. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface TYAlertControllerDemoTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation TYAlertControllerDemoTests 17 | 18 | - (void)setUp { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown { 24 | // Put teardown code here. This method is called after the invocation of each test method in the class. 25 | [super tearDown]; 26 | } 27 | 28 | - (void)testExample { 29 | // This is an example of a functional test case. 30 | XCTAssert(YES, @"Pass"); 31 | } 32 | 33 | - (void)testPerformanceExample { 34 | // This is an example of a performance test case. 35 | [self measureBlock:^{ 36 | // Put the code you want to measure the time of here. 37 | }]; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 tany 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 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/TYAlertController/TYShowAlertView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TYShowAlertView.h 3 | // TYAlertControllerDemo 4 | // 5 | // Created by tanyang on 15/3/16. 6 | // Copyright (c) 2015年 mark. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TYShowAlertView : UIView 12 | 13 | @property (nonatomic, weak, readonly) UIView *alertView; 14 | @property (nonatomic, strong) UIView *backgroundView; 15 | 16 | @property (nonatomic, assign) BOOL backgoundTapDismissEnable; // default NO 17 | @property (nonatomic, assign) CGFloat alertViewOriginY; // default center Y 18 | @property (nonatomic, assign) CGFloat alertViewEdging; // default 15 19 | 20 | +(void)showAlertViewWithView:(UIView *)alertView; 21 | 22 | + (void)showAlertViewWithView:(UIView *)alertView backgoundTapDismissEnable:(BOOL)backgoundTapDismissEnable; 23 | 24 | +(void)showAlertViewWithView:(UIView *)alertView originY:(CGFloat)originY; 25 | 26 | +(void)showAlertViewWithView:(UIView *)alertView originY:(CGFloat)originY backgoundTapDismissEnable:(BOOL)backgoundTapDismissEnable; 27 | 28 | + (instancetype)alertViewWithView:(UIView *)alertView; 29 | 30 | - (void)show; 31 | 32 | - (void)hide; 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/TYAlertController/TYBaseAnimation.h: -------------------------------------------------------------------------------- 1 | // 2 | // TYBaseAnimation.h 3 | // TYAlertControllerDemo 4 | // 5 | // Created by SunYong on 15/9/1. 6 | // Copyright (c) 2015年 tanyang. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "TYAlertController.h" 11 | 12 | @interface TYBaseAnimation : NSObject 13 | 14 | @property (nonatomic, assign, readonly) BOOL isPresenting; // present . dismiss 15 | 16 | + (instancetype)alertAnimationIsPresenting:(BOOL)isPresenting; 17 | 18 | // if you only want alert or actionsheet style ,you can judge that you don't need and return nil 19 | // code : only support alert style 20 | // if (preferredStyle == TYAlertControllerStyleAlert) { 21 | // return [super alertAnimationIsPresenting:isPresenting]; 22 | // } 23 | // return nil; 24 | + (instancetype)alertAnimationIsPresenting:(BOOL)isPresenting preferredStyle:(TYAlertControllerStyle) preferredStyle; 25 | 26 | 27 | // override transiton time 28 | - (NSTimeInterval)transitionDuration:(id)transitionContext; 29 | 30 | // override present 31 | - (void)presentAnimateTransition:(id)transitionContext; 32 | 33 | // override dismiss 34 | - (void)dismissAnimateTransition:(id)transitionContext; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/TYAlertController/UIView+TYAutoLayout.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+TYAutoLayout.h 3 | // TYAlertControllerDemo 4 | // 5 | // Created by tanyang on 15/9/8. 6 | // Copyright (c) 2015年 tanyang. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIView (TYAutoLayout) 12 | 13 | - (void)addConstraintToView:(UIView *)view edgeInset:(UIEdgeInsets)edgeInset; 14 | 15 | - (void)addConstraintWithView:(UIView *)view topView:(UIView *)topView leftView:(UIView *)leftView 16 | bottomView:(UIView *)bottomView rightView:(UIView *)rightView edgeInset:(UIEdgeInsets)edgeInset; 17 | 18 | - (void)addConstraintWithLeftView:(UIView *)leftView toRightView:(UIView *)rightView constant:(CGFloat)constant; 19 | 20 | - (NSLayoutConstraint *)addConstraintWithTopView:(UIView *)topView toBottomView:(UIView *)bottomView constant:(CGFloat)constant; 21 | 22 | - (void)addConstraintWidth:(CGFloat)width height:(CGFloat)height; 23 | 24 | - (void)addConstraintEqualWithView:(UIView *)view widthToView:(UIView *)wView heightToView:(UIView *)hView; 25 | 26 | - (NSLayoutConstraint *)addConstraintCenterYToView:(UIView *)yView constant:(CGFloat)constant; 27 | 28 | - (void)addConstraintCenterXToView:(UIView *)xView centerYToView:(UIView *)yView; 29 | 30 | - (void)removeConstraintWithAttribte:(NSLayoutAttribute)attr; 31 | 32 | - (void)removeConstraintWithView:(UIView *)view attribute:(NSLayoutAttribute)attr; 33 | 34 | - (void)removeAllConstraints; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/TYAlertController/TYBaseAnimation.m: -------------------------------------------------------------------------------- 1 | // 2 | // TYBaseAnimation.m 3 | // TYAlertControllerDemo 4 | // 5 | // Created by SunYong on 15/9/1. 6 | // Copyright (c) 2015年 tanyang. All rights reserved. 7 | // 8 | 9 | #import "TYBaseAnimation.h" 10 | 11 | @interface TYBaseAnimation () 12 | @property (nonatomic, assign) BOOL isPresenting; 13 | @end 14 | 15 | @implementation TYBaseAnimation 16 | 17 | - (instancetype)initWithIsPresenting:(BOOL)isPresenting 18 | { 19 | if (self = [super init]) { 20 | self.isPresenting = isPresenting; 21 | } 22 | return self; 23 | } 24 | 25 | + (instancetype)alertAnimationIsPresenting:(BOOL)isPresenting 26 | { 27 | return [[self alloc]initWithIsPresenting:isPresenting]; 28 | } 29 | 30 | + (instancetype)alertAnimationIsPresenting:(BOOL)isPresenting preferredStyle:(TYAlertControllerStyle)preferredStyle 31 | { 32 | return [[self alloc]initWithIsPresenting:isPresenting]; 33 | } 34 | 35 | // override this moethod 36 | - (NSTimeInterval)transitionDuration:(id)transitionContext 37 | { 38 | return 0.4; 39 | } 40 | 41 | - (void)animateTransition:(id)transitionContext 42 | { 43 | if (_isPresenting) { 44 | [self presentAnimateTransition:transitionContext]; 45 | }else { 46 | [self dismissAnimateTransition:transitionContext]; 47 | } 48 | } 49 | 50 | - (void)presentAnimateTransition:(id)transitionContext 51 | { 52 | 53 | } 54 | 55 | - (void)dismissAnimateTransition:(id)transitionContext 56 | { 57 | 58 | } 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.tanyang.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/Images.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 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /TYAlertControllerDemo/TYAlertController/UIView+TYAlertView.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+TYAlertView.h 3 | // TYAlertControllerDemo 4 | // 5 | // Created by tanyang on 15/9/7. 6 | // Copyright (c) 2015年 tanyang. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "TYAlertController.h" 11 | #import "TYShowAlertView.h" 12 | 13 | @interface UIView (TYAlertView) 14 | 15 | + (instancetype)createViewFromNib; 16 | 17 | + (instancetype)createViewFromNibName:(NSString *)nibName; 18 | 19 | - (UIViewController*)viewController; 20 | 21 | #pragma mark - show in controller 22 | 23 | - (void)showInController:(UIViewController *)viewController; 24 | 25 | - (void)showInController:(UIViewController *)viewController preferredStyle:(TYAlertControllerStyle)preferredStyle; 26 | 27 | // backgoundTapDismissEnable default NO 28 | - (void)showInController:(UIViewController *)viewController preferredStyle:(TYAlertControllerStyle)preferredStyle backgoundTapDismissEnable:(BOOL)backgoundTapDismissEnable; 29 | 30 | - (void)showInController:(UIViewController *)viewController preferredStyle:(TYAlertControllerStyle)preferredStyle transitionAnimation:(TYAlertTransitionAnimation)transitionAnimation; 31 | 32 | - (void)showInController:(UIViewController *)viewController preferredStyle:(TYAlertControllerStyle)preferredStyle transitionAnimation:(TYAlertTransitionAnimation)transitionAnimation backgoundTapDismissEnable:(BOOL)backgoundTapDismissEnable; 33 | 34 | #pragma mark - show in window 35 | 36 | - (void)showInWindow; 37 | 38 | // backgoundTapDismissEnable default NO 39 | - (void)showInWindowWithBackgoundTapDismissEnable:(BOOL)backgoundTapDismissEnable; 40 | 41 | - (void)showInWindowWithOriginY:(CGFloat)OriginY; 42 | 43 | - (void)showInWindowWithOriginY:(CGFloat)OriginY backgoundTapDismissEnable:(BOOL)backgoundTapDismissEnable; 44 | 45 | 46 | #pragma mark - hide 47 | 48 | // this will judge and call right method 49 | - (void)hideView; 50 | 51 | - (void)hideInController; 52 | 53 | - (void)hideInWindow; 54 | 55 | @end -------------------------------------------------------------------------------- /TYAlertControllerDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // TYAlertControllerDemo 4 | // 5 | // Created by tanyang on 15/9/1. 6 | // Copyright (c) 2015年 tanyang. 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 | - (void)applicationWillResignActive:(UIApplication *)application { 24 | // 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. 25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 26 | } 27 | 28 | - (void)applicationDidEnterBackground:(UIApplication *)application { 29 | // 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. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | - (void)applicationWillEnterForeground:(UIApplication *)application { 34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 35 | } 36 | 37 | - (void)applicationDidBecomeActive:(UIApplication *)application { 38 | // 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. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application { 42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/TYAlertController/TYAlertController+TransitionAnimate.m: -------------------------------------------------------------------------------- 1 | // 2 | // TYAlertController+TransitionAnimate.m 3 | // TYAlertControllerDemo 4 | // 5 | // Created by tanyang on 15/9/1. 6 | // Copyright (c) 2015年 tanyang. All rights reserved. 7 | // 8 | 9 | #import "TYAlertController.h" 10 | #import "TYAlertFadeAnimation.h" 11 | #import "TYAlertScaleFadeAnimation.h" 12 | #import "TYAlertDropDownAnimation.h" 13 | 14 | @implementation TYAlertController (TransitionAnimate) 15 | 16 | #pragma mark - UIViewControllerTransitioningDelegate 17 | 18 | - (id)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source 19 | { 20 | switch (self.transitionAnimation) { 21 | case TYAlertTransitionAnimationFade: 22 | return [TYAlertFadeAnimation alertAnimationIsPresenting:YES]; 23 | case TYAlertTransitionAnimationScaleFade: 24 | return [TYAlertScaleFadeAnimation alertAnimationIsPresenting:YES]; 25 | case TYAlertTransitionAnimationDropDown: 26 | return [TYAlertDropDownAnimation alertAnimationIsPresenting:YES]; 27 | case TYAlertTransitionAnimationCustom: 28 | return [self.transitionAnimationClass alertAnimationIsPresenting:YES preferredStyle:self.preferredStyle]; 29 | default: 30 | return nil; 31 | } 32 | } 33 | 34 | - (id)animationControllerForDismissedController:(UIViewController *)dismissed 35 | { 36 | switch (self.transitionAnimation) { 37 | case TYAlertTransitionAnimationFade: 38 | return [TYAlertFadeAnimation alertAnimationIsPresenting:NO]; 39 | case TYAlertTransitionAnimationScaleFade: 40 | return [TYAlertScaleFadeAnimation alertAnimationIsPresenting:NO]; 41 | case TYAlertTransitionAnimationDropDown: 42 | return [TYAlertDropDownAnimation alertAnimationIsPresenting:NO]; 43 | case TYAlertTransitionAnimationCustom: 44 | return [self.transitionAnimationClass alertAnimationIsPresenting:NO preferredStyle:self.preferredStyle]; 45 | default: 46 | return nil; 47 | } 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/Blur Effects/TYAlertController+BlurEffects.m: -------------------------------------------------------------------------------- 1 | // 2 | // TYAlertController+BlurEffects.m 3 | // TYAlertControllerDemo 4 | // 5 | // Created by tanyang on 15/10/26. 6 | // Copyright © 2015年 tanyang. All rights reserved. 7 | // 8 | 9 | #import "TYAlertController+BlurEffects.h" 10 | #import "UIImage+ImageEffects.h" 11 | 12 | @implementation TYAlertController (BlurEffects) 13 | 14 | #pragma mark - public 15 | 16 | - (void)setBlurEffectWithView:(UIView *)view 17 | { 18 | [self setBlurEffectWithView:view style:BlurEffectStyleLight]; 19 | } 20 | 21 | - (void)setBlurEffectWithView:(UIView *)view style:(BlurEffectStyle)blurStyle 22 | { 23 | // time consuming task ,so use dispatch_async .很耗时的操作 24 | dispatch_async(dispatch_get_global_queue(0, 0), ^{ 25 | // 处理耗时操作的代码块... 26 | UIImage *snapshotImage = [UIImage snapshotImageWithView:view]; 27 | UIImage * blurImage = [self blurImageWithSnapshotImage:snapshotImage style:blurStyle]; 28 | //通知主线程刷新 29 | dispatch_async(dispatch_get_main_queue(), ^{ 30 | UIImageView *blurImageView = [[UIImageView alloc]initWithImage:blurImage]; 31 | self.backgroundView = blurImageView; 32 | }); 33 | 34 | }); 35 | } 36 | 37 | - (void)setBlurEffectWithView:(UIView *)view effectTintColor:(UIColor *)effectTintColor 38 | { 39 | // time consuming task ,so use dispatch_async .很耗时的操作 40 | dispatch_async(dispatch_get_global_queue(0, 0), ^{ 41 | // 处理耗时操作的代码块... 42 | UIImage *snapshotImage = [UIImage snapshotImageWithView:view]; 43 | UIImage * blurImage = [snapshotImage applyTintEffectWithColor:effectTintColor]; 44 | //通知主线程刷新 45 | dispatch_async(dispatch_get_main_queue(), ^{ 46 | UIImageView *blurImageView = [[UIImageView alloc]initWithImage:blurImage]; 47 | self.backgroundView = blurImageView; 48 | }); 49 | 50 | }); 51 | } 52 | 53 | #pragma mark - private 54 | 55 | - (UIImage *)blurImageWithSnapshotImage:(UIImage *)snapshotImage style:(BlurEffectStyle)blurStyle 56 | { 57 | switch (blurStyle) { 58 | case BlurEffectStyleLight: 59 | return [snapshotImage applyLightEffect]; 60 | case BlurEffectStyleDarkEffect: 61 | return [snapshotImage applyDarkEffect]; 62 | case BlurEffectStyleExtraLight: 63 | return [snapshotImage applyExtraLightEffect]; 64 | default: 65 | return nil; 66 | } 67 | } 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/TYAlertController/TYAlertView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TYAlertView.h 3 | // TYAlertControllerDemo 4 | // 5 | // Created by tanyang on 15/9/7. 6 | // Copyright (c) 2015年 tanyang. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSUInteger, TYAlertActionStyle) { 12 | TYAlertActionStyleDefault, 13 | TYAlertActionStyleCancel, 14 | TYAlertActionStyleDestructive, 15 | }; 16 | 17 | @interface TYAlertAction : NSObject 18 | 19 | + (instancetype)actionWithTitle:(NSString *)title style:(TYAlertActionStyle)style handler:(void (^)(TYAlertAction *action))handler; 20 | 21 | @property (nonatomic, readonly) NSString *title; 22 | @property (nonatomic, readonly) TYAlertActionStyle style; 23 | @property (nonatomic, getter=isEnabled) BOOL enabled; 24 | 25 | @end 26 | 27 | 28 | @interface TYAlertView : UIView 29 | 30 | @property (nonatomic, weak, readonly) UILabel *titleLable; 31 | @property (nonatomic, weak, readonly) UILabel *messageLabel; 32 | 33 | // alertView textfield array 34 | @property (nonatomic, strong, readonly) NSArray *textFieldArray; 35 | 36 | // default 280, if 0 don't add width constraint, 37 | @property (nonatomic, assign) CGFloat alertViewWidth; 38 | 39 | // contentView space custom 40 | @property (nonatomic, assign) CGFloat contentViewSpace; 41 | 42 | // textLabel custom 43 | @property (nonatomic, assign) CGFloat textLabelSpace; 44 | @property (nonatomic, assign) CGFloat textLabelContentViewEdge; 45 | 46 | // button custom 47 | @property (nonatomic, assign) CGFloat buttonHeight; 48 | @property (nonatomic, assign) CGFloat buttonSpace; 49 | @property (nonatomic, assign) CGFloat buttonContentViewEdge; 50 | @property (nonatomic, assign) CGFloat buttonContentViewTop; 51 | @property (nonatomic, assign) CGFloat buttonCornerRadius; 52 | @property (nonatomic, strong) UIFont *buttonFont; 53 | @property (nonatomic, strong) UIColor *buttonDefaultBgColor; 54 | @property (nonatomic, strong) UIColor *buttonCancelBgColor; 55 | @property (nonatomic, strong) UIColor *buttonDestructiveBgColor; 56 | 57 | // textField custom 58 | @property (nonatomic, strong) UIColor *textFieldBorderColor; 59 | @property (nonatomic, strong) UIColor *textFieldBackgroudColor; 60 | @property (nonatomic, strong) UIFont *textFieldFont; 61 | @property (nonatomic, assign) CGFloat textFieldHeight; 62 | @property (nonatomic, assign) CGFloat textFieldEdge; 63 | @property (nonatomic, assign) CGFloat textFieldBorderWidth; 64 | @property (nonatomic, assign) CGFloat textFieldContentViewEdge; 65 | 66 | @property (nonatomic, assign) BOOL clickedAutoHide; 67 | 68 | 69 | + (instancetype)alertViewWithTitle:(NSString *)title message:(NSString *)message; 70 | 71 | - (void)addAction:(TYAlertAction *)action; 72 | 73 | - (void)addTextFieldWithConfigurationHandler:(void (^)(UITextField *textField))configurationHandler; 74 | 75 | @end 76 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/TYAlertController/TYAlertDropDownAnimation.m: -------------------------------------------------------------------------------- 1 | // 2 | // TYAlertDropDownAnimation.m 3 | // TYAlertControllerDemo 4 | // 5 | // Created by tanyang on 15/10/27. 6 | // Copyright © 2015年 tanyang. All rights reserved. 7 | // 8 | 9 | #import "TYAlertDropDownAnimation.h" 10 | 11 | @implementation TYAlertDropDownAnimation 12 | 13 | - (NSTimeInterval)transitionDuration:(id)transitionContext 14 | { 15 | if (self.isPresenting) { 16 | return 0.5; 17 | } 18 | return 0.25; 19 | } 20 | 21 | - (void)presentAnimateTransition:(id)transitionContext 22 | { 23 | TYAlertController *alertController = (TYAlertController *)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; 24 | 25 | alertController.backgroundView.alpha = 0.0; 26 | 27 | switch (alertController.preferredStyle) { 28 | case TYAlertControllerStyleAlert: 29 | alertController.alertView.transform = CGAffineTransformMakeTranslation(0, -CGRectGetMaxY(alertController.alertView.frame)); 30 | break; 31 | case TYAlertControllerStyleActionSheet: 32 | NSLog(@"don't support ActionSheet style!"); 33 | break; 34 | default: 35 | break; 36 | } 37 | 38 | UIView *containerView = [transitionContext containerView]; 39 | [containerView addSubview:alertController.view]; 40 | 41 | [UIView animateWithDuration:0.5 delay:0.0 usingSpringWithDamping:0.65 initialSpringVelocity:0.5 options:0 animations:^{ 42 | 43 | alertController.backgroundView.alpha = 1.0; 44 | alertController.alertView.transform = CGAffineTransformIdentity; 45 | 46 | } completion:^(BOOL finished) { 47 | [transitionContext completeTransition:YES]; 48 | }]; 49 | } 50 | 51 | - (void)dismissAnimateTransition:(id)transitionContext 52 | { 53 | TYAlertController *alertController = (TYAlertController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; 54 | 55 | [UIView animateWithDuration:0.25 animations:^{ 56 | alertController.backgroundView.alpha = 0.0; 57 | switch (alertController.preferredStyle) { 58 | case TYAlertControllerStyleAlert: 59 | alertController.alertView.alpha = 0.0; 60 | alertController.alertView.transform = CGAffineTransformMakeScale(0.9, 0.9); 61 | break; 62 | case TYAlertControllerStyleActionSheet: 63 | NSLog(@"don't support ActionSheet style!"); 64 | break; 65 | default: 66 | break; 67 | } 68 | } completion:^(BOOL finished) { 69 | [transitionContext completeTransition:YES]; 70 | }]; 71 | } 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/TYAlertController/TYAlertController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TYAlertController.h 3 | // TYAlertControllerDemo 4 | // 5 | // Created by tanyang on 15/9/1. 6 | // Copyright (c) 2015年 tanyang. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "TYAlertView.h" 11 | 12 | typedef NS_ENUM(NSInteger, TYAlertControllerStyle) { 13 | TYAlertControllerStyleAlert = 0, 14 | TYAlertControllerStyleActionSheet 15 | }; 16 | 17 | typedef NS_ENUM(NSInteger, TYAlertTransitionAnimation) { 18 | TYAlertTransitionAnimationFade = 0, 19 | TYAlertTransitionAnimationScaleFade, 20 | TYAlertTransitionAnimationDropDown, 21 | TYAlertTransitionAnimationCustom 22 | }; 23 | 24 | 25 | @interface TYAlertController : UIViewController 26 | 27 | @property (nonatomic, strong, readonly) UIView *alertView; 28 | 29 | @property (nonatomic, strong) UIColor *backgroundColor; // set backgroundColor 30 | @property (nonatomic, strong) UIView *backgroundView; // you set coustom view to it 31 | 32 | @property (nonatomic, assign, readonly) TYAlertControllerStyle preferredStyle; 33 | 34 | @property (nonatomic, assign, readonly) TYAlertTransitionAnimation transitionAnimation; 35 | 36 | @property (nonatomic, assign, readonly) Class transitionAnimationClass; 37 | 38 | @property (nonatomic, assign) BOOL backgoundTapDismissEnable; // default NO 39 | 40 | @property (nonatomic, assign) CGFloat alertViewOriginY; // default center Y 41 | 42 | @property (nonatomic, assign) CGFloat alertStyleEdging; // when width frame equal to 0,or no width constraint ,this proprty will use, default to 15 edge 43 | @property (nonatomic, assign) CGFloat actionSheetStyleEdging; // default 0 44 | 45 | // alertView lifecycle block 46 | @property (copy, nonatomic) void (^viewWillShowHandler)(UIView *alertView); 47 | @property (copy, nonatomic) void (^viewDidShowHandler)(UIView *alertView); 48 | @property (copy, nonatomic) void (^viewWillHideHandler)(UIView *alertView); 49 | @property (copy, nonatomic) void (^viewDidHideHandler)(UIView *alertView); 50 | 51 | // dismiss controller completed block 52 | @property (nonatomic, copy) void (^dismissComplete)(void); 53 | 54 | + (instancetype)alertControllerWithAlertView:(UIView *)alertView; 55 | 56 | + (instancetype)alertControllerWithAlertView:(UIView *)alertView preferredStyle:(TYAlertControllerStyle)preferredStyle; 57 | 58 | + (instancetype)alertControllerWithAlertView:(UIView *)alertView preferredStyle:(TYAlertControllerStyle)preferredStyle transitionAnimation:(TYAlertTransitionAnimation)transitionAnimation; 59 | 60 | + (instancetype)alertControllerWithAlertView:(UIView *)alertView preferredStyle:(TYAlertControllerStyle)preferredStyle transitionAnimationClass:(Class)transitionAnimationClass; 61 | 62 | - (void)dismissViewControllerAnimated: (BOOL)animated; 63 | 64 | @end 65 | 66 | // Transition Animate 67 | @interface TYAlertController (TransitionAnimate) 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/TYAlertController/TYAlertScaleFadeAnimation.m: -------------------------------------------------------------------------------- 1 | // 2 | // TYAlertScaleFadeAnimation.m 3 | // TYAlertControllerDemo 4 | // 5 | // Created by SunYong on 15/9/2. 6 | // Copyright (c) 2015年 tanyang. All rights reserved. 7 | // 8 | 9 | #import "TYAlertScaleFadeAnimation.h" 10 | 11 | @implementation TYAlertScaleFadeAnimation 12 | 13 | - (NSTimeInterval)transitionDuration:(id)transitionContext 14 | { 15 | return 0.3; 16 | } 17 | 18 | - (void)presentAnimateTransition:(id)transitionContext 19 | { 20 | TYAlertController *alertController = (TYAlertController *)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; 21 | 22 | alertController.backgroundView.alpha = 0.0; 23 | 24 | switch (alertController.preferredStyle) { 25 | case TYAlertControllerStyleAlert: 26 | alertController.alertView.alpha = 0.0; 27 | alertController.alertView.transform = CGAffineTransformMakeScale(0.1, 0.1); 28 | break; 29 | case TYAlertControllerStyleActionSheet: 30 | alertController.alertView.transform = CGAffineTransformMakeTranslation(0, CGRectGetHeight(alertController.alertView.frame)); 31 | break; 32 | default: 33 | break; 34 | } 35 | 36 | UIView *containerView = [transitionContext containerView]; 37 | [containerView addSubview:alertController.view]; 38 | 39 | [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{ 40 | alertController.backgroundView.alpha = 1.0; 41 | switch (alertController.preferredStyle) { 42 | case TYAlertControllerStyleAlert: 43 | alertController.alertView.alpha = 1.0; 44 | alertController.alertView.transform = CGAffineTransformIdentity; 45 | break; 46 | case TYAlertControllerStyleActionSheet: 47 | alertController.alertView.transform = CGAffineTransformIdentity; 48 | break; 49 | default: 50 | break; 51 | } 52 | } completion:^(BOOL finished) { 53 | [transitionContext completeTransition:YES]; 54 | }]; 55 | } 56 | 57 | - (void)dismissAnimateTransition:(id)transitionContext 58 | { 59 | TYAlertController *alertController = (TYAlertController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; 60 | 61 | [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{ 62 | alertController.backgroundView.alpha = 0.0; 63 | switch (alertController.preferredStyle) { 64 | case TYAlertControllerStyleAlert: 65 | alertController.alertView.alpha = 0.0; 66 | alertController.alertView.transform = CGAffineTransformMakeScale(0.1, 0.1); 67 | break; 68 | case TYAlertControllerStyleActionSheet: 69 | alertController.alertView.transform = CGAffineTransformMakeTranslation(0, CGRectGetHeight(alertController.alertView.frame)); 70 | break; 71 | default: 72 | break; 73 | } 74 | } completion:^(BOOL finished) { 75 | [transitionContext completeTransition:YES]; 76 | }]; 77 | } 78 | 79 | @end 80 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/TYAlertController/TYAlertFadeAnimation.m: -------------------------------------------------------------------------------- 1 | // 2 | // TYAlertDefaultAnimation.m 3 | // TYAlertControllerDemo 4 | // 5 | // Created by SunYong on 15/9/1. 6 | // Copyright (c) 2015年 tanyang. All rights reserved. 7 | // 8 | 9 | #import "TYAlertFadeAnimation.h" 10 | 11 | @implementation TYAlertFadeAnimation 12 | 13 | - (NSTimeInterval)transitionDuration:(id)transitionContext 14 | { 15 | if (self.isPresenting) { 16 | return 0.45; 17 | } 18 | return 0.25; 19 | } 20 | 21 | - (void)presentAnimateTransition:(id)transitionContext 22 | { 23 | TYAlertController *alertController = (TYAlertController *)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; 24 | 25 | alertController.backgroundView.alpha = 0.0; 26 | 27 | switch (alertController.preferredStyle) { 28 | case TYAlertControllerStyleAlert: 29 | alertController.alertView.alpha = 0.0; 30 | alertController.alertView.transform = CGAffineTransformMakeScale(0.5, 0.5); 31 | break; 32 | case TYAlertControllerStyleActionSheet: 33 | alertController.alertView.transform = CGAffineTransformMakeTranslation(0, CGRectGetHeight(alertController.alertView.frame)); 34 | break; 35 | default: 36 | break; 37 | } 38 | 39 | UIView *containerView = [transitionContext containerView]; 40 | [containerView addSubview:alertController.view]; 41 | 42 | [UIView animateWithDuration:0.25 animations:^{ 43 | alertController.backgroundView.alpha = 1.0; 44 | switch (alertController.preferredStyle) { 45 | case TYAlertControllerStyleAlert: 46 | alertController.alertView.alpha = 1.0; 47 | alertController.alertView.transform = CGAffineTransformMakeScale(1.05, 1.05); 48 | break; 49 | case TYAlertControllerStyleActionSheet: 50 | alertController.alertView.transform = CGAffineTransformMakeTranslation(0, -10.0); 51 | break; 52 | default: 53 | break; 54 | } 55 | } completion:^(BOOL finished) { 56 | [UIView animateWithDuration:0.2 animations:^{ 57 | alertController.alertView.transform = CGAffineTransformIdentity; 58 | } completion:^(BOOL finished) { 59 | [transitionContext completeTransition:YES]; 60 | }]; 61 | }]; 62 | 63 | } 64 | 65 | - (void)dismissAnimateTransition:(id)transitionContext 66 | { 67 | TYAlertController *alertController = (TYAlertController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; 68 | 69 | [UIView animateWithDuration:0.25 animations:^{ 70 | alertController.backgroundView.alpha = 0.0; 71 | switch (alertController.preferredStyle) { 72 | case TYAlertControllerStyleAlert: 73 | alertController.alertView.alpha = 0.0; 74 | alertController.alertView.transform = CGAffineTransformMakeScale(0.9, 0.9); 75 | break; 76 | case TYAlertControllerStyleActionSheet: 77 | alertController.alertView.transform = CGAffineTransformMakeTranslation(0, CGRectGetHeight(alertController.alertView.frame)); 78 | break; 79 | default: 80 | break; 81 | } 82 | } completion:^(BOOL finished) { 83 | [transitionContext completeTransition:YES]; 84 | }]; 85 | } 86 | 87 | @end 88 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TYAlertController 2 | Powerful, Easy to use alertView or popupView on controller and window, support blur effect, custom view and custom animation, use aotolayout.support iphone, ipad . 3 | 4 | ## CocoaPods 5 | ``` 6 | pod 'TYAlertController' 7 | ``` 8 | 9 | ### ScreenShot 10 | ![image](https://github.com/12207480/TYAlertController/blob/master/screenshot/TYAlertControllerDemo.gif) 11 | 12 | ### Requirements 13 | * Xcode 5 or higher 14 | * iOS 7.0 or higher 15 | * ARC 16 | 17 | ### Usage 18 | 19 | 1.copy TYAlertController Folder to your project, if you want to have blur effect ,you need copy Blur Effects Folder to your project.
20 | 2. #import "UIView+TYAlertView.h", when you use it, if you want use blur effect, #import "TYAlertController+BlurEffects.h".
21 | 3. you can use TYAlertController show in controller, or use TYShowAlertView show in window, or use Category UIView+TYAlertView convenient show alertview.
22 | 4. check Demo,it have more usefull usage and example. 23 | 24 | ### usege demo 25 | 26 | * alertView lifecycle block 27 | ```objc 28 | // alertView lifecycle block 29 | @property (copy, nonatomic) void (^viewWillShowHandler)(UIView *alertView); 30 | @property (copy, nonatomic) void (^viewDidShowHandler)(UIView *alertView); 31 | @property (copy, nonatomic) void (^viewWillHideHandler)(UIView *alertView); 32 | @property (copy, nonatomic) void (^viewDidHideHandler)(UIView *alertView); 33 | 34 | // dismiss controller completed block 35 | @property (nonatomic, copy) void (^dismissComplete)(void); 36 | ``` 37 | 38 | * show in controller (tow way)(recommend) 39 | ```objc 40 | TYAlertView *alertView = [TYAlertView alertViewWithTitle:@"TYAlertView" message:@"This is a message, the alert view containt text and textfiled. "]; 41 | 42 | [alertView addAction:[TYAlertAction actionWithTitle:@"取消" style:TYAlertActionStyleCancle handler:^(TYAlertAction *action) { 43 | NSLog(@"%@",action.title); 44 | }]]; 45 | 46 | [alertView addAction:[TYAlertAction actionWithTitle:@"确定" style:TYAlertActionStyleDestructive handler:^(TYAlertAction *action) { 47 | NSLog(@"%@",action.title); 48 | }]]; 49 | 50 | [alertView addTextFieldWithConfigurationHandler:^(UITextField *textField) { 51 | textField.placeholder = @"请输入账号"; 52 | }]; 53 | [alertView addTextFieldWithConfigurationHandler:^(UITextField *textField) { 54 | textField.placeholder = @"请输入密码"; 55 | }]; 56 | 57 | // first way to show 58 | TYAlertController *alertController = [TYAlertController alertControllerWithAlertView:alertView preferredStyle:TYAlertControllerStyleAlert]; 59 | //alertController.alertViewOriginY = 60; 60 | [self presentViewController:alertController animated:YES completion:nil]; 61 | 62 | // second way to show,use UIView Category 63 | //[alertView showInController:self preferredStyle:TYAlertControllerStyleAlert]; 64 | ``` 65 | 66 | * show in window (tow way) 67 | ```objc 68 | TYAlertView *alertView = [TYAlertView alertViewWithTitle:@"TYAlertView" message:@"A message should be a short, but it can support long message"]; 69 | 70 | [alertView addAction:[TYAlertAction actionWithTitle:@"取消" style:TYAlertActionStyleCancle handler:^(TYAlertAction *action) { 71 | NSLog(@"%@",action.title); 72 | }]]; 73 | 74 | [alertView addAction:[TYAlertAction actionWithTitle:@"确定" style:TYAlertActionStyleDestructive handler:^(TYAlertAction *action) { 75 | NSLog(@"%@",action.title); 76 | }]]; 77 | 78 | // first way to show ,use UIView Category 79 | [alertView showInWindowWithOriginY:200 backgoundTapDismissEnable:YES]; 80 | 81 | // second way to show 82 | // [TYShowAlertView showAlertViewWithView:alertView originY:200 backgoundTapDismissEnable:YES]; 83 | ``` 84 | 85 | ### Contact 86 | if you find bug,please pull reqeust me
87 | 88 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /TYAlertControllerDemo.xcodeproj/xcuserdata/tanyang.xcuserdatad/xcschemes/TYAlertControllerDemo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /TYAlertControllerDemo.xcodeproj/xcuserdata/233wangxiao.xcuserdatad/xcschemes/TYAlertControllerDemo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 75 | 77 | 83 | 84 | 85 | 86 | 87 | 88 | 94 | 96 | 102 | 103 | 104 | 105 | 107 | 108 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/TYAlertController/UIView+TYAlertView.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+TYAlertView.m 3 | // TYAlertControllerDemo 4 | // 5 | // Created by tanyang on 15/9/7. 6 | // Copyright (c) 2015年 tanyang. All rights reserved. 7 | // 8 | 9 | #import "UIView+TYAlertView.h" 10 | 11 | @implementation UIView (TYAlertView) 12 | 13 | + (instancetype)createViewFromNibName:(NSString *)nibName 14 | { 15 | NSArray *nib = [[NSBundle mainBundle] loadNibNamed:nibName owner:self options:nil]; 16 | return [nib objectAtIndex:0]; 17 | } 18 | 19 | + (instancetype)createViewFromNib 20 | { 21 | return [self createViewFromNibName:NSStringFromClass(self.class)]; 22 | } 23 | 24 | - (UIViewController*)viewController 25 | { 26 | for (UIView* next = [self superview]; next; next = next.superview) { 27 | UIResponder* nextResponder = [next nextResponder]; 28 | if ([nextResponder isKindOfClass:[UIViewController class]]) { 29 | return (UIViewController*)nextResponder; 30 | } 31 | } 32 | return nil; 33 | } 34 | 35 | #pragma mark - show in window 36 | 37 | - (void)showInWindow 38 | { 39 | [self showInWindowWithBackgoundTapDismissEnable:NO]; 40 | } 41 | 42 | - (void)showInWindowWithBackgoundTapDismissEnable:(BOOL)backgoundTapDismissEnable 43 | { 44 | if (self.superview) { 45 | [self removeFromSuperview]; 46 | } 47 | [TYShowAlertView showAlertViewWithView:self backgoundTapDismissEnable:backgoundTapDismissEnable]; 48 | } 49 | 50 | - (void)showInWindowWithOriginY:(CGFloat)OriginY 51 | { 52 | [self showInWindowWithOriginY:OriginY backgoundTapDismissEnable:NO]; 53 | } 54 | 55 | - (void)showInWindowWithOriginY:(CGFloat)OriginY backgoundTapDismissEnable:(BOOL)backgoundTapDismissEnable 56 | { 57 | if (self.superview) { 58 | [self removeFromSuperview]; 59 | } 60 | [TYShowAlertView showAlertViewWithView:self originY:OriginY backgoundTapDismissEnable:backgoundTapDismissEnable]; 61 | } 62 | 63 | - (void)hideInWindow 64 | { 65 | if ([self isShowInWindow]) { 66 | [(TYShowAlertView *)self.superview hide]; 67 | }else { 68 | NSLog(@"self.superview is nil, or isn't TYShowAlertView"); 69 | } 70 | } 71 | 72 | #pragma mark - show in controller 73 | 74 | - (void)showInController:(UIViewController *)viewController 75 | { 76 | [self showInController:viewController preferredStyle:TYAlertControllerStyleAlert transitionAnimation:TYAlertTransitionAnimationFade]; 77 | } 78 | 79 | - (void)showInController:(UIViewController *)viewController preferredStyle:(TYAlertControllerStyle)preferredStyle 80 | { 81 | [self showInController:viewController preferredStyle:preferredStyle transitionAnimation:TYAlertTransitionAnimationFade]; 82 | } 83 | 84 | - (void)showInController:(UIViewController *)viewController preferredStyle:(TYAlertControllerStyle)preferredStyle backgoundTapDismissEnable:(BOOL)backgoundTapDismissEnable 85 | { 86 | [self showInController:viewController preferredStyle:preferredStyle transitionAnimation:TYAlertTransitionAnimationFade backgoundTapDismissEnable:backgoundTapDismissEnable]; 87 | } 88 | 89 | - (void)showInController:(UIViewController *)viewController preferredStyle:(TYAlertControllerStyle)preferredStyle transitionAnimation:(TYAlertTransitionAnimation)transitionAnimation 90 | { 91 | [self showInController:viewController preferredStyle:preferredStyle transitionAnimation:transitionAnimation backgoundTapDismissEnable:NO]; 92 | } 93 | 94 | - (void)showInController:(UIViewController *)viewController preferredStyle:(TYAlertControllerStyle)preferredStyle transitionAnimation:(TYAlertTransitionAnimation)transitionAnimation backgoundTapDismissEnable:(BOOL)backgoundTapDismissEnable 95 | { 96 | if (self.superview) { 97 | [self removeFromSuperview]; 98 | } 99 | 100 | TYAlertController *alertController = [TYAlertController alertControllerWithAlertView:self preferredStyle:preferredStyle transitionAnimation:transitionAnimation]; 101 | alertController.backgoundTapDismissEnable = backgoundTapDismissEnable; 102 | [viewController presentViewController:alertController animated:YES completion:nil]; 103 | } 104 | 105 | - (void)hideInController 106 | { 107 | if ([self isShowInAlertController]) { 108 | [(TYAlertController *)self.viewController dismissViewControllerAnimated:YES]; 109 | }else { 110 | NSLog(@"self.viewController is nil, or isn't TYAlertController"); 111 | } 112 | } 113 | 114 | #pragma mark - hide 115 | 116 | - (BOOL)isShowInAlertController 117 | { 118 | UIViewController *viewController = self.viewController; 119 | if (viewController && [viewController isKindOfClass:[TYAlertController class]]) { 120 | return YES; 121 | } 122 | return NO; 123 | 124 | } 125 | 126 | - (BOOL)isShowInWindow 127 | { 128 | if (self.superview && [self.superview isKindOfClass:[TYShowAlertView class]]) { 129 | return YES; 130 | } 131 | return NO; 132 | } 133 | 134 | - (void)hideView 135 | { 136 | if ([self isShowInAlertController]) { 137 | [self hideInController]; 138 | }else if ([self isShowInWindow]) { 139 | [self hideInWindow]; 140 | }else { 141 | NSLog(@"self.viewController is nil, or isn't TYAlertController,or self.superview is nil, or isn't TYShowAlertView"); 142 | } 143 | } 144 | 145 | @end 146 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/TYAlertController/UIView+TYAutoLayout.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+TYAutoLayout.m 3 | // TYAlertControllerDemo 4 | // 5 | // Created by SunYong on 15/9/8. 6 | // Copyright (c) 2015年 tanyang. All rights reserved. 7 | // 8 | 9 | #import "UIView+TYAutoLayout.h" 10 | 11 | @implementation UIView (TYAutoLayout) 12 | 13 | - (void)addConstraintToView:(UIView *)view edgeInset:(UIEdgeInsets)edgeInset 14 | { 15 | [self addConstraintWithView:view topView:self leftView:self bottomView:self rightView:self edgeInset:edgeInset]; 16 | } 17 | 18 | - (void)addConstraintWithView:(UIView *)view topView:(UIView *)topView leftView:(UIView *)leftView 19 | bottomView:(UIView *)bottomView rightView:(UIView *)rightView edgeInset:(UIEdgeInsets)edgeInset 20 | { 21 | if (topView) { 22 | [self addConstraint:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:topView attribute:NSLayoutAttributeTop multiplier:1 constant:edgeInset.top]]; 23 | } 24 | 25 | if (leftView) { 26 | [self addConstraint:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:leftView attribute:NSLayoutAttributeLeft multiplier:1 constant:edgeInset.left]]; 27 | } 28 | 29 | if (rightView) { 30 | [self addConstraint:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:rightView attribute:NSLayoutAttributeRight multiplier:1 constant:edgeInset.right]]; 31 | } 32 | 33 | if (bottomView) { 34 | [self addConstraint:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:bottomView attribute:NSLayoutAttributeBottom multiplier:1 constant:edgeInset.bottom]]; 35 | } 36 | } 37 | 38 | - (void)addConstraintWithLeftView:(UIView *)leftView toRightView:(UIView *)rightView constant:(CGFloat)constant 39 | { 40 | [self addConstraint:[NSLayoutConstraint constraintWithItem:leftView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:rightView attribute:NSLayoutAttributeLeft multiplier:1 constant:-constant]]; 41 | } 42 | 43 | - (NSLayoutConstraint *)addConstraintWithTopView:(UIView *)topView toBottomView:(UIView *)bottomView constant:(CGFloat)constant 44 | { 45 | NSLayoutConstraint *topBottomConstraint =[NSLayoutConstraint constraintWithItem:topView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:bottomView attribute:NSLayoutAttributeTop multiplier:1 constant:-constant]; 46 | [self addConstraint:topBottomConstraint]; 47 | return topBottomConstraint; 48 | } 49 | 50 | - (void)addConstraintWidth:(CGFloat)width height:(CGFloat)height 51 | { 52 | if (width > 0) { 53 | [self addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:1 constant:width]]; 54 | } 55 | 56 | if (height > 0) { 57 | [self addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:1 constant:height]]; 58 | } 59 | } 60 | 61 | - (void)addConstraintEqualWithView:(UIView *)view widthToView:(UIView *)wView heightToView:(UIView *)hView 62 | { 63 | if (wView) { 64 | [self addConstraint:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:wView attribute:NSLayoutAttributeWidth multiplier:1 constant:0]]; 65 | } 66 | 67 | if (hView) { 68 | [self addConstraint:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:hView attribute:NSLayoutAttributeHeight multiplier:1 constant:0]]; 69 | } 70 | } 71 | 72 | - (void)addConstraintCenterXToView:(UIView *)xView centerYToView:(UIView *)yView 73 | { 74 | if (xView) { 75 | [self addConstraint:[NSLayoutConstraint constraintWithItem:xView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0]]; 76 | } 77 | 78 | if (yView) { 79 | [self addConstraint:[NSLayoutConstraint constraintWithItem:yView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0]]; 80 | } 81 | } 82 | 83 | - (NSLayoutConstraint *)addConstraintCenterYToView:(UIView *)yView constant:(CGFloat)constant; 84 | { 85 | if (yView) { 86 | NSLayoutConstraint *centerYConstraint = [NSLayoutConstraint constraintWithItem:yView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:constant]; 87 | [self addConstraint:centerYConstraint]; 88 | return centerYConstraint; 89 | } 90 | return nil; 91 | } 92 | 93 | - (void)removeConstraintWithAttribte:(NSLayoutAttribute)attr 94 | { 95 | for (NSLayoutConstraint *constraint in self.constraints) { 96 | if (constraint.firstAttribute == attr) { 97 | [self removeConstraint:constraint]; 98 | break; 99 | } 100 | } 101 | } 102 | 103 | - (void)removeConstraintWithView:(UIView *)view attribute:(NSLayoutAttribute)attr 104 | { 105 | for (NSLayoutConstraint *constraint in self.constraints) { 106 | if (constraint.firstAttribute == attr && constraint.firstItem == view) { 107 | [self removeConstraint:constraint]; 108 | break; 109 | } 110 | } 111 | } 112 | 113 | - (void)removeAllConstraints 114 | { 115 | [self removeConstraints:self.constraints]; 116 | } 117 | 118 | @end 119 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/TYAlertController/TYShowAlertView.m: -------------------------------------------------------------------------------- 1 | // 2 | // TYShowAlertView.m 3 | // TYAlertControllerDemo 4 | // 5 | // Created by tanyang on 15/3/16. 6 | // Copyright (c) 2015年 mark. All rights reserved. 7 | // 8 | 9 | #import "TYShowAlertView.h" 10 | #import "UIView+TYAutoLayout.h" 11 | 12 | @interface TYShowAlertView () 13 | @property (nonatomic, weak) UIView *alertView; 14 | @property (nonatomic, weak) UITapGestureRecognizer *singleTap; 15 | @end 16 | 17 | //current window 18 | #define kCurrentWindow [UIApplication sharedApplication].keyWindow 19 | 20 | @implementation TYShowAlertView 21 | 22 | - (instancetype)initWithFrame:(CGRect)frame 23 | { 24 | if (self = [super initWithFrame:frame]) { 25 | self.backgroundColor = [UIColor clearColor]; 26 | 27 | _backgoundTapDismissEnable = NO; 28 | _alertViewEdging = 15; 29 | 30 | [self addBackgroundView]; 31 | 32 | [self addSingleGesture]; 33 | } 34 | return self; 35 | } 36 | 37 | - (instancetype)initWithAlertView:(UIView *)tipView 38 | { 39 | if (self = [self initWithFrame:CGRectZero]) { 40 | 41 | [self addSubview:tipView]; 42 | _alertView = tipView; 43 | } 44 | return self; 45 | } 46 | 47 | + (instancetype)alertViewWithView:(UIView *)tipView 48 | { 49 | return [[self alloc]initWithAlertView:tipView]; 50 | } 51 | 52 | + (void)showAlertViewWithView:(UIView *)alertView 53 | { 54 | [self showAlertViewWithView:alertView backgoundTapDismissEnable:NO]; 55 | } 56 | 57 | + (void)showAlertViewWithView:(UIView *)alertView backgoundTapDismissEnable:(BOOL)backgoundTapDismissEnable 58 | { 59 | TYShowAlertView *showTipView = [self alertViewWithView:alertView]; 60 | showTipView.backgoundTapDismissEnable = backgoundTapDismissEnable; 61 | [showTipView show]; 62 | } 63 | 64 | + (void)showAlertViewWithView:(UIView *)alertView originY:(CGFloat)originY 65 | { 66 | [self showAlertViewWithView:alertView 67 | originY:originY backgoundTapDismissEnable:NO]; 68 | } 69 | 70 | + (void)showAlertViewWithView:(UIView *)alertView originY:(CGFloat)originY backgoundTapDismissEnable:(BOOL)backgoundTapDismissEnable 71 | { 72 | TYShowAlertView *showTipView = [self alertViewWithView:alertView]; 73 | showTipView.alertViewOriginY = originY; 74 | showTipView.backgoundTapDismissEnable = backgoundTapDismissEnable; 75 | [showTipView show]; 76 | } 77 | 78 | - (void)addBackgroundView 79 | { 80 | if (_backgroundView == nil) { 81 | UIView *backgroundView = [[UIView alloc]initWithFrame:self.bounds]; 82 | backgroundView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.4]; 83 | _backgroundView = backgroundView; 84 | } 85 | [self insertSubview:_backgroundView atIndex:0]; 86 | _backgroundView.translatesAutoresizingMaskIntoConstraints = NO; 87 | [self addConstraintToView:_backgroundView edgeInset:UIEdgeInsetsZero]; 88 | } 89 | 90 | - (void)setBackgroundView:(UIView *)backgroundView 91 | { 92 | if (_backgroundView != backgroundView) { 93 | [_backgroundView removeFromSuperview]; 94 | _backgroundView = backgroundView; 95 | [self addBackgroundView]; 96 | [self addSingleGesture]; 97 | } 98 | } 99 | - (void)setBackgoundTapDismissEnable:(BOOL)backgoundTapDismissEnable 100 | { 101 | _backgoundTapDismissEnable = backgoundTapDismissEnable; 102 | _singleTap.enabled = backgoundTapDismissEnable; 103 | } 104 | 105 | - (void)didMoveToSuperview 106 | { 107 | if (self.superview) { 108 | self.translatesAutoresizingMaskIntoConstraints = NO; 109 | [self.superview addConstraintToView:self edgeInset:UIEdgeInsetsZero]; 110 | [self layoutAlertView]; 111 | } 112 | } 113 | 114 | - (void)layoutAlertView 115 | { 116 | _alertView.translatesAutoresizingMaskIntoConstraints = NO; 117 | // center X 118 | [self addConstraintCenterXToView:_alertView centerYToView:nil]; 119 | 120 | // width, height 121 | if (!CGSizeEqualToSize(_alertView.frame.size,CGSizeZero)) { 122 | [_alertView addConstraintWidth:CGRectGetWidth(_alertView.frame) height:CGRectGetHeight(_alertView.frame)]; 123 | 124 | }else { 125 | BOOL findAlertViewWidthConstraint = NO; 126 | for (NSLayoutConstraint *constraint in _alertView.constraints) { 127 | if (constraint.firstAttribute == NSLayoutAttributeWidth) { 128 | findAlertViewWidthConstraint = YES; 129 | break; 130 | } 131 | } 132 | 133 | if (!findAlertViewWidthConstraint) { 134 | [_alertView addConstraintWidth:CGRectGetWidth(self.superview.frame)-2*_alertViewEdging height:0]; 135 | } 136 | } 137 | 138 | // topY 139 | NSLayoutConstraint *alertViewCenterYConstraint = [self addConstraintCenterYToView:_alertView constant:0]; 140 | 141 | if (_alertViewOriginY > 0) { 142 | [_alertView layoutIfNeeded]; 143 | alertViewCenterYConstraint.constant = _alertViewOriginY - (CGRectGetHeight(self.superview.frame) - CGRectGetHeight(_alertView.frame))/2; 144 | } 145 | } 146 | 147 | #pragma mark - add Gesture 148 | - (void)addSingleGesture 149 | { 150 | self.userInteractionEnabled = YES; 151 | //单指单击 152 | UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTap:)]; 153 | singleTap.enabled = _backgoundTapDismissEnable; 154 | //增加事件者响应者, 155 | [_backgroundView addGestureRecognizer:singleTap]; 156 | _singleTap = singleTap; 157 | } 158 | 159 | #pragma mark 手指点击事件 160 | - (void)singleTap:(UITapGestureRecognizer *)sender 161 | { 162 | [self hide]; 163 | } 164 | 165 | - (void)show 166 | { 167 | if (self.superview == nil) { 168 | [kCurrentWindow addSubview:self]; 169 | } 170 | self.alpha = 0; 171 | _alertView.transform = CGAffineTransformScale(_alertView.transform,0.1,0.1); 172 | [UIView animateWithDuration:0.3 animations:^{ 173 | _alertView.transform = CGAffineTransformIdentity; 174 | self.alpha = 1; 175 | }]; 176 | 177 | } 178 | 179 | - (void)hide 180 | { 181 | if (self.superview) { 182 | [UIView animateWithDuration:0.3 animations:^{ 183 | _alertView.transform = CGAffineTransformScale(_alertView.transform,0.1,0.1); 184 | self.alpha = 0; 185 | } completion:^(BOOL finished) { 186 | [self removeFromSuperview]; 187 | }]; 188 | } 189 | } 190 | 191 | - (void)dealloc 192 | { 193 | NSLog(@"%@ dealloc",NSStringFromClass([self class])); 194 | } 195 | 196 | @end 197 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // TYAlertControllerDemo 4 | // 5 | // Created by tanyang on 15/9/1. 6 | // Copyright (c) 2015年 tanyang. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | // contain this header 11 | #import "UIView+TYAlertView.h" 12 | // if you want blur efffect contain this 13 | #import "TYAlertController+BlurEffects.h" 14 | 15 | #import "SettingModelView.h" 16 | #import "ShareView.h" 17 | 18 | @interface ViewController () 19 | @end 20 | 21 | @implementation ViewController 22 | 23 | - (void)viewDidLoad { 24 | [super viewDidLoad]; 25 | // Do any additional setup after loading the view, typically from a nib. 26 | 27 | } 28 | 29 | 30 | - (IBAction)showAlertViewAction:(id)sender { 31 | 32 | TYAlertView *alertView = [TYAlertView alertViewWithTitle:@"TYAlertView" message:@"This is a message, the alert view containt text and textfiled. "]; 33 | 34 | [alertView addAction:[TYAlertAction actionWithTitle:@"取消" style:TYAlertActionStyleCancel handler:^(TYAlertAction *action) { 35 | NSLog(@"%@",action.title); 36 | }]]; 37 | 38 | // 弱引用alertView 否则 会循环引用 39 | __typeof (alertView) __weak weakAlertView = alertView; 40 | [alertView addAction:[TYAlertAction actionWithTitle:@"确定" style:TYAlertActionStyleDestructive handler:^(TYAlertAction *action) { 41 | 42 | NSLog(@"%@",action.title); 43 | for (UITextField *textField in weakAlertView.textFieldArray) { 44 | NSLog(@"%@",textField.text); 45 | } 46 | }]]; 47 | 48 | [alertView addTextFieldWithConfigurationHandler:^(UITextField *textField) { 49 | textField.placeholder = @"请输入账号"; 50 | }]; 51 | [alertView addTextFieldWithConfigurationHandler:^(UITextField *textField) { 52 | textField.placeholder = @"请输入密码"; 53 | }]; 54 | 55 | // first way to show 56 | TYAlertController *alertController = [TYAlertController alertControllerWithAlertView:alertView preferredStyle:TYAlertControllerStyleAlert]; 57 | 58 | [alertController setViewWillShowHandler:^(UIView *alertView) { 59 | NSLog(@"ViewWillShow"); 60 | }]; 61 | 62 | [alertController setViewDidShowHandler:^(UIView *alertView) { 63 | NSLog(@"ViewDidShow"); 64 | }]; 65 | 66 | [alertController setViewWillHideHandler:^(UIView *alertView) { 67 | NSLog(@"ViewWillHide"); 68 | }]; 69 | 70 | [alertController setViewDidHideHandler:^(UIView *alertView) { 71 | NSLog(@"ViewDidHide"); 72 | }]; 73 | 74 | [alertController setDismissComplete:^{ 75 | NSLog(@"DismissComplete"); 76 | }]; 77 | 78 | //alertController.alertViewOriginY = 60; 79 | [self presentViewController:alertController animated:YES completion:nil]; 80 | 81 | // second way ,use UIView Category 82 | //[alertView showInController:self preferredStyle:TYAlertControllerStyleAlert]; 83 | 84 | } 85 | - (IBAction)showActionSheetAction:(id)sender { 86 | 87 | TYAlertView *alertView = [TYAlertView alertViewWithTitle:@"TYAlertView" message:@"This is a message, the alert view style is actionsheet. "]; 88 | 89 | [alertView addAction:[TYAlertAction actionWithTitle:@"默认2" style:TYAlertActionStyleDefault handler:^(TYAlertAction *action) { 90 | NSLog(@"%@",action.title); 91 | }]]; 92 | 93 | [alertView addAction:[TYAlertAction actionWithTitle:@"默认1" style:TYAlertActionStyleDefault handler:^(TYAlertAction *action) { 94 | NSLog(@"%@",action.title); 95 | }]]; 96 | 97 | [alertView addAction:[TYAlertAction actionWithTitle:@"删除" style:TYAlertActionStyleDestructive handler:^(TYAlertAction *action) { 98 | NSLog(@"%@",action.title); 99 | }]]; 100 | [alertView addAction:[TYAlertAction actionWithTitle:@"取消" style:TYAlertActionStyleCancel handler:^(TYAlertAction *action) { 101 | NSLog(@"%@",action.title); 102 | }]]; 103 | 104 | TYAlertController *alertController = [TYAlertController alertControllerWithAlertView:alertView preferredStyle:TYAlertControllerStyleActionSheet]; 105 | [self presentViewController:alertController animated:YES completion:nil]; 106 | } 107 | 108 | - (IBAction)blurEffectAlertViewAction:(id)sender { 109 | ShareView *shareView = [ShareView createViewFromNib]; 110 | 111 | TYAlertController *alertController = [TYAlertController alertControllerWithAlertView:shareView preferredStyle:TYAlertControllerStyleAlert]; 112 | 113 | // blur effect 114 | [alertController setBlurEffectWithView:self.view]; 115 | 116 | //alertController.alertViewOriginY = 60; 117 | [self presentViewController:alertController animated:YES completion:nil]; 118 | } 119 | 120 | - (IBAction)dropdwonAnimationAction:(id)sender { 121 | TYAlertView *alertView = [TYAlertView alertViewWithTitle:@"TYAlertView" message:@"This is a message, the alert view containt dropdwon animation. "]; 122 | 123 | [alertView addAction:[TYAlertAction actionWithTitle:@"取消" style:TYAlertActionStyleCancel handler:^(TYAlertAction *action) { 124 | NSLog(@"%@",action.title); 125 | }]]; 126 | 127 | TYAlertController *alertController = [TYAlertController alertControllerWithAlertView:alertView preferredStyle:TYAlertControllerStyleAlert transitionAnimation:TYAlertTransitionAnimationDropDown]; 128 | [self presentViewController:alertController animated:YES completion:nil]; 129 | 130 | // or show,use UIView Category 131 | //[alertView showInController:self preferredStyle:TYAlertControllerStyleAlert]; 132 | } 133 | 134 | - (IBAction)costomActonSheetAction:(id)sender { 135 | // customview from xib 136 | SettingModelView *settingModelView = [SettingModelView createViewFromNib]; 137 | 138 | // fisrt way to show ,use UIView Category 139 | // [settingModelView showInController:self preferredStyle:TYAlertControllerStyleActionSheet backgoundTapDismissEnable:YES]; 140 | 141 | // second way to show 142 | TYAlertController *alertController = [TYAlertController alertControllerWithAlertView:settingModelView preferredStyle:TYAlertControllerStyleActionSheet]; 143 | alertController.backgoundTapDismissEnable = YES; 144 | [self presentViewController:alertController animated:YES completion:nil]; 145 | } 146 | 147 | 148 | - (IBAction)showAlertViewInWindowAction:(id)sender { 149 | 150 | TYAlertView *alertView = [TYAlertView alertViewWithTitle:@"TYAlertView" message:@"A message should be a short, but it can support long message, hahahhahahahahhahahahahhaahahhahahahahahhahahahahhahahahahahhahahahahahhahahahhahahhahahahahh. (NSTextAlignmentCenter)"]; 151 | 152 | [alertView addAction:[TYAlertAction actionWithTitle:@"取消" style:TYAlertActionStyleCancel handler:^(TYAlertAction *action) { 153 | 154 | }]]; 155 | 156 | [alertView addAction:[TYAlertAction actionWithTitle:@"确定" style:TYAlertActionStyleDestructive handler:^(TYAlertAction *action) { 157 | 158 | }]]; 159 | 160 | // first way to show ,use UIView Category 161 | [alertView showInWindowWithOriginY:200 backgoundTapDismissEnable:YES]; 162 | 163 | // second way to show 164 | //[TYShowAlertView showAlertViewWithView:alertView originY:200 backgoundTapDismissEnable:YES]; 165 | } 166 | 167 | - (IBAction)customViewInWindowAction:(id)sender { 168 | ShareView *shareView = [ShareView createViewFromNib]; 169 | 170 | // use UIView Category 171 | [shareView showInWindow]; 172 | } 173 | 174 | - (void)didReceiveMemoryWarning { 175 | [super didReceiveMemoryWarning]; 176 | // Dispose of any resources that can be recreated. 177 | } 178 | 179 | @end 180 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/SettingModelView.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 21 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/ShareView.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 23 | 29 | 39 | 40 | 41 | 42 | 43 | 53 | 54 | 55 | 56 | 57 | 67 | 77 | 86 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/TYAlertController/TYAlertController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TYAlertController.m 3 | // TYAlertControllerDemo 4 | // 5 | // Created by tanyang on 15/9/1. 6 | // Copyright (c) 2015年 tanyang. All rights reserved. 7 | // 8 | 9 | #import "TYAlertController.h" 10 | #import "UIView+TYAutoLayout.h" 11 | 12 | @interface TYAlertController () 13 | 14 | @property (nonatomic, strong) UIView *alertView; 15 | 16 | @property (nonatomic, assign) TYAlertControllerStyle preferredStyle; 17 | 18 | @property (nonatomic, assign) TYAlertTransitionAnimation transitionAnimation; 19 | 20 | @property (nonatomic, assign) Class transitionAnimationClass; 21 | 22 | @property (nonatomic, weak) UITapGestureRecognizer *singleTap; 23 | 24 | @property (nonatomic, strong) NSLayoutConstraint *alertViewCenterYConstraint; 25 | 26 | @property (nonatomic, assign) CGFloat alertViewCenterYOffset; 27 | 28 | @end 29 | 30 | @implementation TYAlertController 31 | 32 | #pragma mark - init 33 | 34 | - (instancetype)init 35 | { 36 | if (self = [super init]) { 37 | [self configureController]; 38 | } 39 | return self; 40 | } 41 | 42 | - (id)initWithCoder:(NSCoder *)aDecoder 43 | { 44 | if (self = [super initWithCoder:aDecoder]) { 45 | [self configureController]; 46 | } 47 | return self; 48 | } 49 | 50 | - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 51 | { 52 | if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { 53 | [self configureController]; 54 | } 55 | return self; 56 | } 57 | 58 | - (instancetype)initWithAlertView:(UIView *)alertView preferredStyle:(TYAlertControllerStyle)preferredStyle transitionAnimation:(TYAlertTransitionAnimation)transitionAnimation transitionAnimationClass:(Class)transitionAnimationClass 59 | { 60 | if (self = [self initWithNibName:nil bundle:nil]) { 61 | _alertView = alertView; 62 | _preferredStyle = preferredStyle; 63 | _transitionAnimation = transitionAnimation; 64 | _transitionAnimationClass = transitionAnimationClass; 65 | } 66 | return self; 67 | } 68 | 69 | + (instancetype)alertControllerWithAlertView:(UIView *)alertView 70 | { 71 | return [[self alloc]initWithAlertView:alertView 72 | preferredStyle:TYAlertControllerStyleAlert 73 | transitionAnimation:TYAlertTransitionAnimationFade 74 | transitionAnimationClass:nil]; 75 | } 76 | 77 | + (instancetype)alertControllerWithAlertView:(UIView *)alertView preferredStyle:(TYAlertControllerStyle)preferredStyle 78 | { 79 | return [[self alloc]initWithAlertView:alertView 80 | preferredStyle:preferredStyle 81 | transitionAnimation:TYAlertTransitionAnimationFade 82 | transitionAnimationClass:nil]; 83 | } 84 | 85 | + (instancetype)alertControllerWithAlertView:(UIView *)alertView preferredStyle:(TYAlertControllerStyle)preferredStyle transitionAnimation:(TYAlertTransitionAnimation)transitionAnimation 86 | { 87 | return [[self alloc]initWithAlertView:alertView 88 | preferredStyle:preferredStyle 89 | transitionAnimation:transitionAnimation 90 | transitionAnimationClass:nil]; 91 | } 92 | 93 | + (instancetype)alertControllerWithAlertView:(UIView *)alertView preferredStyle:(TYAlertControllerStyle)preferredStyle transitionAnimationClass:(Class)transitionAnimationClass 94 | { 95 | return [[self alloc]initWithAlertView:alertView 96 | preferredStyle:preferredStyle 97 | transitionAnimation:TYAlertTransitionAnimationCustom 98 | transitionAnimationClass:transitionAnimationClass]; 99 | } 100 | 101 | #pragma mark - life cycle 102 | 103 | - (void)viewDidLoad { 104 | [super viewDidLoad]; 105 | // Do any additional setup after loading the view. 106 | self.view.backgroundColor = [UIColor clearColor]; 107 | 108 | [self addBackgroundView]; 109 | 110 | [self addSingleTapGesture]; 111 | 112 | [self configureAlertView]; 113 | 114 | [self.view layoutIfNeeded]; 115 | 116 | if (_preferredStyle == TYAlertControllerStyleAlert) { 117 | // UIKeyboard Notification 118 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; 119 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; 120 | } 121 | 122 | } 123 | 124 | - (void)viewWillAppear:(BOOL)animated 125 | { 126 | [super viewWillAppear:animated]; 127 | 128 | if (_viewWillShowHandler) { 129 | _viewWillShowHandler(_alertView); 130 | } 131 | } 132 | 133 | - (void)viewDidAppear:(BOOL)animated 134 | { 135 | [super viewDidAppear:animated]; 136 | 137 | if (_viewDidShowHandler) { 138 | _viewDidShowHandler(_alertView); 139 | } 140 | } 141 | 142 | - (void)viewWillDisappear:(BOOL)animated 143 | { 144 | [super viewWillDisappear:animated]; 145 | 146 | if (_viewWillHideHandler) { 147 | _viewWillHideHandler(_alertView); 148 | } 149 | } 150 | 151 | - (void)viewDidDisappear:(BOOL)animated 152 | { 153 | [super viewDidDisappear:animated]; 154 | 155 | if (_viewDidHideHandler) { 156 | _viewDidHideHandler(_alertView); 157 | } 158 | } 159 | 160 | - (void)addBackgroundView 161 | { 162 | if (_backgroundView == nil) { 163 | UIView *backgroundView = [[UIView alloc]init]; 164 | backgroundView.backgroundColor = _backgroundColor; 165 | _backgroundView = backgroundView; 166 | } 167 | _backgroundView.translatesAutoresizingMaskIntoConstraints = NO; 168 | [self.view insertSubview:_backgroundView atIndex:0]; 169 | [self.view addConstraintToView:_backgroundView edgeInset:UIEdgeInsetsZero]; 170 | } 171 | 172 | - (void)setBackgroundView:(UIView *)backgroundView 173 | { 174 | if (_backgroundView == nil) { 175 | _backgroundView = backgroundView; 176 | } else if (_backgroundView != backgroundView) { 177 | backgroundView.translatesAutoresizingMaskIntoConstraints = NO; 178 | [self.view insertSubview:backgroundView aboveSubview:_backgroundView]; 179 | [self.view addConstraintToView:backgroundView edgeInset:UIEdgeInsetsZero]; 180 | backgroundView.alpha = 0; 181 | [UIView animateWithDuration:0.3 animations:^{ 182 | backgroundView.alpha = 1; 183 | } completion:^(BOOL finished) { 184 | [_backgroundView removeFromSuperview]; 185 | _backgroundView = backgroundView; 186 | [self addSingleTapGesture]; 187 | }]; 188 | } 189 | } 190 | 191 | - (void)addSingleTapGesture 192 | { 193 | self.view.userInteractionEnabled = YES; 194 | _backgroundView.userInteractionEnabled = YES; 195 | 196 | UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTap:)]; 197 | singleTap.enabled = _backgoundTapDismissEnable; 198 | 199 | [_backgroundView addGestureRecognizer:singleTap]; 200 | _singleTap = singleTap; 201 | } 202 | 203 | - (void)setBackgoundTapDismissEnable:(BOOL)backgoundTapDismissEnable 204 | { 205 | _backgoundTapDismissEnable = backgoundTapDismissEnable; 206 | _singleTap.enabled = backgoundTapDismissEnable; 207 | } 208 | 209 | #pragma mark - configure 210 | 211 | - (void)configureController 212 | { 213 | self.providesPresentationContextTransitionStyle = YES; 214 | self.definesPresentationContext = YES; 215 | self.modalPresentationStyle = UIModalPresentationCustom; 216 | self.transitioningDelegate = self; 217 | 218 | _backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.4]; 219 | _backgoundTapDismissEnable = NO; 220 | _alertStyleEdging = 15; 221 | _actionSheetStyleEdging = 0; 222 | } 223 | 224 | - (void)configureAlertView 225 | { 226 | if (_alertView == nil) { 227 | NSLog(@"%@: alertView is nil",NSStringFromClass([self class])); 228 | return; 229 | } 230 | _alertView.userInteractionEnabled = YES; 231 | [self.view addSubview:_alertView]; 232 | _alertView.translatesAutoresizingMaskIntoConstraints = NO; 233 | switch (_preferredStyle) { 234 | case TYAlertControllerStyleActionSheet: 235 | [self layoutActionSheetStyleView]; 236 | break; 237 | case TYAlertControllerStyleAlert: 238 | [self layoutAlertStyleView]; 239 | break; 240 | default: 241 | break; 242 | } 243 | } 244 | 245 | - (void)configureAlertViewWidth 246 | { 247 | // width, height 248 | if (!CGSizeEqualToSize(_alertView.frame.size,CGSizeZero)) { 249 | [_alertView addConstraintWidth:CGRectGetWidth(_alertView.frame) height:CGRectGetHeight(_alertView.frame)]; 250 | 251 | }else { 252 | BOOL findAlertViewWidthConstraint = NO; 253 | for (NSLayoutConstraint *constraint in _alertView.constraints) { 254 | if (constraint.firstAttribute == NSLayoutAttributeWidth) { 255 | findAlertViewWidthConstraint = YES; 256 | break; 257 | } 258 | } 259 | 260 | if (!findAlertViewWidthConstraint) { 261 | [_alertView addConstraintWidth:CGRectGetWidth(self.view.frame)-2*_alertStyleEdging height:0]; 262 | } 263 | } 264 | } 265 | 266 | #pragma mark - layout 267 | 268 | - (void)layoutAlertStyleView 269 | { 270 | // center X 271 | [self.view addConstraintCenterXToView:_alertView centerYToView:nil]; 272 | 273 | [self configureAlertViewWidth]; 274 | 275 | // top Y 276 | _alertViewCenterYConstraint = [self.view addConstraintCenterYToView:_alertView constant:0]; 277 | 278 | if (_alertViewOriginY > 0) { 279 | [_alertView layoutIfNeeded]; 280 | _alertViewCenterYOffset = _alertViewOriginY - (CGRectGetHeight(self.view.frame) - CGRectGetHeight(_alertView.frame))/2; 281 | _alertViewCenterYConstraint.constant = _alertViewCenterYOffset; 282 | }else{ 283 | _alertViewCenterYOffset = 0; 284 | } 285 | } 286 | 287 | - (void)layoutActionSheetStyleView 288 | { 289 | // remove width constaint 290 | for (NSLayoutConstraint *constraint in _alertView.constraints) { 291 | if (constraint.firstAttribute == NSLayoutAttributeWidth) { 292 | [_alertView removeConstraint: constraint]; 293 | break; 294 | } 295 | } 296 | 297 | // add edge constraint 298 | [self.view addConstraintWithView:_alertView topView:nil leftView:self.view bottomView:self.view rightView:self.view edgeInset:UIEdgeInsetsMake(0, _actionSheetStyleEdging, 0, -_actionSheetStyleEdging)]; 299 | 300 | if (CGRectGetHeight(_alertView.frame) > 0) { 301 | // height 302 | [_alertView addConstraintWidth:0 height:CGRectGetHeight(_alertView.frame)]; 303 | } 304 | } 305 | 306 | - (void)dismissViewControllerAnimated:(BOOL)animated 307 | { 308 | [self dismissViewControllerAnimated:YES completion:self.dismissComplete]; 309 | } 310 | 311 | #pragma mark - action 312 | 313 | - (void)singleTap:(UITapGestureRecognizer *)sender 314 | { 315 | [self dismissViewControllerAnimated:YES]; 316 | } 317 | 318 | #pragma mark - notification 319 | 320 | - (void)keyboardWillShow:(NSNotification*)notification 321 | { 322 | CGRect keyboardRect = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; 323 | 324 | CGFloat alertViewBottomEdge = (CGRectGetHeight(self.view.frame) - CGRectGetHeight(_alertView.frame))/2 - _alertViewCenterYOffset; 325 | 326 | //当开启热点时,向下偏移20px 327 | //修复键盘遮挡问题 328 | CGFloat statusBarHeight = [UIApplication sharedApplication].statusBarFrame.size.height; 329 | CGFloat differ = CGRectGetHeight(keyboardRect) - alertViewBottomEdge; 330 | 331 | //修复:输入框获取焦点时,会重复刷新,导致输入框文章偏移一下 332 | if (_alertViewCenterYConstraint.constant == -differ -statusBarHeight) { 333 | return; 334 | } 335 | 336 | if (differ >= 0) { 337 | _alertViewCenterYConstraint.constant = _alertViewCenterYOffset - differ - statusBarHeight; 338 | [UIView animateWithDuration:0.25 animations:^{ 339 | [self.view layoutIfNeeded]; 340 | }]; 341 | } 342 | } 343 | 344 | 345 | - (void)keyboardWillHide:(NSNotification*)notification 346 | { 347 | _alertViewCenterYConstraint.constant = _alertViewCenterYOffset; 348 | [UIView animateWithDuration:0.25 animations:^{ 349 | [self.view layoutIfNeeded]; 350 | }]; 351 | } 352 | 353 | - (void)didReceiveMemoryWarning { 354 | [super didReceiveMemoryWarning]; 355 | // Dispose of any resources that can be recreated. 356 | } 357 | 358 | - (void)dealloc 359 | { 360 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil]; 361 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil]; 362 | } 363 | 364 | @end 365 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/Blur Effects/UIImage+ImageEffects.m: -------------------------------------------------------------------------------- 1 | /* 2 | File: UIImage+ImageEffects.m 3 | Abstract: This is a category of UIImage that adds methods to apply blur and tint effects to an image. This is the code you’ll want to look out to find out how to use vImage to efficiently calculate a blur. 4 | Version: 1.0 5 | 6 | Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple 7 | Inc. ("Apple") in consideration of your agreement to the following 8 | terms, and your use, installation, modification or redistribution of 9 | this Apple software constitutes acceptance of these terms. If you do 10 | not agree with these terms, please do not use, install, modify or 11 | redistribute this Apple software. 12 | 13 | In consideration of your agreement to abide by the following terms, and 14 | subject to these terms, Apple grants you a personal, non-exclusive 15 | license, under Apple's copyrights in this original Apple software (the 16 | "Apple Software"), to use, reproduce, modify and redistribute the Apple 17 | Software, with or without modifications, in source and/or binary forms; 18 | provided that if you redistribute the Apple Software in its entirety and 19 | without modifications, you must retain this notice and the following 20 | text and disclaimers in all such redistributions of the Apple Software. 21 | Neither the name, trademarks, service marks or logos of Apple Inc. may 22 | be used to endorse or promote products derived from the Apple Software 23 | without specific prior written permission from Apple. Except as 24 | expressly stated in this notice, no other rights or licenses, express or 25 | implied, are granted by Apple herein, including but not limited to any 26 | patent rights that may be infringed by your derivative works or by other 27 | works in which the Apple Software may be incorporated. 28 | 29 | The Apple Software is provided by Apple on an "AS IS" basis. APPLE 30 | MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 31 | THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 32 | FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 33 | OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 34 | 35 | IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 36 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 37 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 38 | INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 39 | MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 40 | AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 41 | STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 42 | POSSIBILITY OF SUCH DAMAGE. 43 | 44 | Copyright (C) 2013 Apple Inc. All Rights Reserved. 45 | 46 | 47 | Copyright © 2013 Apple Inc. All rights reserved. 48 | WWDC 2013 License 49 | 50 | NOTE: This Apple Software was supplied by Apple as part of a WWDC 2013 51 | Session. Please refer to the applicable WWDC 2013 Session for further 52 | information. 53 | 54 | IMPORTANT: This Apple software is supplied to you by Apple Inc. 55 | ("Apple") in consideration of your agreement to the following terms, and 56 | your use, installation, modification or redistribution of this Apple 57 | software constitutes acceptance of these terms. If you do not agree with 58 | these terms, please do not use, install, modify or redistribute this 59 | Apple software. 60 | 61 | In consideration of your agreement to abide by the following terms, and 62 | subject to these terms, Apple grants you a non-exclusive license, under 63 | Apple's copyrights in this original Apple software (the "Apple 64 | Software"), to use, reproduce, modify and redistribute the Apple 65 | Software, with or without modifications, in source and/or binary forms; 66 | provided that if you redistribute the Apple Software in its entirety and 67 | without modifications, you must retain this notice and the following 68 | text and disclaimers in all such redistributions of the Apple Software. 69 | Neither the name, trademarks, service marks or logos of Apple Inc. may 70 | be used to endorse or promote products derived from the Apple Software 71 | without specific prior written permission from Apple. Except as 72 | expressly stated in this notice, no other rights or licenses, express or 73 | implied, are granted by Apple herein, including but not limited to any 74 | patent rights that may be infringed by your derivative works or by other 75 | works in which the Apple Software may be incorporated. 76 | 77 | The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES 78 | NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE 79 | IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR 80 | A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 81 | OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 82 | 83 | IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 84 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 85 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 86 | INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 87 | MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 88 | AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 89 | STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 90 | POSSIBILITY OF SUCH DAMAGE. 91 | 92 | EA1002 93 | 5/3/2013 94 | */ 95 | 96 | #import "UIImage+ImageEffects.h" 97 | 98 | @import Accelerate; 99 | #import 100 | 101 | 102 | @implementation UIImage (ImageEffects) 103 | 104 | 105 | - (UIImage *)applyLightEffect 106 | { 107 | UIColor *tintColor = [UIColor colorWithWhite:1.0 alpha:0.3]; 108 | return [self applyBlurWithRadius:10 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil]; 109 | } 110 | 111 | 112 | - (UIImage *)applyExtraLightEffect 113 | { 114 | UIColor *tintColor = [UIColor colorWithWhite:0.97 alpha:0.82]; 115 | return [self applyBlurWithRadius:20 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil]; 116 | } 117 | 118 | 119 | - (UIImage *)applyDarkEffect 120 | { 121 | UIColor *tintColor = [UIColor colorWithWhite:0.11 alpha:0.73]; 122 | return [self applyBlurWithRadius:20 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil]; 123 | } 124 | 125 | 126 | - (UIImage *)applyTintEffectWithColor:(UIColor *)tintColor 127 | { 128 | const CGFloat EffectColorAlpha = 0.6; 129 | UIColor *effectColor = tintColor; 130 | int componentCount = CGColorGetNumberOfComponents(tintColor.CGColor); 131 | if (componentCount == 2) { 132 | CGFloat b; 133 | if ([tintColor getWhite:&b alpha:NULL]) { 134 | effectColor = [UIColor colorWithWhite:b alpha:EffectColorAlpha]; 135 | } 136 | } 137 | else { 138 | CGFloat r, g, b; 139 | if ([tintColor getRed:&r green:&g blue:&b alpha:NULL]) { 140 | effectColor = [UIColor colorWithRed:r green:g blue:b alpha:EffectColorAlpha]; 141 | } 142 | } 143 | return [self applyBlurWithRadius:10 tintColor:effectColor saturationDeltaFactor:-1.0 maskImage:nil]; 144 | } 145 | 146 | 147 | - (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage 148 | { 149 | // Check pre-conditions. 150 | if (self.size.width < 1 || self.size.height < 1) { 151 | NSLog (@"*** error: invalid size: (%.2f x %.2f). Both dimensions must be >= 1: %@", self.size.width, self.size.height, self); 152 | return nil; 153 | } 154 | if (!self.CGImage) { 155 | NSLog (@"*** error: image must be backed by a CGImage: %@", self); 156 | return nil; 157 | } 158 | if (maskImage && !maskImage.CGImage) { 159 | NSLog (@"*** error: maskImage must be backed by a CGImage: %@", maskImage); 160 | return nil; 161 | } 162 | 163 | CGRect imageRect = { CGPointZero, self.size }; 164 | UIImage *effectImage = self; 165 | 166 | BOOL hasBlur = blurRadius > __FLT_EPSILON__; 167 | BOOL hasSaturationChange = fabs(saturationDeltaFactor - 1.) > __FLT_EPSILON__; 168 | if (hasBlur || hasSaturationChange) { 169 | UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]); 170 | CGContextRef effectInContext = UIGraphicsGetCurrentContext(); 171 | CGContextScaleCTM(effectInContext, 1.0, -1.0); 172 | CGContextTranslateCTM(effectInContext, 0, -self.size.height); 173 | CGContextDrawImage(effectInContext, imageRect, self.CGImage); 174 | 175 | vImage_Buffer effectInBuffer; 176 | effectInBuffer.data = CGBitmapContextGetData(effectInContext); 177 | effectInBuffer.width = CGBitmapContextGetWidth(effectInContext); 178 | effectInBuffer.height = CGBitmapContextGetHeight(effectInContext); 179 | effectInBuffer.rowBytes = CGBitmapContextGetBytesPerRow(effectInContext); 180 | 181 | UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]); 182 | CGContextRef effectOutContext = UIGraphicsGetCurrentContext(); 183 | vImage_Buffer effectOutBuffer; 184 | effectOutBuffer.data = CGBitmapContextGetData(effectOutContext); 185 | effectOutBuffer.width = CGBitmapContextGetWidth(effectOutContext); 186 | effectOutBuffer.height = CGBitmapContextGetHeight(effectOutContext); 187 | effectOutBuffer.rowBytes = CGBitmapContextGetBytesPerRow(effectOutContext); 188 | 189 | if (hasBlur) { 190 | // A description of how to compute the box kernel width from the Gaussian 191 | // radius (aka standard deviation) appears in the SVG spec: 192 | // http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement 193 | // 194 | // For larger values of 's' (s >= 2.0), an approximation can be used: Three 195 | // successive box-blurs build a piece-wise quadratic convolution kernel, which 196 | // approximates the Gaussian kernel to within roughly 3%. 197 | // 198 | // let d = floor(s * 3*sqrt(2*pi)/4 + 0.5) 199 | // 200 | // ... if d is odd, use three box-blurs of size 'd', centered on the output pixel. 201 | // 202 | CGFloat inputRadius = blurRadius * [[UIScreen mainScreen] scale]; 203 | NSUInteger radius = floor(inputRadius * 3. * sqrt(2 * M_PI) / 4 + 0.5); 204 | if (radius % 2 != 1) { 205 | radius += 1; // force radius to be odd so that the three box-blur methodology works. 206 | } 207 | vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend); 208 | vImageBoxConvolve_ARGB8888(&effectOutBuffer, &effectInBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend); 209 | vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend); 210 | } 211 | BOOL effectImageBuffersAreSwapped = NO; 212 | if (hasSaturationChange) { 213 | CGFloat s = saturationDeltaFactor; 214 | CGFloat floatingPointSaturationMatrix[] = { 215 | 0.0722 + 0.9278 * s, 0.0722 - 0.0722 * s, 0.0722 - 0.0722 * s, 0, 216 | 0.7152 - 0.7152 * s, 0.7152 + 0.2848 * s, 0.7152 - 0.7152 * s, 0, 217 | 0.2126 - 0.2126 * s, 0.2126 - 0.2126 * s, 0.2126 + 0.7873 * s, 0, 218 | 0, 0, 0, 1, 219 | }; 220 | const int32_t divisor = 256; 221 | NSUInteger matrixSize = sizeof(floatingPointSaturationMatrix)/sizeof(floatingPointSaturationMatrix[0]); 222 | int16_t saturationMatrix[matrixSize]; 223 | for (NSUInteger i = 0; i < matrixSize; ++i) { 224 | saturationMatrix[i] = (int16_t)roundf(floatingPointSaturationMatrix[i] * divisor); 225 | } 226 | if (hasBlur) { 227 | vImageMatrixMultiply_ARGB8888(&effectOutBuffer, &effectInBuffer, saturationMatrix, divisor, NULL, NULL, kvImageNoFlags); 228 | effectImageBuffersAreSwapped = YES; 229 | } 230 | else { 231 | vImageMatrixMultiply_ARGB8888(&effectInBuffer, &effectOutBuffer, saturationMatrix, divisor, NULL, NULL, kvImageNoFlags); 232 | } 233 | } 234 | if (!effectImageBuffersAreSwapped) 235 | effectImage = UIGraphicsGetImageFromCurrentImageContext(); 236 | UIGraphicsEndImageContext(); 237 | 238 | if (effectImageBuffersAreSwapped) 239 | effectImage = UIGraphicsGetImageFromCurrentImageContext(); 240 | UIGraphicsEndImageContext(); 241 | } 242 | 243 | // Set up output context. 244 | UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]); 245 | CGContextRef outputContext = UIGraphicsGetCurrentContext(); 246 | CGContextScaleCTM(outputContext, 1.0, -1.0); 247 | CGContextTranslateCTM(outputContext, 0, -self.size.height); 248 | 249 | // Draw base image. 250 | CGContextDrawImage(outputContext, imageRect, self.CGImage); 251 | 252 | // Draw effect image. 253 | if (hasBlur) { 254 | CGContextSaveGState(outputContext); 255 | if (maskImage) { 256 | CGContextClipToMask(outputContext, imageRect, maskImage.CGImage); 257 | } 258 | CGContextDrawImage(outputContext, imageRect, effectImage.CGImage); 259 | CGContextRestoreGState(outputContext); 260 | } 261 | 262 | // Add in color tint. 263 | if (tintColor) { 264 | CGContextSaveGState(outputContext); 265 | CGContextSetFillColorWithColor(outputContext, tintColor.CGColor); 266 | CGContextFillRect(outputContext, imageRect); 267 | CGContextRestoreGState(outputContext); 268 | } 269 | 270 | // Output image is ready. 271 | UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext(); 272 | UIGraphicsEndImageContext(); 273 | 274 | return outputImage; 275 | } 276 | 277 | @end 278 | 279 | @implementation UIImage (SnapshotImage) 280 | 281 | + (UIImage *)snapshotImageWithView:(UIView *)view 282 | { 283 | //currentView 当前的view 创建一个基于位图的图形上下文并指定大小为 284 | UIGraphicsBeginImageContextWithOptions(view.bounds.size, YES, [UIScreen mainScreen].scale); 285 | //renderInContext呈现接受者及其子范围到指定的上下文 286 | [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:NO]; 287 | //返回一个基于当前图形上下文的图片 288 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 289 | // 生成后的image 290 | UIGraphicsEndImageContext(); 291 | 292 | return image; 293 | } 294 | 295 | @end 296 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/TYAlertController/TYAlertView.m: -------------------------------------------------------------------------------- 1 | // 2 | // TYAlertView.m 3 | // TYAlertControllerDemo 4 | // 5 | // Created by tanyang on 15/9/7. 6 | // Copyright (c) 2015年 tanyang. All rights reserved. 7 | // 8 | 9 | #import "TYAlertView.h" 10 | #import "UIView+TYAlertView.h" 11 | #import "UIView+TYAutoLayout.h" 12 | 13 | @interface TYAlertAction () 14 | @property (nonatomic, strong) NSString *title; 15 | @property (nonatomic, assign) TYAlertActionStyle style; 16 | @property (nonatomic, copy) void (^handler)(TYAlertAction *); 17 | @end 18 | 19 | @implementation TYAlertAction 20 | 21 | + (instancetype)actionWithTitle:(NSString *)title style:(TYAlertActionStyle)style handler:(void (^)(TYAlertAction *))handler 22 | { 23 | return [[self alloc]initWithTitle:title style:style handler:handler]; 24 | } 25 | 26 | - (instancetype)initWithTitle:(NSString *)title style:(TYAlertActionStyle)style handler:(void (^)(TYAlertAction *))handler 27 | { 28 | if (self = [super init]) { 29 | _title = title; 30 | _style = style; 31 | _handler = handler; 32 | _enabled = YES; 33 | 34 | } 35 | return self; 36 | } 37 | 38 | - (id)copyWithZone:(NSZone *)zone 39 | { 40 | TYAlertAction *action = [[self class]allocWithZone:zone]; 41 | action.title = self.title; 42 | action.style = self.style; 43 | return action; 44 | } 45 | 46 | @end 47 | 48 | 49 | @interface TYAlertView () 50 | 51 | // text content View 52 | @property (nonatomic, weak) UIView *textContentView; 53 | @property (nonatomic, weak) UILabel *titleLable; 54 | @property (nonatomic, weak) UILabel *messageLabel; 55 | 56 | @property (nonatomic, weak) UIView *textFieldContentView; 57 | @property (nonatomic, weak) NSLayoutConstraint *textFieldTopConstraint; 58 | @property (nonatomic, strong) NSMutableArray *textFields; 59 | @property (nonatomic, strong) NSMutableArray *textFieldSeparateViews; 60 | 61 | // button content View 62 | @property (nonatomic, weak) UIView *buttonContentView; 63 | @property (nonatomic, weak) NSLayoutConstraint *buttonTopConstraint; 64 | @property (nonatomic, strong) NSMutableArray *buttons; 65 | @property (nonatomic, strong) NSMutableArray *actions; 66 | 67 | @end 68 | 69 | #define kAlertViewWidth 280 70 | #define kContentViewEdge 15 71 | #define kContentViewSpace 15 72 | 73 | #define kTextLabelSpace 6 74 | 75 | #define kButtonTagOffset 1000 76 | #define kButtonSpace 6 77 | #define KButtonHeight 44 78 | 79 | #define kTextFieldOffset 10000 80 | #define kTextFieldHeight 29 81 | #define kTextFieldEdge 8 82 | #define KTextFieldBorderWidth 0.5 83 | 84 | 85 | @implementation TYAlertView 86 | 87 | #pragma mark - init 88 | 89 | - (instancetype)initWithFrame:(CGRect)frame 90 | { 91 | if (self = [super initWithFrame:frame]) { 92 | 93 | [self configureProperty]; 94 | 95 | [self addContentViews]; 96 | 97 | [self addTextLabels]; 98 | 99 | } 100 | return self; 101 | } 102 | 103 | - (instancetype)initWithTitle:(NSString *)title message:(NSString *)message 104 | { 105 | if (self = [self init]) { 106 | 107 | _titleLable.text = title; 108 | _messageLabel.text = message; 109 | 110 | } 111 | return self; 112 | } 113 | 114 | + (instancetype)alertViewWithTitle:(NSString *)title message:(NSString *)message 115 | { 116 | return [[self alloc]initWithTitle:title message:message]; 117 | } 118 | 119 | #pragma mark - configure 120 | 121 | - (void)configureProperty 122 | { 123 | _clickedAutoHide = YES; 124 | self.backgroundColor = [UIColor whiteColor]; 125 | _alertViewWidth = kAlertViewWidth; 126 | _contentViewSpace = kContentViewSpace; 127 | 128 | _textLabelSpace = kTextLabelSpace; 129 | _textLabelContentViewEdge = kContentViewEdge; 130 | 131 | _buttonHeight = KButtonHeight; 132 | _buttonSpace = kButtonSpace; 133 | _buttonContentViewEdge = kContentViewEdge; 134 | _buttonContentViewTop = kContentViewSpace; 135 | _buttonCornerRadius = 4.0; 136 | _buttonFont = [UIFont fontWithName:@"HelveticaNeue" size:18]; 137 | _buttonDefaultBgColor = [UIColor colorWithRed:52/255.0 green:152/255.0 blue:219/255.0 alpha:1]; 138 | _buttonCancelBgColor = [UIColor colorWithRed:127/255.0 green:140/255.0 blue:141/255.0 alpha:1]; 139 | _buttonDestructiveBgColor = [UIColor colorWithRed:231/255.0 green:76/255.0 blue:60/255.0 alpha:1]; 140 | 141 | _textFieldHeight = kTextFieldHeight; 142 | _textFieldEdge = kTextFieldEdge; 143 | _textFieldBorderWidth = KTextFieldBorderWidth; 144 | _textFieldContentViewEdge = kContentViewEdge; 145 | 146 | _textFieldBorderColor = [UIColor colorWithRed:203/255.0 green:203/255.0 blue:203/255.0 alpha:1]; 147 | _textFieldBackgroudColor = [UIColor whiteColor]; 148 | _textFieldFont = [UIFont systemFontOfSize:14]; 149 | 150 | _buttons = [NSMutableArray array]; 151 | _actions = [NSMutableArray array]; 152 | } 153 | 154 | - (UIColor *)buttonBgColorWithStyle:(TYAlertActionStyle)style 155 | { 156 | switch (style) { 157 | case TYAlertActionStyleDefault: 158 | return _buttonDefaultBgColor; 159 | case TYAlertActionStyleCancel: 160 | return _buttonCancelBgColor; 161 | case TYAlertActionStyleDestructive: 162 | return _buttonDestructiveBgColor; 163 | 164 | default: 165 | return nil; 166 | } 167 | } 168 | 169 | #pragma mark - add contentview 170 | 171 | - (void)addContentViews 172 | { 173 | UIView *textContentView = [[UIView alloc]init]; 174 | [self addSubview:textContentView]; 175 | _textContentView = textContentView; 176 | 177 | UIView *textFieldContentView = [[UIView alloc]init]; 178 | [self addSubview:textFieldContentView]; 179 | _textFieldContentView = textFieldContentView; 180 | 181 | UIView *buttonContentView = [[UIView alloc]init]; 182 | buttonContentView.userInteractionEnabled = YES; 183 | [self addSubview:buttonContentView]; 184 | _buttonContentView = buttonContentView; 185 | } 186 | 187 | - (void)addTextLabels 188 | { 189 | UILabel *titleLabel = [[UILabel alloc]init]; 190 | titleLabel.textAlignment = NSTextAlignmentCenter; 191 | titleLabel.font = [UIFont fontWithName:@"HelveticaNeue-Bold" size:18]; 192 | titleLabel.textColor = [UIColor colorWithRed:51/255.0 green:51/255.0 blue:51/255.0 alpha:1.0]; 193 | [_textContentView addSubview:titleLabel]; 194 | _titleLable = titleLabel; 195 | 196 | UILabel *messageLabel = [[UILabel alloc]init]; 197 | messageLabel.numberOfLines = 0; 198 | messageLabel.textAlignment = NSTextAlignmentCenter; 199 | messageLabel.font = [UIFont fontWithName:@"HelveticaNeue" size:15]; 200 | messageLabel.textColor = [UIColor colorWithRed:51/255.0 green:51/255.0 blue:51/255.0 alpha:1.0]; 201 | [_textContentView addSubview:messageLabel]; 202 | _messageLabel = messageLabel; 203 | } 204 | 205 | - (void)didMoveToSuperview 206 | { 207 | if (self.superview) { 208 | [self layoutContentViews]; 209 | [self layoutTextLabels]; 210 | } 211 | } 212 | 213 | - (void)addAction:(TYAlertAction *)action 214 | { 215 | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 216 | button.clipsToBounds = YES; 217 | button.layer.cornerRadius = _buttonCornerRadius; 218 | [button setTitle:action.title forState:UIControlStateNormal]; 219 | button.titleLabel.font = _buttonFont; 220 | button.backgroundColor = [self buttonBgColorWithStyle:action.style]; 221 | button.enabled = action.enabled; 222 | button.tag = kButtonTagOffset + _buttons.count; 223 | button.translatesAutoresizingMaskIntoConstraints = NO; 224 | [button addTarget:self action:@selector(actionButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; 225 | 226 | [_buttonContentView addSubview:button]; 227 | [_buttons addObject:button]; 228 | [_actions addObject:action]; 229 | 230 | if (_buttons.count == 1) { 231 | [self layoutContentViews]; 232 | [self layoutTextLabels]; 233 | } 234 | 235 | [self layoutButtons]; 236 | } 237 | 238 | - (void)addTextFieldWithConfigurationHandler:(void (^)(UITextField *textField))configurationHandler 239 | { 240 | if (_textFields == nil) { 241 | _textFields = [NSMutableArray array]; 242 | } 243 | 244 | UITextField *textField = [[UITextField alloc]init]; 245 | textField.tag = kTextFieldOffset + _textFields.count; 246 | textField.font = _textFieldFont; 247 | textField.translatesAutoresizingMaskIntoConstraints = NO; 248 | 249 | if (configurationHandler) { 250 | configurationHandler(textField); 251 | } 252 | 253 | [_textFieldContentView addSubview:textField]; 254 | [_textFields addObject:textField]; 255 | 256 | if (_textFields.count > 1) { 257 | if (_textFieldSeparateViews == nil) { 258 | _textFieldSeparateViews = [NSMutableArray array]; 259 | } 260 | UIView *separateView = [[UIView alloc]init]; 261 | separateView.backgroundColor = _textFieldBorderColor; 262 | separateView.translatesAutoresizingMaskIntoConstraints = NO; 263 | [_textFieldContentView addSubview:separateView]; 264 | [_textFieldSeparateViews addObject:separateView]; 265 | } 266 | 267 | [self layoutTextFields]; 268 | } 269 | 270 | - (NSArray *)textFieldArray 271 | { 272 | return _textFields; 273 | } 274 | 275 | #pragma mark - layout contenview 276 | 277 | - (void)layoutContentViews 278 | { 279 | if (!_textContentView.translatesAutoresizingMaskIntoConstraints) { 280 | // layout done 281 | return; 282 | } 283 | if (_alertViewWidth) { 284 | [self addConstraintWidth:_alertViewWidth height:0]; 285 | } 286 | 287 | // textContentView 288 | _textContentView.translatesAutoresizingMaskIntoConstraints = NO; 289 | 290 | [self addConstraintWithView:_textContentView topView:self leftView:self bottomView:nil rightView:self edgeInset:UIEdgeInsetsMake(_contentViewSpace, _textLabelContentViewEdge, 0, -_textLabelContentViewEdge)]; 291 | 292 | // textFieldContentView 293 | _textFieldContentView.translatesAutoresizingMaskIntoConstraints = NO; 294 | _textFieldTopConstraint = [self addConstraintWithTopView:_textContentView toBottomView:_textFieldContentView constant:0]; 295 | 296 | [self addConstraintWithView:_textFieldContentView topView:nil leftView:self bottomView:nil rightView:self edgeInset:UIEdgeInsetsMake(0, _textFieldContentViewEdge, 0, -_textFieldContentViewEdge)]; 297 | 298 | // buttonContentView 299 | _buttonContentView.translatesAutoresizingMaskIntoConstraints = NO; 300 | 301 | _buttonTopConstraint = [self addConstraintWithTopView:_textFieldContentView toBottomView:_buttonContentView constant:_buttonContentViewTop]; 302 | 303 | [self addConstraintWithView:_buttonContentView topView:nil leftView:self bottomView:self rightView:self edgeInset:UIEdgeInsetsMake(0, _buttonContentViewEdge, -_contentViewSpace, -_buttonContentViewEdge)]; 304 | } 305 | 306 | - (void)layoutTextLabels 307 | { 308 | if (!_titleLable.translatesAutoresizingMaskIntoConstraints && !_messageLabel.translatesAutoresizingMaskIntoConstraints) { 309 | // layout done 310 | return; 311 | } 312 | // title 313 | _titleLable.translatesAutoresizingMaskIntoConstraints = NO; 314 | [_textContentView addConstraintWithView:_titleLable topView:_textContentView leftView:_textContentView bottomView:nil rightView:_textContentView edgeInset:UIEdgeInsetsZero]; 315 | 316 | // message 317 | _messageLabel.translatesAutoresizingMaskIntoConstraints = NO; 318 | [_textContentView addConstraintWithTopView:_titleLable toBottomView:_messageLabel constant:_textLabelSpace]; 319 | [_textContentView addConstraintWithView:_messageLabel topView:nil leftView:_textContentView bottomView:_textContentView rightView:_textContentView edgeInset:UIEdgeInsetsZero]; 320 | } 321 | 322 | - (void)layoutButtons 323 | { 324 | UIButton *button = _buttons.lastObject; 325 | if (_buttons.count == 1) { 326 | _buttonTopConstraint.constant = -_buttonContentViewTop; 327 | [_buttonContentView addConstraintToView:button edgeInset:UIEdgeInsetsZero]; 328 | [button addConstraintWidth:0 height:_buttonHeight]; 329 | }else if (_buttons.count == 2) { 330 | UIButton *firstButton = _buttons.firstObject; 331 | [_buttonContentView removeConstraintWithView:firstButton attribute:NSLayoutAttributeRight]; 332 | [_buttonContentView addConstraintWithView:button topView:_buttonContentView leftView:nil bottomView:nil rightView:_buttonContentView edgeInset:UIEdgeInsetsZero]; 333 | [_buttonContentView addConstraintWithLeftView:firstButton toRightView:button constant:_buttonSpace]; 334 | [_buttonContentView addConstraintEqualWithView:button widthToView:firstButton heightToView:firstButton]; 335 | }else { 336 | if (_buttons.count == 3) { 337 | UIButton *firstBtn = _buttons[0]; 338 | UIButton *secondBtn = _buttons[1]; 339 | [_buttonContentView removeConstraintWithView:firstBtn attribute:NSLayoutAttributeRight]; 340 | [_buttonContentView removeConstraintWithView:firstBtn attribute:NSLayoutAttributeBottom]; 341 | [_buttonContentView removeConstraintWithView:secondBtn attribute:NSLayoutAttributeTop]; 342 | [_buttonContentView addConstraintWithView:firstBtn topView:nil leftView:nil bottomView:nil rightView:_buttonContentView edgeInset:UIEdgeInsetsZero]; 343 | [_buttonContentView addConstraintWithTopView:firstBtn toBottomView:secondBtn constant:_buttonSpace]; 344 | 345 | } 346 | 347 | UIButton *lastSecondBtn = _buttons[_buttons.count - 2]; 348 | [_buttonContentView removeConstraintWithView:lastSecondBtn attribute:NSLayoutAttributeBottom]; 349 | [_buttonContentView addConstraintWithTopView:lastSecondBtn toBottomView:button constant:_buttonSpace]; 350 | [_buttonContentView addConstraintWithView:button topView:nil leftView:_buttonContentView bottomView:_buttonContentView rightView:_buttonContentView edgeInset:UIEdgeInsetsZero]; 351 | [_buttonContentView addConstraintEqualWithView:button widthToView:nil heightToView:lastSecondBtn]; 352 | } 353 | } 354 | 355 | - (void)layoutTextFields 356 | { 357 | UITextField *textField = _textFields.lastObject; 358 | 359 | if (_textFields.count == 1) { 360 | // setup textFieldContentView 361 | _textFieldContentView.backgroundColor = _textFieldBackgroudColor; 362 | _textFieldContentView.layer.masksToBounds = YES; 363 | _textFieldContentView.layer.cornerRadius = 4; 364 | _textFieldContentView.layer.borderWidth = _textFieldBorderWidth; 365 | _textFieldContentView.layer.borderColor = _textFieldBorderColor.CGColor; 366 | _textFieldTopConstraint.constant = -_contentViewSpace; 367 | [_textFieldContentView addConstraintToView:textField edgeInset:UIEdgeInsetsMake(_textFieldBorderWidth, _textFieldEdge, -_textFieldBorderWidth, -_textFieldEdge)]; 368 | [textField addConstraintWidth:0 height:_textFieldHeight]; 369 | }else { 370 | // textField 371 | UITextField *lastSecondTextField = _textFields[_textFields.count - 2]; 372 | [_textFieldContentView removeConstraintWithView:lastSecondTextField attribute:NSLayoutAttributeBottom]; 373 | [_textFieldContentView addConstraintWithTopView:lastSecondTextField toBottomView:textField constant:_textFieldBorderWidth]; 374 | [_textFieldContentView addConstraintWithView:textField topView:nil leftView:_textFieldContentView bottomView:_textFieldContentView rightView:_textFieldContentView edgeInset:UIEdgeInsetsMake(0, _textFieldEdge, -_textFieldBorderWidth, -_textFieldEdge)]; 375 | [_textFieldContentView addConstraintEqualWithView:textField widthToView:nil heightToView:lastSecondTextField]; 376 | 377 | // separateview 378 | UIView *separateView = _textFieldSeparateViews[_textFields.count - 2]; 379 | [_textFieldContentView addConstraintWithView:separateView topView:nil leftView:_textFieldContentView bottomView:nil rightView:_textFieldContentView edgeInset:UIEdgeInsetsZero]; 380 | [_textFieldContentView addConstraintWithTopView:separateView toBottomView:textField constant:0]; 381 | [separateView addConstraintWidth:0 height:_textFieldBorderWidth]; 382 | } 383 | } 384 | 385 | #pragma mark - action 386 | 387 | - (void)actionButtonClicked:(UIButton *)button 388 | { 389 | TYAlertAction *action = _actions[button.tag - kButtonTagOffset]; 390 | 391 | if (_clickedAutoHide) { 392 | [self hideView]; 393 | } 394 | 395 | if (action.handler) { 396 | action.handler(action); 397 | } 398 | } 399 | 400 | //- (void)dealloc 401 | //{ 402 | // NSLog(@"%@ dealloc",NSStringFromClass([self class])); 403 | //} 404 | 405 | @end 406 | -------------------------------------------------------------------------------- /TYAlertControllerDemo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 55 | 81 | 101 | 119 | 145 | 163 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | -------------------------------------------------------------------------------- /TYAlertControllerDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | B01448F01BDE4677009E0389 /* SettingModelView.m in Sources */ = {isa = PBXBuildFile; fileRef = B01448EF1BDE4677009E0389 /* SettingModelView.m */; }; 11 | B01448F21BDE4690009E0389 /* SettingModelView.xib in Resources */ = {isa = PBXBuildFile; fileRef = B01448F11BDE4690009E0389 /* SettingModelView.xib */; }; 12 | B01448F71BDE50C1009E0389 /* UIImage+ImageEffects.m in Sources */ = {isa = PBXBuildFile; fileRef = B01448F61BDE50C1009E0389 /* UIImage+ImageEffects.m */; }; 13 | B01448FA1BDE51DB009E0389 /* TYAlertController+BlurEffects.m in Sources */ = {isa = PBXBuildFile; fileRef = B01448F91BDE51DB009E0389 /* TYAlertController+BlurEffects.m */; }; 14 | B01449061BDE57E9009E0389 /* ShareView.m in Sources */ = {isa = PBXBuildFile; fileRef = B01449051BDE57E9009E0389 /* ShareView.m */; }; 15 | B01449081BDE5817009E0389 /* ShareView.xib in Resources */ = {isa = PBXBuildFile; fileRef = B01449071BDE5817009E0389 /* ShareView.xib */; }; 16 | B0873F0D1BD370C700D2F4D5 /* TYShowAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = B0873F0C1BD370C700D2F4D5 /* TYShowAlertView.m */; }; 17 | B08FD7D01BD905EF00B83FF5 /* screen.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B08FD7CF1BD905EF00B83FF5 /* screen.jpg */; }; 18 | B0D617E41BDF9C5D0084EE84 /* TYAlertDropDownAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = B0D617E31BDF9C5D0084EE84 /* TYAlertDropDownAnimation.m */; }; 19 | D35854241B9532D700B5FA1F /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = D35854231B9532D700B5FA1F /* main.m */; }; 20 | D35854271B9532D700B5FA1F /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = D35854261B9532D700B5FA1F /* AppDelegate.m */; }; 21 | D358542A1B9532D700B5FA1F /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D35854291B9532D700B5FA1F /* ViewController.m */; }; 22 | D358542D1B9532D700B5FA1F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D358542B1B9532D700B5FA1F /* Main.storyboard */; }; 23 | D358542F1B9532D700B5FA1F /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D358542E1B9532D700B5FA1F /* Images.xcassets */; }; 24 | D35854321B9532D700B5FA1F /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = D35854301B9532D700B5FA1F /* LaunchScreen.xib */; }; 25 | D358543E1B9532D700B5FA1F /* TYAlertControllerDemoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D358543D1B9532D700B5FA1F /* TYAlertControllerDemoTests.m */; }; 26 | D35854A61B953FC300B5FA1F /* TYAlertController.m in Sources */ = {isa = PBXBuildFile; fileRef = D35854A51B953FC300B5FA1F /* TYAlertController.m */; }; 27 | D35854A91B95973000B5FA1F /* TYAlertFadeAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = D35854A81B95973000B5FA1F /* TYAlertFadeAnimation.m */; }; 28 | D35854B51B95B7BB00B5FA1F /* TYBaseAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = D35854B41B95B7BB00B5FA1F /* TYBaseAnimation.m */; }; 29 | D35854B81B95BC9700B5FA1F /* TYAlertController+TransitionAnimate.m in Sources */ = {isa = PBXBuildFile; fileRef = D35854B71B95BC9700B5FA1F /* TYAlertController+TransitionAnimate.m */; }; 30 | D37A91E11B9E7B6000C6661A /* UIView+TYAutoLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = D37A91E01B9E7B6000C6661A /* UIView+TYAutoLayout.m */; }; 31 | D395FE1F1B96C7F1000F72F7 /* TYAlertScaleFadeAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = D395FE1E1B96C7F1000F72F7 /* TYAlertScaleFadeAnimation.m */; }; 32 | D3C1A9731B9D16D5009738B0 /* UIView+TYAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = D3C1A9721B9D16D5009738B0 /* UIView+TYAlertView.m */; }; 33 | D3C1A9761B9D1A83009738B0 /* TYAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = D3C1A9751B9D1A83009738B0 /* TYAlertView.m */; }; 34 | /* End PBXBuildFile section */ 35 | 36 | /* Begin PBXContainerItemProxy section */ 37 | D35854381B9532D700B5FA1F /* PBXContainerItemProxy */ = { 38 | isa = PBXContainerItemProxy; 39 | containerPortal = D35854161B9532D700B5FA1F /* Project object */; 40 | proxyType = 1; 41 | remoteGlobalIDString = D358541D1B9532D700B5FA1F; 42 | remoteInfo = TYAlertControllerDemo; 43 | }; 44 | /* End PBXContainerItemProxy section */ 45 | 46 | /* Begin PBXFileReference section */ 47 | B01448EE1BDE4677009E0389 /* SettingModelView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingModelView.h; sourceTree = ""; }; 48 | B01448EF1BDE4677009E0389 /* SettingModelView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingModelView.m; sourceTree = ""; }; 49 | B01448F11BDE4690009E0389 /* SettingModelView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SettingModelView.xib; sourceTree = ""; }; 50 | B01448F51BDE50C1009E0389 /* UIImage+ImageEffects.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+ImageEffects.h"; sourceTree = ""; }; 51 | B01448F61BDE50C1009E0389 /* UIImage+ImageEffects.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+ImageEffects.m"; sourceTree = ""; }; 52 | B01448F81BDE51DB009E0389 /* TYAlertController+BlurEffects.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "TYAlertController+BlurEffects.h"; sourceTree = ""; }; 53 | B01448F91BDE51DB009E0389 /* TYAlertController+BlurEffects.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "TYAlertController+BlurEffects.m"; sourceTree = ""; }; 54 | B01449041BDE57E9009E0389 /* ShareView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShareView.h; sourceTree = ""; }; 55 | B01449051BDE57E9009E0389 /* ShareView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShareView.m; sourceTree = ""; }; 56 | B01449071BDE5817009E0389 /* ShareView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ShareView.xib; sourceTree = ""; }; 57 | B0873F0B1BD370C700D2F4D5 /* TYShowAlertView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TYShowAlertView.h; sourceTree = ""; }; 58 | B0873F0C1BD370C700D2F4D5 /* TYShowAlertView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TYShowAlertView.m; sourceTree = ""; }; 59 | B08FD7CF1BD905EF00B83FF5 /* screen.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = screen.jpg; sourceTree = ""; }; 60 | B0D617E21BDF9C5D0084EE84 /* TYAlertDropDownAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TYAlertDropDownAnimation.h; sourceTree = ""; }; 61 | B0D617E31BDF9C5D0084EE84 /* TYAlertDropDownAnimation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TYAlertDropDownAnimation.m; sourceTree = ""; }; 62 | D358541E1B9532D700B5FA1F /* TYAlertControllerDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TYAlertControllerDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 63 | D35854221B9532D700B5FA1F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 64 | D35854231B9532D700B5FA1F /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 65 | D35854251B9532D700B5FA1F /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 66 | D35854261B9532D700B5FA1F /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 67 | D35854281B9532D700B5FA1F /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 68 | D35854291B9532D700B5FA1F /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 69 | D358542C1B9532D700B5FA1F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 70 | D358542E1B9532D700B5FA1F /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 71 | D35854311B9532D700B5FA1F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 72 | D35854371B9532D700B5FA1F /* TYAlertControllerDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TYAlertControllerDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 73 | D358543C1B9532D700B5FA1F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 74 | D358543D1B9532D700B5FA1F /* TYAlertControllerDemoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TYAlertControllerDemoTests.m; sourceTree = ""; }; 75 | D35854A41B953FC300B5FA1F /* TYAlertController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TYAlertController.h; sourceTree = ""; }; 76 | D35854A51B953FC300B5FA1F /* TYAlertController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TYAlertController.m; sourceTree = ""; }; 77 | D35854A71B95973000B5FA1F /* TYAlertFadeAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TYAlertFadeAnimation.h; sourceTree = ""; }; 78 | D35854A81B95973000B5FA1F /* TYAlertFadeAnimation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TYAlertFadeAnimation.m; sourceTree = ""; }; 79 | D35854B31B95B7BB00B5FA1F /* TYBaseAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TYBaseAnimation.h; sourceTree = ""; }; 80 | D35854B41B95B7BB00B5FA1F /* TYBaseAnimation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TYBaseAnimation.m; sourceTree = ""; }; 81 | D35854B71B95BC9700B5FA1F /* TYAlertController+TransitionAnimate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "TYAlertController+TransitionAnimate.m"; sourceTree = ""; }; 82 | D37A91DF1B9E7B6000C6661A /* UIView+TYAutoLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+TYAutoLayout.h"; sourceTree = ""; }; 83 | D37A91E01B9E7B6000C6661A /* UIView+TYAutoLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+TYAutoLayout.m"; sourceTree = ""; }; 84 | D395FE1D1B96C7F1000F72F7 /* TYAlertScaleFadeAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TYAlertScaleFadeAnimation.h; sourceTree = ""; }; 85 | D395FE1E1B96C7F1000F72F7 /* TYAlertScaleFadeAnimation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TYAlertScaleFadeAnimation.m; sourceTree = ""; }; 86 | D3C1A9711B9D16D5009738B0 /* UIView+TYAlertView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+TYAlertView.h"; sourceTree = ""; }; 87 | D3C1A9721B9D16D5009738B0 /* UIView+TYAlertView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+TYAlertView.m"; sourceTree = ""; }; 88 | D3C1A9741B9D1A83009738B0 /* TYAlertView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TYAlertView.h; sourceTree = ""; }; 89 | D3C1A9751B9D1A83009738B0 /* TYAlertView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TYAlertView.m; sourceTree = ""; }; 90 | /* End PBXFileReference section */ 91 | 92 | /* Begin PBXFrameworksBuildPhase section */ 93 | D358541B1B9532D700B5FA1F /* Frameworks */ = { 94 | isa = PBXFrameworksBuildPhase; 95 | buildActionMask = 2147483647; 96 | files = ( 97 | ); 98 | runOnlyForDeploymentPostprocessing = 0; 99 | }; 100 | D35854341B9532D700B5FA1F /* Frameworks */ = { 101 | isa = PBXFrameworksBuildPhase; 102 | buildActionMask = 2147483647; 103 | files = ( 104 | ); 105 | runOnlyForDeploymentPostprocessing = 0; 106 | }; 107 | /* End PBXFrameworksBuildPhase section */ 108 | 109 | /* Begin PBXGroup section */ 110 | B01448F41BDE509A009E0389 /* Blur Effects */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | B01448F81BDE51DB009E0389 /* TYAlertController+BlurEffects.h */, 114 | B01448F91BDE51DB009E0389 /* TYAlertController+BlurEffects.m */, 115 | B01448F51BDE50C1009E0389 /* UIImage+ImageEffects.h */, 116 | B01448F61BDE50C1009E0389 /* UIImage+ImageEffects.m */, 117 | ); 118 | path = "Blur Effects"; 119 | sourceTree = ""; 120 | }; 121 | B03322B61BDCEC5000F778D4 /* customAlertView */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | B01448EE1BDE4677009E0389 /* SettingModelView.h */, 125 | B01448EF1BDE4677009E0389 /* SettingModelView.m */, 126 | B01448F11BDE4690009E0389 /* SettingModelView.xib */, 127 | B01449041BDE57E9009E0389 /* ShareView.h */, 128 | B01449051BDE57E9009E0389 /* ShareView.m */, 129 | B01449071BDE5817009E0389 /* ShareView.xib */, 130 | ); 131 | name = customAlertView; 132 | sourceTree = ""; 133 | }; 134 | D35854151B9532D700B5FA1F = { 135 | isa = PBXGroup; 136 | children = ( 137 | D35854201B9532D700B5FA1F /* TYAlertControllerDemo */, 138 | D358543A1B9532D700B5FA1F /* TYAlertControllerDemoTests */, 139 | D358541F1B9532D700B5FA1F /* Products */, 140 | ); 141 | sourceTree = ""; 142 | }; 143 | D358541F1B9532D700B5FA1F /* Products */ = { 144 | isa = PBXGroup; 145 | children = ( 146 | D358541E1B9532D700B5FA1F /* TYAlertControllerDemo.app */, 147 | D35854371B9532D700B5FA1F /* TYAlertControllerDemoTests.xctest */, 148 | ); 149 | name = Products; 150 | sourceTree = ""; 151 | }; 152 | D35854201B9532D700B5FA1F /* TYAlertControllerDemo */ = { 153 | isa = PBXGroup; 154 | children = ( 155 | D35854A31B953F3D00B5FA1F /* TYAlertController */, 156 | B01448F41BDE509A009E0389 /* Blur Effects */, 157 | B03322B61BDCEC5000F778D4 /* customAlertView */, 158 | D35854251B9532D700B5FA1F /* AppDelegate.h */, 159 | D35854261B9532D700B5FA1F /* AppDelegate.m */, 160 | D35854281B9532D700B5FA1F /* ViewController.h */, 161 | D35854291B9532D700B5FA1F /* ViewController.m */, 162 | D358542B1B9532D700B5FA1F /* Main.storyboard */, 163 | D358542E1B9532D700B5FA1F /* Images.xcassets */, 164 | D35854301B9532D700B5FA1F /* LaunchScreen.xib */, 165 | D35854211B9532D700B5FA1F /* Supporting Files */, 166 | ); 167 | path = TYAlertControllerDemo; 168 | sourceTree = ""; 169 | }; 170 | D35854211B9532D700B5FA1F /* Supporting Files */ = { 171 | isa = PBXGroup; 172 | children = ( 173 | B08FD7CF1BD905EF00B83FF5 /* screen.jpg */, 174 | D35854221B9532D700B5FA1F /* Info.plist */, 175 | D35854231B9532D700B5FA1F /* main.m */, 176 | ); 177 | name = "Supporting Files"; 178 | sourceTree = ""; 179 | }; 180 | D358543A1B9532D700B5FA1F /* TYAlertControllerDemoTests */ = { 181 | isa = PBXGroup; 182 | children = ( 183 | D358543D1B9532D700B5FA1F /* TYAlertControllerDemoTests.m */, 184 | D358543B1B9532D700B5FA1F /* Supporting Files */, 185 | ); 186 | path = TYAlertControllerDemoTests; 187 | sourceTree = ""; 188 | }; 189 | D358543B1B9532D700B5FA1F /* Supporting Files */ = { 190 | isa = PBXGroup; 191 | children = ( 192 | D358543C1B9532D700B5FA1F /* Info.plist */, 193 | ); 194 | name = "Supporting Files"; 195 | sourceTree = ""; 196 | }; 197 | D35854A31B953F3D00B5FA1F /* TYAlertController */ = { 198 | isa = PBXGroup; 199 | children = ( 200 | D386E9711B9C162400321875 /* AlertView */, 201 | D386E9701B9C15E800321875 /* AlertAimations */, 202 | D35854A41B953FC300B5FA1F /* TYAlertController.h */, 203 | D35854A51B953FC300B5FA1F /* TYAlertController.m */, 204 | D35854B71B95BC9700B5FA1F /* TYAlertController+TransitionAnimate.m */, 205 | B0873F0B1BD370C700D2F4D5 /* TYShowAlertView.h */, 206 | B0873F0C1BD370C700D2F4D5 /* TYShowAlertView.m */, 207 | ); 208 | path = TYAlertController; 209 | sourceTree = ""; 210 | }; 211 | D386E9701B9C15E800321875 /* AlertAimations */ = { 212 | isa = PBXGroup; 213 | children = ( 214 | D35854B31B95B7BB00B5FA1F /* TYBaseAnimation.h */, 215 | D35854B41B95B7BB00B5FA1F /* TYBaseAnimation.m */, 216 | D35854A71B95973000B5FA1F /* TYAlertFadeAnimation.h */, 217 | D35854A81B95973000B5FA1F /* TYAlertFadeAnimation.m */, 218 | D395FE1D1B96C7F1000F72F7 /* TYAlertScaleFadeAnimation.h */, 219 | D395FE1E1B96C7F1000F72F7 /* TYAlertScaleFadeAnimation.m */, 220 | B0D617E21BDF9C5D0084EE84 /* TYAlertDropDownAnimation.h */, 221 | B0D617E31BDF9C5D0084EE84 /* TYAlertDropDownAnimation.m */, 222 | ); 223 | name = AlertAimations; 224 | sourceTree = ""; 225 | }; 226 | D386E9711B9C162400321875 /* AlertView */ = { 227 | isa = PBXGroup; 228 | children = ( 229 | D3C1A9711B9D16D5009738B0 /* UIView+TYAlertView.h */, 230 | D3C1A9721B9D16D5009738B0 /* UIView+TYAlertView.m */, 231 | D37A91DF1B9E7B6000C6661A /* UIView+TYAutoLayout.h */, 232 | D37A91E01B9E7B6000C6661A /* UIView+TYAutoLayout.m */, 233 | D3C1A9741B9D1A83009738B0 /* TYAlertView.h */, 234 | D3C1A9751B9D1A83009738B0 /* TYAlertView.m */, 235 | ); 236 | name = AlertView; 237 | sourceTree = ""; 238 | }; 239 | /* End PBXGroup section */ 240 | 241 | /* Begin PBXNativeTarget section */ 242 | D358541D1B9532D700B5FA1F /* TYAlertControllerDemo */ = { 243 | isa = PBXNativeTarget; 244 | buildConfigurationList = D35854411B9532D700B5FA1F /* Build configuration list for PBXNativeTarget "TYAlertControllerDemo" */; 245 | buildPhases = ( 246 | D358541A1B9532D700B5FA1F /* Sources */, 247 | D358541B1B9532D700B5FA1F /* Frameworks */, 248 | D358541C1B9532D700B5FA1F /* Resources */, 249 | ); 250 | buildRules = ( 251 | ); 252 | dependencies = ( 253 | ); 254 | name = TYAlertControllerDemo; 255 | productName = TYAlertControllerDemo; 256 | productReference = D358541E1B9532D700B5FA1F /* TYAlertControllerDemo.app */; 257 | productType = "com.apple.product-type.application"; 258 | }; 259 | D35854361B9532D700B5FA1F /* TYAlertControllerDemoTests */ = { 260 | isa = PBXNativeTarget; 261 | buildConfigurationList = D35854441B9532D700B5FA1F /* Build configuration list for PBXNativeTarget "TYAlertControllerDemoTests" */; 262 | buildPhases = ( 263 | D35854331B9532D700B5FA1F /* Sources */, 264 | D35854341B9532D700B5FA1F /* Frameworks */, 265 | D35854351B9532D700B5FA1F /* Resources */, 266 | ); 267 | buildRules = ( 268 | ); 269 | dependencies = ( 270 | D35854391B9532D700B5FA1F /* PBXTargetDependency */, 271 | ); 272 | name = TYAlertControllerDemoTests; 273 | productName = TYAlertControllerDemoTests; 274 | productReference = D35854371B9532D700B5FA1F /* TYAlertControllerDemoTests.xctest */; 275 | productType = "com.apple.product-type.bundle.unit-test"; 276 | }; 277 | /* End PBXNativeTarget section */ 278 | 279 | /* Begin PBXProject section */ 280 | D35854161B9532D700B5FA1F /* Project object */ = { 281 | isa = PBXProject; 282 | attributes = { 283 | LastUpgradeCheck = 0640; 284 | ORGANIZATIONNAME = tanyang; 285 | TargetAttributes = { 286 | D358541D1B9532D700B5FA1F = { 287 | CreatedOnToolsVersion = 6.4; 288 | DevelopmentTeam = ZW52Q3KXX4; 289 | }; 290 | D35854361B9532D700B5FA1F = { 291 | CreatedOnToolsVersion = 6.4; 292 | TestTargetID = D358541D1B9532D700B5FA1F; 293 | }; 294 | }; 295 | }; 296 | buildConfigurationList = D35854191B9532D700B5FA1F /* Build configuration list for PBXProject "TYAlertControllerDemo" */; 297 | compatibilityVersion = "Xcode 3.2"; 298 | developmentRegion = English; 299 | hasScannedForEncodings = 0; 300 | knownRegions = ( 301 | en, 302 | Base, 303 | ); 304 | mainGroup = D35854151B9532D700B5FA1F; 305 | productRefGroup = D358541F1B9532D700B5FA1F /* Products */; 306 | projectDirPath = ""; 307 | projectRoot = ""; 308 | targets = ( 309 | D358541D1B9532D700B5FA1F /* TYAlertControllerDemo */, 310 | D35854361B9532D700B5FA1F /* TYAlertControllerDemoTests */, 311 | ); 312 | }; 313 | /* End PBXProject section */ 314 | 315 | /* Begin PBXResourcesBuildPhase section */ 316 | D358541C1B9532D700B5FA1F /* Resources */ = { 317 | isa = PBXResourcesBuildPhase; 318 | buildActionMask = 2147483647; 319 | files = ( 320 | D358542D1B9532D700B5FA1F /* Main.storyboard in Resources */, 321 | B08FD7D01BD905EF00B83FF5 /* screen.jpg in Resources */, 322 | B01449081BDE5817009E0389 /* ShareView.xib in Resources */, 323 | D35854321B9532D700B5FA1F /* LaunchScreen.xib in Resources */, 324 | B01448F21BDE4690009E0389 /* SettingModelView.xib in Resources */, 325 | D358542F1B9532D700B5FA1F /* Images.xcassets in Resources */, 326 | ); 327 | runOnlyForDeploymentPostprocessing = 0; 328 | }; 329 | D35854351B9532D700B5FA1F /* Resources */ = { 330 | isa = PBXResourcesBuildPhase; 331 | buildActionMask = 2147483647; 332 | files = ( 333 | ); 334 | runOnlyForDeploymentPostprocessing = 0; 335 | }; 336 | /* End PBXResourcesBuildPhase section */ 337 | 338 | /* Begin PBXSourcesBuildPhase section */ 339 | D358541A1B9532D700B5FA1F /* Sources */ = { 340 | isa = PBXSourcesBuildPhase; 341 | buildActionMask = 2147483647; 342 | files = ( 343 | D358542A1B9532D700B5FA1F /* ViewController.m in Sources */, 344 | B01448FA1BDE51DB009E0389 /* TYAlertController+BlurEffects.m in Sources */, 345 | B01448F01BDE4677009E0389 /* SettingModelView.m in Sources */, 346 | B01448F71BDE50C1009E0389 /* UIImage+ImageEffects.m in Sources */, 347 | B01449061BDE57E9009E0389 /* ShareView.m in Sources */, 348 | D35854B51B95B7BB00B5FA1F /* TYBaseAnimation.m in Sources */, 349 | B0D617E41BDF9C5D0084EE84 /* TYAlertDropDownAnimation.m in Sources */, 350 | D3C1A9761B9D1A83009738B0 /* TYAlertView.m in Sources */, 351 | D37A91E11B9E7B6000C6661A /* UIView+TYAutoLayout.m in Sources */, 352 | D35854271B9532D700B5FA1F /* AppDelegate.m in Sources */, 353 | D3C1A9731B9D16D5009738B0 /* UIView+TYAlertView.m in Sources */, 354 | D395FE1F1B96C7F1000F72F7 /* TYAlertScaleFadeAnimation.m in Sources */, 355 | B0873F0D1BD370C700D2F4D5 /* TYShowAlertView.m in Sources */, 356 | D35854241B9532D700B5FA1F /* main.m in Sources */, 357 | D35854A61B953FC300B5FA1F /* TYAlertController.m in Sources */, 358 | D35854B81B95BC9700B5FA1F /* TYAlertController+TransitionAnimate.m in Sources */, 359 | D35854A91B95973000B5FA1F /* TYAlertFadeAnimation.m in Sources */, 360 | ); 361 | runOnlyForDeploymentPostprocessing = 0; 362 | }; 363 | D35854331B9532D700B5FA1F /* Sources */ = { 364 | isa = PBXSourcesBuildPhase; 365 | buildActionMask = 2147483647; 366 | files = ( 367 | D358543E1B9532D700B5FA1F /* TYAlertControllerDemoTests.m in Sources */, 368 | ); 369 | runOnlyForDeploymentPostprocessing = 0; 370 | }; 371 | /* End PBXSourcesBuildPhase section */ 372 | 373 | /* Begin PBXTargetDependency section */ 374 | D35854391B9532D700B5FA1F /* PBXTargetDependency */ = { 375 | isa = PBXTargetDependency; 376 | target = D358541D1B9532D700B5FA1F /* TYAlertControllerDemo */; 377 | targetProxy = D35854381B9532D700B5FA1F /* PBXContainerItemProxy */; 378 | }; 379 | /* End PBXTargetDependency section */ 380 | 381 | /* Begin PBXVariantGroup section */ 382 | D358542B1B9532D700B5FA1F /* Main.storyboard */ = { 383 | isa = PBXVariantGroup; 384 | children = ( 385 | D358542C1B9532D700B5FA1F /* Base */, 386 | ); 387 | name = Main.storyboard; 388 | sourceTree = ""; 389 | }; 390 | D35854301B9532D700B5FA1F /* LaunchScreen.xib */ = { 391 | isa = PBXVariantGroup; 392 | children = ( 393 | D35854311B9532D700B5FA1F /* Base */, 394 | ); 395 | name = LaunchScreen.xib; 396 | sourceTree = ""; 397 | }; 398 | /* End PBXVariantGroup section */ 399 | 400 | /* Begin XCBuildConfiguration section */ 401 | D358543F1B9532D700B5FA1F /* Debug */ = { 402 | isa = XCBuildConfiguration; 403 | buildSettings = { 404 | ALWAYS_SEARCH_USER_PATHS = NO; 405 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 406 | CLANG_CXX_LIBRARY = "libc++"; 407 | CLANG_ENABLE_MODULES = YES; 408 | CLANG_ENABLE_OBJC_ARC = YES; 409 | CLANG_WARN_BOOL_CONVERSION = YES; 410 | CLANG_WARN_CONSTANT_CONVERSION = YES; 411 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 412 | CLANG_WARN_EMPTY_BODY = YES; 413 | CLANG_WARN_ENUM_CONVERSION = YES; 414 | CLANG_WARN_INT_CONVERSION = YES; 415 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 416 | CLANG_WARN_UNREACHABLE_CODE = YES; 417 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 418 | CODE_SIGN_IDENTITY = "iPhone Developer"; 419 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 420 | COPY_PHASE_STRIP = NO; 421 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 422 | ENABLE_STRICT_OBJC_MSGSEND = YES; 423 | GCC_C_LANGUAGE_STANDARD = gnu99; 424 | GCC_DYNAMIC_NO_PIC = NO; 425 | GCC_NO_COMMON_BLOCKS = YES; 426 | GCC_OPTIMIZATION_LEVEL = 0; 427 | GCC_PREPROCESSOR_DEFINITIONS = ( 428 | "DEBUG=1", 429 | "$(inherited)", 430 | ); 431 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 432 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 433 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 434 | GCC_WARN_UNDECLARED_SELECTOR = YES; 435 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 436 | GCC_WARN_UNUSED_FUNCTION = YES; 437 | GCC_WARN_UNUSED_VARIABLE = YES; 438 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 439 | MTL_ENABLE_DEBUG_INFO = YES; 440 | ONLY_ACTIVE_ARCH = YES; 441 | SDKROOT = iphoneos; 442 | TARGETED_DEVICE_FAMILY = "1,2"; 443 | }; 444 | name = Debug; 445 | }; 446 | D35854401B9532D700B5FA1F /* Release */ = { 447 | isa = XCBuildConfiguration; 448 | buildSettings = { 449 | ALWAYS_SEARCH_USER_PATHS = NO; 450 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 451 | CLANG_CXX_LIBRARY = "libc++"; 452 | CLANG_ENABLE_MODULES = YES; 453 | CLANG_ENABLE_OBJC_ARC = YES; 454 | CLANG_WARN_BOOL_CONVERSION = YES; 455 | CLANG_WARN_CONSTANT_CONVERSION = YES; 456 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 457 | CLANG_WARN_EMPTY_BODY = YES; 458 | CLANG_WARN_ENUM_CONVERSION = YES; 459 | CLANG_WARN_INT_CONVERSION = YES; 460 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 461 | CLANG_WARN_UNREACHABLE_CODE = YES; 462 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 463 | CODE_SIGN_IDENTITY = "iPhone Developer"; 464 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 465 | COPY_PHASE_STRIP = NO; 466 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 467 | ENABLE_NS_ASSERTIONS = NO; 468 | ENABLE_STRICT_OBJC_MSGSEND = YES; 469 | GCC_C_LANGUAGE_STANDARD = gnu99; 470 | GCC_NO_COMMON_BLOCKS = YES; 471 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 472 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 473 | GCC_WARN_UNDECLARED_SELECTOR = YES; 474 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 475 | GCC_WARN_UNUSED_FUNCTION = YES; 476 | GCC_WARN_UNUSED_VARIABLE = YES; 477 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 478 | MTL_ENABLE_DEBUG_INFO = NO; 479 | SDKROOT = iphoneos; 480 | TARGETED_DEVICE_FAMILY = "1,2"; 481 | VALIDATE_PRODUCT = YES; 482 | }; 483 | name = Release; 484 | }; 485 | D35854421B9532D700B5FA1F /* Debug */ = { 486 | isa = XCBuildConfiguration; 487 | buildSettings = { 488 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 489 | CODE_SIGN_IDENTITY = "iPhone Developer"; 490 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 491 | INFOPLIST_FILE = TYAlertControllerDemo/Info.plist; 492 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 493 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 494 | PRODUCT_BUNDLE_IDENTIFIER = com.tanyang.TYAlertControllerDemo; 495 | PRODUCT_NAME = "$(TARGET_NAME)"; 496 | PROVISIONING_PROFILE = ""; 497 | }; 498 | name = Debug; 499 | }; 500 | D35854431B9532D700B5FA1F /* Release */ = { 501 | isa = XCBuildConfiguration; 502 | buildSettings = { 503 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 504 | CODE_SIGN_IDENTITY = "iPhone Developer"; 505 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 506 | INFOPLIST_FILE = TYAlertControllerDemo/Info.plist; 507 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 508 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 509 | PRODUCT_BUNDLE_IDENTIFIER = com.tanyang.TYAlertControllerDemo; 510 | PRODUCT_NAME = "$(TARGET_NAME)"; 511 | PROVISIONING_PROFILE = ""; 512 | }; 513 | name = Release; 514 | }; 515 | D35854451B9532D700B5FA1F /* Debug */ = { 516 | isa = XCBuildConfiguration; 517 | buildSettings = { 518 | BUNDLE_LOADER = "$(TEST_HOST)"; 519 | FRAMEWORK_SEARCH_PATHS = ( 520 | "$(SDKROOT)/Developer/Library/Frameworks", 521 | "$(inherited)", 522 | ); 523 | GCC_PREPROCESSOR_DEFINITIONS = ( 524 | "DEBUG=1", 525 | "$(inherited)", 526 | ); 527 | INFOPLIST_FILE = TYAlertControllerDemoTests/Info.plist; 528 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 529 | PRODUCT_NAME = "$(TARGET_NAME)"; 530 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TYAlertControllerDemo.app/TYAlertControllerDemo"; 531 | }; 532 | name = Debug; 533 | }; 534 | D35854461B9532D700B5FA1F /* Release */ = { 535 | isa = XCBuildConfiguration; 536 | buildSettings = { 537 | BUNDLE_LOADER = "$(TEST_HOST)"; 538 | FRAMEWORK_SEARCH_PATHS = ( 539 | "$(SDKROOT)/Developer/Library/Frameworks", 540 | "$(inherited)", 541 | ); 542 | INFOPLIST_FILE = TYAlertControllerDemoTests/Info.plist; 543 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 544 | PRODUCT_NAME = "$(TARGET_NAME)"; 545 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TYAlertControllerDemo.app/TYAlertControllerDemo"; 546 | }; 547 | name = Release; 548 | }; 549 | /* End XCBuildConfiguration section */ 550 | 551 | /* Begin XCConfigurationList section */ 552 | D35854191B9532D700B5FA1F /* Build configuration list for PBXProject "TYAlertControllerDemo" */ = { 553 | isa = XCConfigurationList; 554 | buildConfigurations = ( 555 | D358543F1B9532D700B5FA1F /* Debug */, 556 | D35854401B9532D700B5FA1F /* Release */, 557 | ); 558 | defaultConfigurationIsVisible = 0; 559 | defaultConfigurationName = Release; 560 | }; 561 | D35854411B9532D700B5FA1F /* Build configuration list for PBXNativeTarget "TYAlertControllerDemo" */ = { 562 | isa = XCConfigurationList; 563 | buildConfigurations = ( 564 | D35854421B9532D700B5FA1F /* Debug */, 565 | D35854431B9532D700B5FA1F /* Release */, 566 | ); 567 | defaultConfigurationIsVisible = 0; 568 | defaultConfigurationName = Release; 569 | }; 570 | D35854441B9532D700B5FA1F /* Build configuration list for PBXNativeTarget "TYAlertControllerDemoTests" */ = { 571 | isa = XCConfigurationList; 572 | buildConfigurations = ( 573 | D35854451B9532D700B5FA1F /* Debug */, 574 | D35854461B9532D700B5FA1F /* Release */, 575 | ); 576 | defaultConfigurationIsVisible = 0; 577 | defaultConfigurationName = Release; 578 | }; 579 | /* End XCConfigurationList section */ 580 | }; 581 | rootObject = D35854161B9532D700B5FA1F /* Project object */; 582 | } 583 | --------------------------------------------------------------------------------