├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── SPAlertController.podspec
├── SPAlertController
├── SPAlertAction.swift
├── SPAlertAnimation.swift
├── SPAlertController+Public.swift
├── SPAlertController+transitionDelegate.swift
├── SPAlertController.swift
├── SPAlertControllerActionView.swift
├── SPAlertControllerDelegate.swift
├── SPAlertPresentationController.swift
├── SPConstant.swift
├── SPInteractiveTransition.swift
├── SPInterfaceActionItemSeparatorView.swift
├── SPInterfaceActionSequenceView.swift
├── SPInterfaceHeaderScrollView.swift
└── SPOverlayView.swift
└── Swift_SPAlertController
├── Carthage
└── Build
│ ├── .SPAlertController.version
│ └── iOS
│ ├── SPAlertController.framework.dSYM
│ └── Contents
│ │ ├── Info.plist
│ │ └── Resources
│ │ └── DWARF
│ │ └── SPAlertController
│ └── SPAlertController.framework
│ ├── Headers
│ ├── SPAlertController-Swift.h
│ └── SPAlertController.h
│ ├── Info.plist
│ ├── Modules
│ ├── SPAlertController.swiftmodule
│ │ ├── arm.swiftdoc
│ │ ├── arm.swiftmodule
│ │ ├── arm64-apple-ios.swiftdoc
│ │ ├── arm64-apple-ios.swiftmodule
│ │ ├── arm64.swiftdoc
│ │ ├── arm64.swiftmodule
│ │ ├── armv7-apple-ios.swiftdoc
│ │ ├── armv7-apple-ios.swiftmodule
│ │ ├── armv7.swiftdoc
│ │ ├── armv7.swiftmodule
│ │ ├── i386-apple-ios-simulator.swiftdoc
│ │ ├── i386-apple-ios-simulator.swiftmodule
│ │ ├── i386.swiftdoc
│ │ ├── i386.swiftmodule
│ │ ├── x86_64-apple-ios-simulator.swiftdoc
│ │ ├── x86_64-apple-ios-simulator.swiftmodule
│ │ ├── x86_64.swiftdoc
│ │ └── x86_64.swiftmodule
│ └── module.modulemap
│ └── SPAlertController
├── SPAlertController
├── Info.plist
├── SPAlertAction.swift
├── SPAlertAnimation.swift
├── SPAlertController+Public.swift
├── SPAlertController+transitionDelegate.swift
├── SPAlertController.h
├── SPAlertController.swift
├── SPAlertControllerActionView.swift
├── SPAlertControllerDelegate.swift
├── SPAlertPresentationController.swift
├── SPConstant.swift
├── SPInteractiveTransition.swift
├── SPInterfaceActionItemSeparatorView.swift
├── SPInterfaceActionSequenceView.swift
├── SPInterfaceHeaderScrollView.swift
└── SPOverlayView.swift
├── Swift_SPAlertController.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
│ └── xcuserdata
│ │ └── ETrans.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
├── xcshareddata
│ └── xcschemes
│ │ └── SPAlertController.xcscheme
└── xcuserdata
│ └── ETrans.xcuserdatad
│ ├── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
│ └── xcschemes
│ └── xcschememanagement.plist
└── Swift_SPAlertController
├── AppDelegate.swift
├── Assets.xcassets
├── AppIcon-1.appiconset
│ └── Contents.json
├── AppIcon.appiconset
│ └── Contents.json
├── Contents.json
├── publish_0.imageset
│ ├── Contents.json
│ ├── publish_0@2x.png
│ └── publish_0@3x.png
├── publish_1.imageset
│ ├── Contents.json
│ ├── publish_1@2x.png
│ └── publish_1@3x.png
├── publish_10.imageset
│ ├── Contents.json
│ ├── publish_10@2x.png
│ └── publish_10@3x.png
├── publish_11.imageset
│ ├── Contents.json
│ ├── publish_11@2x.png
│ └── publish_11@3x.png
├── publish_2.imageset
│ ├── Contents.json
│ ├── publish_2@2x.png
│ └── publish_2@3x.png
├── publish_3.imageset
│ ├── Contents.json
│ ├── publish_3@2x.png
│ └── publish_3@3x.png
├── publish_4.imageset
│ ├── Contents.json
│ ├── publish_4@2x.png
│ └── publish_4@3x.png
├── publish_5.imageset
│ ├── Contents.json
│ ├── publish_5@2x.png
│ └── publish_5@3x.png
├── publish_6.imageset
│ ├── Contents.json
│ ├── publish_6@2x.png
│ └── publish_6@3x.png
├── publish_7.imageset
│ ├── Contents.json
│ ├── publish_7@2x.png
│ └── publish_7@3x.png
├── publish_8.imageset
│ ├── Contents.json
│ ├── publish_8@2x.png
│ └── publish_8@3x.png
├── publish_9.imageset
│ ├── Contents.json
│ ├── publish_9@2x.png
│ └── publish_9@3x.png
├── success.imageset
│ ├── Contents.json
│ └── 勾.png
├── telephone.imageset
│ ├── Contents.json
│ ├── telephone@2x.png
│ └── telephone@3x.png
├── video.imageset
│ ├── Contents.json
│ ├── video@2x.png
│ └── video@3x.png
├── wechatLogo.imageset
│ ├── Contents.json
│ ├── wechatLogo@2x.png
│ └── wechatLogo@3x.png
├── zhiwen.imageset
│ ├── Contents.json
│ ├── zhiwen@2x.png
│ └── zhiwen@3x.png
├── 减号.imageset
│ ├── Contents.json
│ ├── 减号-1.png
│ ├── 减号-2.png
│ └── 减号.png
├── 加号.imageset
│ ├── Contents.json
│ ├── 加号-1.png
│ ├── 加号-3.png
│ └── 加号-4.png
├── 取消.imageset
│ ├── Contents.json
│ ├── 叉-1.png
│ ├── 叉-2.png
│ └── 叉-3.png
└── 苹果logo.imageset
│ ├── Contents.json
│ └── 苹果logo.png
├── Base.lproj
├── LaunchScreen.storyboard
└── Main.storyboard
├── CustomOverlayView.swift
├── CustomViews
├── CustomView1
│ ├── SendAlertView.swift
│ └── SendAlertView.xib
├── CustomView2
│ ├── MyView.swift
│ ├── MyView.xib
│ ├── PassWordView.h
│ ├── PassWordView.m
│ └── Swift_SPAlertController-Bridging-Header.h
├── CustomView3
│ ├── ShoppingCartCell.swift
│ ├── ShoppingCartCell.xib
│ └── ShoppingCartView.swift
├── CustomView4
│ └── CommodityListView.swift
├── CustomView5
│ ├── PickerView.swift
│ └── PickerView.xib
├── CustomView6
│ ├── HCSStarRatingView.h
│ ├── HCSStarRatingView.m
│ └── ScoreView.swift
└── CustomView7
│ └── MyCenterView.swift
├── DLog.swift
├── DynamicBlurView
├── BlurLayer.swift
├── CGContext+CGImage.swift
├── CGImage+Accelerate.swift
├── CaptureQuality.swift
├── DynamicBlurView.h
├── DynamicBlurView.swift
├── TrackingMode.swift
└── UIImage+Blur.swift
├── Images
├── image0.jpg
├── image1.jpg
├── image2.jpg
├── image3.jpg
├── image4.jpg
├── image5.jpg
├── image6.jpg
├── image7.jpg
├── image8.jpg
├── image9.jpg
├── send0.jpeg
├── send1.jpeg
├── 背景1.jpg
└── 背景2.jpg
├── Info.plist
├── Nibloadable.swift
├── ViewController+Alert.swift
├── ViewController+Attributed.swift
├── ViewController+Custom.swift
├── ViewController+Sheet.swift
├── ViewController+Special.swift
├── ViewController+background.swift
└── ViewController.swift
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OS X
2 | .DS_Store
3 |
4 | # Xcode
5 | build/
6 | *.pbxuser
7 | !default.pbxuser
8 | *.mode1v3
9 | !default.mode1v3
10 | *.mode2v3
11 | !default.mode2v3
12 | *.perspectivev3
13 | !default.perspectivev3
14 | xcuserdata/
15 | *.xccheckout
16 | profile
17 | *.moved-aside
18 | DerivedData
19 | *.hmap
20 | *.ipa
21 |
22 | # Bundler
23 | .bundle
24 |
25 | # Carthage
26 |
27 | # We recommend against adding the Pods directory to your .gitignore. However
28 | # you should judge for yourself, the pros and cons are mentioned at:
29 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
30 | #
31 | # Note: if you ignore the Pods directory, make sure to uncomment
32 | # `pod install` in .travis.yml
33 | #
34 | # Pods/
35 | .idea
36 | /Tests/FailureDiffs
37 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright © 2018-2019 leshengping (lesp163@163.com)
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is furnished
8 | to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
21 |
--------------------------------------------------------------------------------
/SPAlertController.podspec:
--------------------------------------------------------------------------------
1 | #
2 | # Be sure to run `pod spec lint SPAlertController.podspec' to ensure this is a
3 | # valid spec and to remove all comments including this before submitting the spec.
4 | #
5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html
6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/
7 | #
8 |
9 | Pod::Spec.new do |s|
10 |
11 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
12 | #
13 | # These will help people to find your library, and whilst it
14 | # can feel like a chore to fill in it's definitely to your advantage. The
15 | # summary should be tweet-length, and the description more in depth.
16 | #
17 |
18 | s.name = "SPAlertController"
19 | s.version = "1.0.0"
20 | s.summary = "万能提醒对话框.自定义弹窗"
21 |
22 | # This description is used to generate tags and improve search results.
23 | # * Think: What does it do? Why did you write it? What is the focus?
24 | # * Try to keep it short, snappy and to the point.
25 | # * Write the description between the DESC delimiters below.
26 | # * Finally, don't worry about the indent, CocoaPods strips it!
27 |
28 | s.homepage = "https://github.com/dongxiexidu/SPAlertController"
29 | # s.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif"
30 |
31 |
32 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
33 | #
34 | # Licensing your code is important. See http://choosealicense.com for more info.
35 | # CocoaPods will detect a license file if there is a named LICENSE*
36 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'.
37 | #
38 |
39 | s.license = "MIT"
40 | # s.license = { :type => "MIT", :file => "FILE_LICENSE" }
41 |
42 |
43 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
44 | #
45 | # Specify the authors of the library, with email addresses. Email addresses
46 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also
47 | # accepts just a name if you'd rather not provide an email address.
48 | #
49 | # Specify a social_media_url where others can refer to, for example a twitter
50 | # profile URL.
51 | #
52 |
53 | s.author = { "dongxiexidu" => "863223764@qq.com" }
54 | # Or just: s.author = "dongxiexidu"
55 | # s.authors = { "dongxiexidu" => "" }
56 | # s.social_media_url = "https://www.jianshu.com/u/6f76b136c31e"
57 |
58 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
59 | #
60 | # If this Pod runs only on iOS or OS X, then specify the platform and
61 | # the deployment target. You can optionally include the target after the platform.
62 | #
63 |
64 | s.platform = :ios
65 | s.platform = :ios, "9.0"
66 | s.swift_versions = '5.0'
67 |
68 | # When using multiple platforms
69 | s.ios.deployment_target = "9.0"
70 | # s.osx.deployment_target = "10.7"
71 | # s.watchos.deployment_target = "2.0"
72 | # s.tvos.deployment_target = "9.0"
73 |
74 |
75 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
76 | #
77 | # Specify the location from where the source should be retrieved.
78 | # Supports git, hg, bzr, svn and HTTP.
79 | #
80 |
81 | s.source = { :git => "https://github.com/dongxiexidu/SPAlertController.git", :tag => s.version }
82 |
83 |
84 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
85 | #
86 | # CocoaPods is smart about how it includes source code. For source files
87 | # giving a folder will include any swift, h, m, mm, c & cpp files.
88 | # For header files it will include any header in the folder.
89 | # Not including the public_header_files will make all headers public.
90 | #
91 |
92 | s.source_files = "SPAlertController"
93 | s.exclude_files = "Classes/Exclude"
94 |
95 | end
96 |
--------------------------------------------------------------------------------
/SPAlertController/SPAlertAction.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SPAlertAction.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2019/12/6.
6 | // Copyright © 2019 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public class SPAlertAction: NSObject {
12 |
13 | /// Whether button should dismiss popup when tapped
14 | open var dismissOnTap = true
15 |
16 | public var title: String? {
17 | didSet{
18 | self.propertyChangedClosure?(self,true)
19 | }
20 | }
21 | /// action的富文本标题
22 | public var attributedTitle: NSAttributedString? {
23 | didSet {
24 | self.propertyChangedClosure?(self,true)
25 | }
26 | }
27 | /// action的图标,位于title的左边
28 | public var image: UIImage? {
29 | didSet {
30 | self.propertyChangedClosure?(self,true)
31 | }
32 | }
33 | /// title跟image之间的间距
34 | public var imageTitleSpacing: CGFloat = 0 {
35 | didSet{
36 | self.propertyChangedClosure?(self,true)
37 | }
38 | }
39 | /// 样式
40 | public var style: SPAlertActionStyle = .default
41 | /// 是否能点击,默认为YES
42 | public var isEnabled: Bool = true {
43 | didSet{ // enabled改变不需要更新布局
44 | self.propertyChangedClosure?(self,false)
45 | }
46 | }
47 | /// action的标题颜色,这个颜色只是普通文本的颜色,富文本颜色需要用NSForegroundColorAttributeName
48 | public var titleColor: UIColor = .black {
49 | didSet{// 颜色改变不需要更新布局
50 | self.propertyChangedClosure?(self,false)
51 | }
52 | }
53 | /// action的标题字体,如果文字太长显示不全,会自动改变字体自适应按钮宽度,最多压缩文字为原来的0.5倍封顶
54 | public var titleFont: UIFont = UIFont.systemFont(ofSize: SP_ACTION_TITLE_FONTSIZE) {
55 | didSet{// 字体改变需要更新布局
56 | self.propertyChangedClosure?(self,true)
57 | }
58 | }
59 | /// action的标题的内边距,如果在不改变字体的情况下想增大action的高度,可以设置该属性的top和bottom值,默认UIEdgeInsetsMake(0, 15, 0, 15)
60 | public var titleEdgeInsets: UIEdgeInsets = .init(top: 0, left: 15, bottom: 0, right: 15)
61 |
62 | public var handler: ((SPAlertAction) ->Void)?
63 | //当在addAction之后设置action属性时,会回调这个block,设置相应控件的字体、颜色等
64 | /// 如果没有这个block,那使用时,只有在addAction之前设置action的属性才有效
65 | internal var propertyChangedClosure: ((SPAlertAction, Bool) ->Void)?
66 |
67 | public class func action(withTitle title: String?,
68 | style: SPAlertActionStyle,
69 | handler: @escaping (SPAlertAction)->Void) -> SPAlertAction {
70 | let action = SPAlertAction.init(title: title, style: style, handler: handler)
71 | return action
72 | }
73 |
74 | convenience init(title: String?, style: SPAlertActionStyle, handler: @escaping ((SPAlertAction) ->Void)) {
75 |
76 | self.init()
77 | self.title = title
78 | self.style = style
79 | self.handler = handler
80 |
81 | if style == .destructive {
82 | self.titleColor = .red
83 | self.titleFont = UIFont.systemFont(ofSize: SP_ACTION_TITLE_FONTSIZE)
84 | } else if style == .cancel {
85 | self.titleColor = .black
86 | self.titleFont = UIFont.boldSystemFont(ofSize: SP_ACTION_TITLE_FONTSIZE)
87 | } else {
88 | self.titleFont = UIFont.systemFont(ofSize: SP_ACTION_TITLE_FONTSIZE)
89 | self.titleColor = .black
90 | }
91 | }
92 |
93 | }
94 |
95 | extension SPAlertAction: NSCopying{
96 | // 由于要对装载action的数组进行拷贝,所以SPAlertAction也需要支持拷贝
97 | public func copy(with zone: NSZone? = nil) -> Any {
98 | let action = SPAlertAction()
99 | action.title = self.title
100 | action.attributedTitle = self.attributedTitle
101 | action.image = self.image
102 | action.imageTitleSpacing = self.imageTitleSpacing
103 | action.style = self.style
104 | action.isEnabled = self.isEnabled
105 | action.titleColor = self.titleColor
106 | action.titleFont = self.titleFont
107 | action.titleEdgeInsets = self.titleEdgeInsets
108 | action.handler = self.handler
109 | action.propertyChangedClosure = self.propertyChangedClosure
110 |
111 | return action
112 | }
113 |
114 |
115 | }
116 |
--------------------------------------------------------------------------------
/SPAlertController/SPAlertController+transitionDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SPAlertController+transitionDelegate.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2019/12/7.
6 | // Copyright © 2019 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | //FIXME: 文件名修改为`SPAlertController+transitioningDelegate`
12 |
13 | //SPAlertController自定义转场动画,需要遵守`UIViewControllerTransitioningDelegate`,实现必要的协议
14 | //MARK: UIViewControllerTransitioningDelegate
15 | extension SPAlertController: UIViewControllerTransitioningDelegate {
16 |
17 | // 2.如何弹出的动画
18 | public func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
19 |
20 | return SPAlertAnimation.animationIsPresenting(isPresenting: true, interactor: self.interactor)
21 | }
22 | // 3.如何dismissed的动画
23 | public func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
24 |
25 | self.view.endEditing(true)
26 | return SPAlertAnimation.animationIsPresenting(isPresenting: false, interactor: self.interactor)
27 | }
28 | // 1.返回一个自定义的UIPresentationController
29 | // 控制控制器跳转的类,是iOS8新增的一个API,用来控制controller之间的跳转特效,
30 | public func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
31 |
32 | return SPAlertPresentationController.init(presentedViewController: presented, presenting: presenting)
33 | }
34 |
35 | public func interactionControllerForDismissal(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
36 | return interactor.hasStarted ? interactor : nil
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/SPAlertController/SPAlertControllerActionView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SPAlertControllerActionView.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2019/12/6.
6 | // Copyright © 2019 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class SPAlertControllerActionView: UIView {
12 |
13 |
14 | public var afterSpacing: CGFloat = SP_LINE_WIDTH
15 |
16 | private var actionButtonConstraints = [NSLayoutConstraint]()
17 | private var methodAction: Selector!
18 | private var target: AnyObject!
19 |
20 |
21 | func addTarget(target: AnyObject, action: Selector) {
22 | self.target = target
23 | self.methodAction = action
24 | }
25 | //手指按下然后在按钮有效事件范围内抬起
26 | @objc func touchUpInside() {
27 | _ = target.perform(self.methodAction, with: self)
28 | }
29 | //手指按下或者手指按下后往外拽再往内拽
30 | @objc func touchDown(button: UIButton) {
31 | guard let alert = self.findAlertController() else{ return }
32 |
33 | if alert.needDialogBlur {
34 | // 需要毛玻璃时,只有白色带透明,毛玻璃效果才更加清澈
35 | button.backgroundColor = SP_SELECTED_COLOR
36 | } else {
37 | // 该颜色比'取消action'上的分割线的颜色浅一些
38 | button.backgroundColor = UIColor.gray.withAlphaComponent(0.1)
39 | }
40 | }
41 | // 手指被迫停止、手指按下后往外拽或者取消,取消的可能性:比如点击的那一刻突然来电话
42 | @objc func touchDragExit(button: UIButton) {
43 | button.backgroundColor = SP_NORMAL_COLOR
44 | }
45 |
46 | func findAlertController() -> SPAlertController? {
47 | var next = self.next
48 | while next != nil {
49 | if next is SPAlertController {
50 | return next as? SPAlertController
51 | } else {
52 | next = next?.next
53 | }
54 | }
55 | return nil
56 | }
57 |
58 | // 安全区域发生了改变,在这个方法里自动适配iPhoneX
59 | override func safeAreaInsetsDidChange() {
60 | if #available(iOS 11.0, *) {
61 | super.safeAreaInsetsDidChange()
62 | self.actionButton.contentEdgeInsets = self.edgeInsetsAddEdgeInsets(i1: self.safeAreaInsets, i2: action.titleEdgeInsets)
63 | } else {
64 | // Fallback on earlier versions
65 | }
66 |
67 | self.setNeedsUpdateConstraints()
68 | }
69 |
70 | override func updateConstraints() {
71 | super.updateConstraints()
72 |
73 | if self.actionButtonConstraints.count > 0 {
74 | NSLayoutConstraint.deactivate(self.actionButtonConstraints)
75 | self.actionButtonConstraints.removeAll()
76 | }
77 |
78 | actionButtonConstraints.append(contentsOf: NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[actionButton]-0-|", options: [], metrics: nil, views: ["actionButton": actionButton]))
79 | actionButtonConstraints.append(contentsOf: NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[actionButton]-0-|", options: [], metrics: nil, views: ["actionButton": actionButton]))
80 | // 按钮必须确认高度,因为其父视图及父视图的父视图乃至根视图都没有设置高度,而且必须用NSLayoutRelationEqual,如果用NSLayoutRelationGreaterThanOrEqual,虽然也能撑起父视图,但是当某个按钮的高度有所变化以后,stackView会将其余按钮按的高度同比增减
81 |
82 | // titleLabel的内容自适应的高度 55
83 | let labelH: CGFloat = actionButton.titleLabel?.intrinsicContentSize.height ?? 0.0
84 | // 按钮的上下内边距之和 0
85 | let topBottom_insetsSum: CGFloat = actionButton.contentEdgeInsets.top+actionButton.contentEdgeInsets.bottom
86 | // 文字的上下间距之和,等于SP_ACTION_HEIGHT-默认字体大小,这是为了保证文字上下有一个固定间距值,不至于使文字靠按钮太紧,,由于按钮内容默认垂直居中,所以最终的顶部或底部间距为topBottom_marginSum/2.0,这个间距,几乎等于18号字体时,最小高度为49时的上下间距 33.5
87 | let topBottom_marginSum: CGFloat = SP_ACTION_HEIGHT-UIFont.systemFont(ofSize: SP_ACTION_TITLE_FONTSIZE).lineHeight
88 |
89 | // 按钮高度
90 | let buttonH = labelH+topBottom_insetsSum+topBottom_marginSum
91 |
92 | var relation = NSLayoutConstraint.Relation.equal
93 | if let stackView = self.superview as? UIStackView, stackView.axis == .horizontal {
94 | relation = .greaterThanOrEqual
95 | }
96 | // 如果字体保持默认18号,只有一行文字时最终结果约等于SP_ACTION_HEIGHT
97 | let buttonHonstraint = NSLayoutConstraint.init(item: actionButton, attribute: .height, relatedBy: relation, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: buttonH)
98 | buttonHonstraint.priority = UILayoutPriority(rawValue: 999)
99 | actionButtonConstraints.append(buttonHonstraint)
100 |
101 | // 给一个最小高度,当按钮字体很小时,如果还按照上面的高度计算,高度会比较小
102 | let minHConstraint = NSLayoutConstraint.init(item: actionButton, attribute: .height, relatedBy: .greaterThanOrEqual, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: SP_ACTION_HEIGHT+topBottom_insetsSum)
103 | minHConstraint.priority = UILayoutPriority.required
104 | self.addConstraints(actionButtonConstraints)
105 | }
106 |
107 | private func edgeInsetsAddEdgeInsets(i1: UIEdgeInsets, i2: UIEdgeInsets) -> UIEdgeInsets {
108 | var bottom: CGFloat = i1.bottom
109 | if bottom > 21 {// 34的高度太大,这里转为21
110 | bottom = 21
111 | }
112 | return .init(top: i1.top+i2.top, left: i1.left+i2.left, bottom: bottom+i2.bottom, right: i1.right+i2.right)
113 | }
114 |
115 | lazy var actionButton: UIButton = {
116 | let btn = UIButton.init(type: .custom)
117 | btn.backgroundColor = SP_NORMAL_COLOR
118 | btn.translatesAutoresizingMaskIntoConstraints = false
119 | btn.titleLabel?.textAlignment = .center
120 | btn.titleLabel?.adjustsFontSizeToFitWidth = true
121 | btn.titleLabel?.baselineAdjustment = .alignCenters
122 | btn.titleLabel?.minimumScaleFactor = 0.5
123 | btn.addTarget(self, action: #selector(touchUpInside), for: .touchUpInside)
124 | btn.addTarget(self, action: #selector(touchDown), for: [.touchDown, .touchDragInside])
125 | btn.addTarget(self, action: #selector(touchDragExit), for: [.touchDragExit, .touchUpOutside, .touchCancel])
126 | self.addSubview(btn)
127 | return btn
128 | }()
129 |
130 | public var action: SPAlertAction! {
131 | didSet {
132 | self.actionButton.titleLabel?.font = action.titleFont
133 | if action.isEnabled == true {
134 | self.actionButton.setTitleColor(action.titleColor, for: .normal)
135 | } else {
136 | self.actionButton.setTitleColor(.lightGray, for: .normal)
137 | }
138 |
139 | // 注意不能赋值给按钮的titleEdgeInsets,当只有文字时,按钮的titleEdgeInsets设置top和bottom值无效
140 | self.actionButton.contentEdgeInsets = action.titleEdgeInsets
141 | self.actionButton.isEnabled = action.isEnabled
142 | if action.attributedTitle != nil {
143 | // 这里之所以要设置按钮颜色为黑色,是因为如果外界在addAction:之后设置按钮的富文本,那么富文本的颜色在没有采用NSForegroundColorAttributeName的情况下会自动读取按钮上普通文本的颜色,在addAction:之前设置会保持默认色(黑色),为了在addAction:前后设置富文本保持统一,这里先将按钮置为黑色,富文本就会是黑色
144 | self.actionButton.setTitleColor(.black, for: .normal)
145 | if action.attributedTitle!.string.contains("\n") || action.attributedTitle!.string.contains("\r") {
146 | self.actionButton.titleLabel?.lineBreakMode = .byWordWrapping
147 | }
148 | self.actionButton.setAttributedTitle(action.attributedTitle!, for: .normal)
149 | // 设置完富文本之后,还原按钮普通文本的颜色,其实这行代码加不加都不影响,只是为了让按钮普通文本的颜色保持跟action.titleColor一致
150 | self.actionButton.setTitleColor(action.titleColor, for: .normal)
151 | } else {
152 |
153 | if let title = action.title {
154 | if title.contains("\n") || title.contains("\r") {
155 | self.actionButton.titleLabel?.lineBreakMode = .byWordWrapping
156 | }
157 | self.actionButton.setTitle(title, for: .normal)
158 | }
159 |
160 | }
161 | self.actionButton.setImage(action.image, for: .normal)
162 | self.actionButton.titleEdgeInsets = .init(top: 0, left: action.imageTitleSpacing, bottom: 0, right: -action.imageTitleSpacing)
163 | self.actionButton.imageEdgeInsets = .init(top: 0, left: -action.imageTitleSpacing, bottom: 0, right: action.imageTitleSpacing)
164 | }
165 | }
166 | }
167 |
--------------------------------------------------------------------------------
/SPAlertController/SPAlertControllerDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SPAlertControllerDelegate.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2019/12/6.
6 | // Copyright © 2019 lidongxi. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | //: NSObject
12 | protocol SPAlertControllerDelegate{
13 |
14 | }
15 |
16 | extension SPAlertControllerDelegate {
17 |
18 | /// 将要present
19 | func willPresentAlertController(alertController: SPAlertController) {
20 |
21 | }
22 | /// 已经present
23 | func didPresentAlertController(alertController: SPAlertController) {
24 |
25 | }
26 | /// 将要dismiss
27 | func willDismissAlertController(alertController: SPAlertController) {
28 |
29 | }
30 | /// 已经dismiss
31 | func didDismissAlertController(alertController: SPAlertController) {
32 |
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/SPAlertController/SPAlertPresentationController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SPAlertPresentationController.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2019/12/6.
6 | // Copyright © 2019 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | // UIPresentationController控制控制器跳转的类,是iOS8新增的一个API,用来控制 controller之间的跳转特效,
12 | // 例如:显示一个模态窗口,大小和位置是自定义的,遮罩在原来的页面
13 | class SPAlertPresentationController: UIPresentationController {
14 |
15 |
16 | override init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController?) {
17 | super.init(presentedViewController: presentedViewController, presenting: presentingViewController)
18 | }
19 |
20 | override func containerViewWillLayoutSubviews() {
21 | super.containerViewWillLayoutSubviews()
22 | if let containerV = self.containerView {
23 | self.overlayView.frame = containerV.bounds
24 | }
25 | }
26 |
27 | override func containerViewDidLayoutSubviews() {
28 | super.containerViewDidLayoutSubviews()
29 | }
30 |
31 | // MARK: - 1.将要开始弹出
32 | override func presentationTransitionWillBegin() {
33 | super.presentationTransitionWillBegin()
34 |
35 | let alertController = self.presentedViewController as! SPAlertController
36 | self.overlayView.setAppearanceStyle(appearanceStyle: alertController.backgroundViewAppearanceStyle, alpha: alertController.backgroundViewAlpha)
37 | // 遮罩的alpha值从0~1变化,UIViewControllerTransitionCoordinator协是一个过渡协调器,当执行模态过渡或push过渡时,可以对视图中的其他部分做动画
38 | let coordinator = self.presentedViewController.transitionCoordinator
39 | if let coordinatorT = coordinator {
40 | coordinatorT.animate(alongsideTransition: { (context) in
41 | self.overlayView.alpha = 1.0
42 | }, completion: nil)
43 | } else {
44 | self.overlayView.alpha = 1.0
45 | }
46 | alertController.delegate?.willPresentAlertController(alertController: alertController)
47 |
48 | }
49 | // MARK: - 2.已经弹出
50 | override func presentationTransitionDidEnd(_ completed: Bool) {
51 | super.presentationTransitionDidEnd(completed)
52 |
53 | let alertController = self.presentedViewController as! SPAlertController
54 | alertController.delegate?.didPresentAlertController(alertController: alertController)
55 | }
56 |
57 | // MARK: - 3.即将dismiss
58 | override func dismissalTransitionWillBegin() {
59 | super.dismissalTransitionWillBegin()
60 |
61 | let alertController = self.presentedViewController as! SPAlertController
62 | // 遮罩的alpha值从1~0变化,UIViewControllerTransitionCoordinator协议执行动画可以保证和转场动画同步
63 | let coordinator = self.presentedViewController.transitionCoordinator
64 | if let coordinatorT = coordinator {
65 | coordinatorT.animate(alongsideTransition: { (context) in
66 | self.overlayView.alpha = 0.0
67 | }, completion: nil)
68 | } else {
69 | self.overlayView.alpha = 0.0
70 | }
71 | alertController.delegate?.willDismissAlertController(alertController: alertController)
72 | }
73 | // MARK: - 4.已经dismissed
74 | override func dismissalTransitionDidEnd(_ completed: Bool) {
75 | super.dismissalTransitionDidEnd(completed)
76 |
77 | if completed {
78 | self.overlayView.removeFromSuperview()
79 | }
80 | let alertController = self.presentedViewController as! SPAlertController
81 | alertController.delegate?.didDismissAlertController(alertController: alertController)
82 | }
83 |
84 |
85 | override var frameOfPresentedViewInContainerView: CGRect{
86 | return self.presentedView!.frame
87 | }
88 |
89 |
90 | lazy var overlayView: SPOverlayView = {
91 | let overlay = SPOverlayView.init()
92 | overlay.autoresizingMask = [.flexibleWidth, .flexibleHeight]
93 | let tap = UITapGestureRecognizer.init(target: self, action: #selector(tapOverlayView))
94 | overlay.addGestureRecognizer(tap)
95 | self.containerView?.addSubview(overlay)
96 | return overlay
97 | }()
98 |
99 | @objc func tapOverlayView() {
100 | let alertController = self.presentedViewController as! SPAlertController
101 | // DLog(alertController.backgroundViewAlpha)
102 | if alertController.tapBackgroundViewDismiss {
103 | alertController.dismiss(animated: true, completion: nil)
104 | }
105 | }
106 | // TODO: 没必要吧?
107 | // deinit {
108 | // NotificationCenter.default.removeObserver(self)
109 | // }
110 | }
111 |
--------------------------------------------------------------------------------
/SPAlertController/SPConstant.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SPConstant.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2019/11/27.
6 | // Copyright © 2019 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | let SP_SCREEN_WIDTH: CGFloat = UIScreen.main.bounds.size.width
12 | let SP_SCREEN_HEIGHT: CGFloat = UIScreen.main.bounds.size.height
13 | let SP_LINE_COLOR: UIColor = UIColor.gray.withAlphaComponent(0.3)
14 | let SP_NORMAL_COLOR: UIColor = UIColor.white.withAlphaComponent(0.7)
15 | let SP_SELECTED_COLOR: UIColor = UIColor.init(white: 1.0, alpha: 0.4)
16 | let SP_LINE_WIDTH: CGFloat = 1.0/UIScreen.main.scale
17 | let Is_iPhoneX: Bool = SP_SCREEN_HEIGHT >= 812.0
18 | let SP_STATUS_BAR_HEIGHT: CGFloat = Is_iPhoneX ? 44.0 : 20.0
19 | let SP_ACTION_TITLE_FONTSIZE: CGFloat = 18.0
20 | let SP_ACTION_HEIGHT: CGFloat = 55.0
21 |
22 | public enum SPAlertControllerStyle {
23 | case actionSheet
24 | case alert
25 | }
26 |
27 | public enum SPAlertAnimationType: Int {
28 | case `default`
29 | case fromBottom
30 | case fromTop
31 | case fromRight
32 | case fromLeft
33 |
34 | case shrink
35 | case expand
36 | case fade
37 | case none
38 | }
39 |
40 | public enum SPAlertActionStyle {
41 | case `default`
42 | case cancel
43 | case destructive
44 | }
45 |
46 | public enum SPBackgroundViewAppearanceStyle {
47 | case translucent
48 | case blurDark
49 | case blurExtraLight
50 | case blurLight
51 | }
52 |
53 |
--------------------------------------------------------------------------------
/SPAlertController/SPInteractiveTransition.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SPInteractiveTransition.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2020/1/16.
6 | // Copyright © 2020 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | // Handles interactive transition triggered via pan gesture recognizer on dialog
11 | class SPInteractiveTransition: UIPercentDrivenInteractiveTransition {
12 | // If the interactive transition was started
13 | var hasStarted = false
14 |
15 | // If the interactive transition
16 | var shouldFinish = false
17 |
18 | // The view controller containing the views
19 | // with attached gesture recognizers weak
20 | var viewController: SPAlertController?
21 |
22 | @objc func handlePan(_ sender: UIPanGestureRecognizer) {
23 |
24 | guard let vc = viewController else { return }
25 |
26 | guard let progress = calculateProgress(sender: sender) else { return }
27 | switch sender.state {
28 | case .began:
29 | hasStarted = true
30 | vc.dismiss(animated: true, completion: nil)
31 | case .changed:
32 | shouldFinish = progress > 0.3
33 | update(progress)
34 | case .cancelled:
35 | hasStarted = false
36 | cancel()
37 | case .ended:
38 | hasStarted = false
39 | completionSpeed = 0.55
40 | shouldFinish ? finish() : cancel()
41 | default:
42 | break
43 | }
44 | }
45 | }
46 |
47 | extension SPInteractiveTransition {
48 |
49 | /*!
50 | Translates the pan gesture recognizer position to the progress percentage
51 | - parameter sender: A UIPanGestureRecognizer
52 | - returns: Progress
53 | */
54 | func calculateProgress(sender: UIPanGestureRecognizer) -> CGFloat? {
55 | guard let vc = viewController else { return nil }
56 |
57 | // http://www.thorntech.com/2016/02/ios-tutorial-close-modal-dragging/
58 | let translation = sender.translation(in: vc.view)
59 | let verticalMovement: CGFloat = translation.y / vc.view.bounds.height
60 |
61 | var downwardMovement: Float = 0.0
62 | if viewController?.animationType == .fromTop && viewController?.preferredStyle == .actionSheet {
63 | downwardMovement = fmaxf(Float(-verticalMovement), 0.0)
64 | } else {
65 | downwardMovement = fmaxf(Float(verticalMovement), 0.0)
66 | }
67 | let downwardMovementPercent = fminf(downwardMovement, 1.0)
68 |
69 | let progress = CGFloat(downwardMovementPercent)
70 |
71 | return progress
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/SPAlertController/SPInterfaceActionItemSeparatorView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SPInterfaceActionItemSeparatorView.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2019/11/27.
6 | // Copyright © 2019 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class SPInterfaceActionItemSeparatorView: UIView {
12 |
13 | override init(frame: CGRect) {
14 | super.init(frame: frame)
15 |
16 | self.backgroundColor = SP_LINE_COLOR
17 | }
18 |
19 | required init?(coder: NSCoder) {
20 | fatalError("init(coder:) has not been implemented")
21 | }
22 |
23 | override func layoutSubviews() {
24 | super.layoutSubviews()
25 |
26 | self.backgroundColor = self.frame.size.height > SP_LINE_WIDTH ? UIColor.gray.withAlphaComponent(0.15) : SP_LINE_COLOR
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/SPAlertController/SPOverlayView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SPOverlayView.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2019/12/6.
6 | // Copyright © 2019 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class SPOverlayView: UIView {
12 |
13 | private var presentedView: UIView?
14 | private var effectView: UIVisualEffectView?
15 |
16 | override init(frame: CGRect) {
17 | super.init(frame: frame)
18 |
19 | self.isUserInteractionEnabled = true
20 | }
21 |
22 | required init?(coder: NSCoder) {
23 | fatalError("init(coder:) has not been implemented")
24 | }
25 |
26 | func setAppearanceStyle(appearanceStyle: SPBackgroundViewAppearanceStyle, alpha: CGFloat) {
27 | switch appearanceStyle {
28 | case .translucent:
29 | self.effectView?.removeFromSuperview()
30 | self.effectView = nil
31 | var tempAlpha: CGFloat = alpha
32 | if alpha < 0 {
33 | tempAlpha = 0.5
34 | }
35 | self.backgroundColor = .init(white: 0, alpha: tempAlpha)
36 | self.alpha = 0
37 | case .blurExtraLight:
38 | let blur = UIBlurEffect.init(style: .extraLight)
39 | self.creatVisualEffectView(withBlu: blur, alpha: alpha)
40 |
41 | case .blurLight:
42 | let blur = UIBlurEffect.init(style: .light)
43 | self.creatVisualEffectView(withBlu: blur, alpha: alpha)
44 | case .blurDark:
45 | let blur = UIBlurEffect.init(style: .dark)
46 | self.creatVisualEffectView(withBlu: blur, alpha: alpha)
47 | }
48 | }
49 |
50 | func creatVisualEffectView(withBlu blur: UIBlurEffect, alpha: CGFloat) {
51 | self.backgroundColor = .clear
52 | let effectV = UIVisualEffectView.init(frame: self.bounds)
53 | effectV.effect = blur
54 | effectV.autoresizingMask = [.flexibleWidth, .flexibleHeight]
55 | effectV.isUserInteractionEnabled = false
56 | effectV.alpha = alpha
57 | self.addSubview(effectV)
58 | effectView = effectV
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Carthage/Build/.SPAlertController.version:
--------------------------------------------------------------------------------
1 | {
2 | "Mac" : [
3 |
4 | ],
5 | "watchOS" : [
6 |
7 | ],
8 | "tvOS" : [
9 |
10 | ],
11 | "commitish" : "2d4ff34ead472ebe420af58fa40275b4f6017469",
12 | "iOS" : [
13 | {
14 | "name" : "SPAlertController",
15 | "hash" : "fcd82b990521cde8f90c15f8c7393569b73c033a3988844ab55a878ce0ff328f",
16 | "swiftToolchainVersion" : "5.1.2 (swiftlang-1100.0.278 clang-1100.0.33.9)"
17 | }
18 | ]
19 | }
--------------------------------------------------------------------------------
/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework.dSYM/Contents/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | English
7 | CFBundleIdentifier
8 | com.apple.xcode.dsym.ETrans.SPAlertController
9 | CFBundleInfoDictionaryVersion
10 | 6.0
11 | CFBundlePackageType
12 | dSYM
13 | CFBundleSignature
14 | ????
15 | CFBundleShortVersionString
16 | 1.0
17 | CFBundleVersion
18 | 1
19 |
20 |
21 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework.dSYM/Contents/Resources/DWARF/SPAlertController:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework.dSYM/Contents/Resources/DWARF/SPAlertController
--------------------------------------------------------------------------------
/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Headers/SPAlertController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SPAlertController.h
3 | // SPAlertController
4 | //
5 | // Created by lidongxi on 2020/1/15.
6 | // Copyright © 2020 HeFahu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for SPAlertController.
12 | FOUNDATION_EXPORT double SPAlertControllerVersionNumber;
13 |
14 | //! Project version string for SPAlertController.
15 | FOUNDATION_EXPORT const unsigned char SPAlertControllerVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Info.plist:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Info.plist
--------------------------------------------------------------------------------
/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/arm.swiftdoc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/arm.swiftdoc
--------------------------------------------------------------------------------
/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/arm.swiftmodule:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/arm.swiftmodule
--------------------------------------------------------------------------------
/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/arm64-apple-ios.swiftdoc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/arm64-apple-ios.swiftdoc
--------------------------------------------------------------------------------
/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/arm64-apple-ios.swiftmodule:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/arm64-apple-ios.swiftmodule
--------------------------------------------------------------------------------
/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/arm64.swiftdoc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/arm64.swiftdoc
--------------------------------------------------------------------------------
/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/arm64.swiftmodule:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/arm64.swiftmodule
--------------------------------------------------------------------------------
/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/armv7-apple-ios.swiftdoc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/armv7-apple-ios.swiftdoc
--------------------------------------------------------------------------------
/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/armv7-apple-ios.swiftmodule:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/armv7-apple-ios.swiftmodule
--------------------------------------------------------------------------------
/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/armv7.swiftdoc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/armv7.swiftdoc
--------------------------------------------------------------------------------
/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/armv7.swiftmodule:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/armv7.swiftmodule
--------------------------------------------------------------------------------
/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/i386-apple-ios-simulator.swiftdoc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/i386-apple-ios-simulator.swiftdoc
--------------------------------------------------------------------------------
/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/i386-apple-ios-simulator.swiftmodule:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/i386-apple-ios-simulator.swiftmodule
--------------------------------------------------------------------------------
/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/i386.swiftdoc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/i386.swiftdoc
--------------------------------------------------------------------------------
/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/i386.swiftmodule:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/i386.swiftmodule
--------------------------------------------------------------------------------
/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/x86_64-apple-ios-simulator.swiftdoc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/x86_64-apple-ios-simulator.swiftdoc
--------------------------------------------------------------------------------
/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/x86_64-apple-ios-simulator.swiftmodule:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/x86_64-apple-ios-simulator.swiftmodule
--------------------------------------------------------------------------------
/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/x86_64.swiftdoc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/x86_64.swiftdoc
--------------------------------------------------------------------------------
/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/x86_64.swiftmodule:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/SPAlertController.swiftmodule/x86_64.swiftmodule
--------------------------------------------------------------------------------
/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/Modules/module.modulemap:
--------------------------------------------------------------------------------
1 | framework module SPAlertController {
2 | umbrella header "SPAlertController.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
8 | module SPAlertController.Swift {
9 | header "SPAlertController-Swift.h"
10 | requires objc
11 | }
12 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/SPAlertController:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Carthage/Build/iOS/SPAlertController.framework/SPAlertController
--------------------------------------------------------------------------------
/Swift_SPAlertController/SPAlertController/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/SPAlertController/SPAlertAction.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SPAlertAction.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2019/12/6.
6 | // Copyright © 2019 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public class SPAlertAction: NSObject {
12 |
13 | /// Whether button should dismiss popup when tapped
14 | open var dismissOnTap = true
15 |
16 | public var title: String? {
17 | didSet{
18 | self.propertyChangedClosure?(self,true)
19 | }
20 | }
21 | /// action的富文本标题
22 | public var attributedTitle: NSAttributedString? {
23 | didSet {
24 | self.propertyChangedClosure?(self,true)
25 | }
26 | }
27 | /// action的图标,位于title的左边
28 | public var image: UIImage? {
29 | didSet {
30 | self.propertyChangedClosure?(self,true)
31 | }
32 | }
33 | /// title跟image之间的间距
34 | public var imageTitleSpacing: CGFloat = 0 {
35 | didSet{
36 | self.propertyChangedClosure?(self,true)
37 | }
38 | }
39 | /// 样式
40 | public var style: SPAlertActionStyle = .default
41 | /// 是否能点击,默认为YES
42 | public var isEnabled: Bool = true {
43 | didSet{ // enabled改变不需要更新布局
44 | self.propertyChangedClosure?(self,false)
45 | }
46 | }
47 | /// action的标题颜色,这个颜色只是普通文本的颜色,富文本颜色需要用NSForegroundColorAttributeName
48 | public var titleColor: UIColor = .black {
49 | didSet{// 颜色改变不需要更新布局
50 | self.propertyChangedClosure?(self,false)
51 | }
52 | }
53 | /// action的标题字体,如果文字太长显示不全,会自动改变字体自适应按钮宽度,最多压缩文字为原来的0.5倍封顶
54 | public var titleFont: UIFont = UIFont.systemFont(ofSize: SP_ACTION_TITLE_FONTSIZE) {
55 | didSet{// 字体改变需要更新布局
56 | self.propertyChangedClosure?(self,true)
57 | }
58 | }
59 | /// action的标题的内边距,如果在不改变字体的情况下想增大action的高度,可以设置该属性的top和bottom值,默认UIEdgeInsetsMake(0, 15, 0, 15)
60 | public var titleEdgeInsets: UIEdgeInsets = .init(top: 0, left: 15, bottom: 0, right: 15)
61 |
62 | public var handler: ((SPAlertAction) ->Void)?
63 | //当在addAction之后设置action属性时,会回调这个block,设置相应控件的字体、颜色等
64 | /// 如果没有这个block,那使用时,只有在addAction之前设置action的属性才有效
65 | internal var propertyChangedClosure: ((SPAlertAction, Bool) ->Void)?
66 |
67 | public class func action(withTitle title: String?,
68 | style: SPAlertActionStyle,
69 | handler: @escaping (SPAlertAction)->Void) -> SPAlertAction {
70 | let action = SPAlertAction.init(title: title, style: style, handler: handler)
71 | return action
72 | }
73 |
74 | convenience init(title: String?, style: SPAlertActionStyle, handler: @escaping ((SPAlertAction) ->Void)) {
75 |
76 | self.init()
77 | self.title = title
78 | self.style = style
79 | self.handler = handler
80 |
81 | if style == .destructive {
82 | self.titleColor = .red
83 | self.titleFont = UIFont.systemFont(ofSize: SP_ACTION_TITLE_FONTSIZE)
84 | } else if style == .cancel {
85 | self.titleColor = .black
86 | self.titleFont = UIFont.boldSystemFont(ofSize: SP_ACTION_TITLE_FONTSIZE)
87 | } else {
88 | self.titleFont = UIFont.systemFont(ofSize: SP_ACTION_TITLE_FONTSIZE)
89 | self.titleColor = .black
90 | }
91 | }
92 |
93 | }
94 |
95 | extension SPAlertAction: NSCopying{
96 | // 由于要对装载action的数组进行拷贝,所以SPAlertAction也需要支持拷贝
97 | public func copy(with zone: NSZone? = nil) -> Any {
98 | let action = SPAlertAction()
99 | action.title = self.title
100 | action.attributedTitle = self.attributedTitle
101 | action.image = self.image
102 | action.imageTitleSpacing = self.imageTitleSpacing
103 | action.style = self.style
104 | action.isEnabled = self.isEnabled
105 | action.titleColor = self.titleColor
106 | action.titleFont = self.titleFont
107 | action.titleEdgeInsets = self.titleEdgeInsets
108 | action.handler = self.handler
109 | action.propertyChangedClosure = self.propertyChangedClosure
110 |
111 | return action
112 | }
113 |
114 |
115 | }
116 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/SPAlertController/SPAlertController+transitionDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SPAlertController+transitionDelegate.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2019/12/7.
6 | // Copyright © 2019 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | //FIXME: 文件名修改为`SPAlertController+transitioningDelegate`
12 |
13 | //SPAlertController自定义转场动画,需要遵守`UIViewControllerTransitioningDelegate`,实现必要的协议
14 | //MARK: UIViewControllerTransitioningDelegate
15 | extension SPAlertController: UIViewControllerTransitioningDelegate {
16 |
17 | // 2.如何弹出的动画
18 | public func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
19 |
20 | return SPAlertAnimation.animationIsPresenting(isPresenting: true, interactor: self.interactor)
21 | }
22 | // 3.如何dismissed的动画
23 | public func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
24 |
25 | self.view.endEditing(true)
26 | return SPAlertAnimation.animationIsPresenting(isPresenting: false, interactor: self.interactor)
27 | }
28 | // 1.返回一个自定义的UIPresentationController
29 | // 控制控制器跳转的类,是iOS8新增的一个API,用来控制controller之间的跳转特效,
30 | public func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
31 | return SPAlertPresentationController.init(customOverlay: customOverlayView, presentedViewController: presented, presenting: presenting)
32 | //return SPAlertPresentationController.init(presentedViewController: presented, presenting: presenting)
33 | }
34 |
35 | public func interactionControllerForDismissal(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
36 | return interactor.hasStarted ? interactor : nil
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/SPAlertController/SPAlertController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SPAlertController.h
3 | // SPAlertController
4 | //
5 | // Created by lidongxi on 2020/1/15.
6 | // Copyright © 2020 HeFahu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for SPAlertController.
12 | FOUNDATION_EXPORT double SPAlertControllerVersionNumber;
13 |
14 | //! Project version string for SPAlertController.
15 | FOUNDATION_EXPORT const unsigned char SPAlertControllerVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/SPAlertController/SPAlertControllerActionView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SPAlertControllerActionView.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2019/12/6.
6 | // Copyright © 2019 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class SPAlertControllerActionView: UIView {
12 |
13 |
14 | public var afterSpacing: CGFloat = SP_LINE_WIDTH
15 |
16 | private var actionButtonConstraints = [NSLayoutConstraint]()
17 | private var methodAction: Selector!
18 | private var target: AnyObject!
19 |
20 |
21 | func addTarget(target: AnyObject, action: Selector) {
22 | self.target = target
23 | self.methodAction = action
24 | }
25 | //手指按下然后在按钮有效事件范围内抬起
26 | @objc func touchUpInside() {
27 | _ = target.perform(self.methodAction, with: self)
28 | }
29 | //手指按下或者手指按下后往外拽再往内拽
30 | @objc func touchDown(button: UIButton) {
31 | guard let alert = self.findAlertController() else{ return }
32 |
33 | if alert.needDialogBlur {
34 | // 需要毛玻璃时,只有白色带透明,毛玻璃效果才更加清澈
35 | button.backgroundColor = SP_SELECTED_COLOR
36 | } else {
37 | // 该颜色比'取消action'上的分割线的颜色浅一些
38 | button.backgroundColor = UIColor.gray.withAlphaComponent(0.1)
39 | }
40 | }
41 | // 手指被迫停止、手指按下后往外拽或者取消,取消的可能性:比如点击的那一刻突然来电话
42 | @objc func touchDragExit(button: UIButton) {
43 | button.backgroundColor = SP_NORMAL_COLOR
44 | }
45 |
46 | func findAlertController() -> SPAlertController? {
47 | var next = self.next
48 | while next != nil {
49 | if next is SPAlertController {
50 | return next as? SPAlertController
51 | } else {
52 | next = next?.next
53 | }
54 | }
55 | return nil
56 | }
57 |
58 | // 安全区域发生了改变,在这个方法里自动适配iPhoneX
59 | override func safeAreaInsetsDidChange() {
60 | if #available(iOS 11.0, *) {
61 | super.safeAreaInsetsDidChange()
62 | self.actionButton.contentEdgeInsets = self.edgeInsetsAddEdgeInsets(i1: self.safeAreaInsets, i2: action.titleEdgeInsets)
63 | } else {
64 | // Fallback on earlier versions
65 | }
66 |
67 | self.setNeedsUpdateConstraints()
68 | }
69 |
70 | override func updateConstraints() {
71 | super.updateConstraints()
72 |
73 | if self.actionButtonConstraints.count > 0 {
74 | NSLayoutConstraint.deactivate(self.actionButtonConstraints)
75 | self.actionButtonConstraints.removeAll()
76 | }
77 |
78 | actionButtonConstraints.append(contentsOf: NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[actionButton]-0-|", options: [], metrics: nil, views: ["actionButton": actionButton]))
79 | actionButtonConstraints.append(contentsOf: NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[actionButton]-0-|", options: [], metrics: nil, views: ["actionButton": actionButton]))
80 | // 按钮必须确认高度,因为其父视图及父视图的父视图乃至根视图都没有设置高度,而且必须用NSLayoutRelationEqual,如果用NSLayoutRelationGreaterThanOrEqual,虽然也能撑起父视图,但是当某个按钮的高度有所变化以后,stackView会将其余按钮按的高度同比增减
81 |
82 | // titleLabel的内容自适应的高度 55
83 | let labelH: CGFloat = actionButton.titleLabel?.intrinsicContentSize.height ?? 0.0
84 | // 按钮的上下内边距之和 0
85 | let topBottom_insetsSum: CGFloat = actionButton.contentEdgeInsets.top+actionButton.contentEdgeInsets.bottom
86 | // 文字的上下间距之和,等于SP_ACTION_HEIGHT-默认字体大小,这是为了保证文字上下有一个固定间距值,不至于使文字靠按钮太紧,,由于按钮内容默认垂直居中,所以最终的顶部或底部间距为topBottom_marginSum/2.0,这个间距,几乎等于18号字体时,最小高度为49时的上下间距 33.5
87 | let topBottom_marginSum: CGFloat = SP_ACTION_HEIGHT-UIFont.systemFont(ofSize: SP_ACTION_TITLE_FONTSIZE).lineHeight
88 |
89 | // 按钮高度
90 | let buttonH = labelH+topBottom_insetsSum+topBottom_marginSum
91 |
92 | var relation = NSLayoutConstraint.Relation.equal
93 | if let stackView = self.superview as? UIStackView, stackView.axis == .horizontal {
94 | relation = .greaterThanOrEqual
95 | }
96 | // 如果字体保持默认18号,只有一行文字时最终结果约等于SP_ACTION_HEIGHT
97 | let buttonHonstraint = NSLayoutConstraint.init(item: actionButton, attribute: .height, relatedBy: relation, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: buttonH)
98 | buttonHonstraint.priority = UILayoutPriority(rawValue: 999)
99 | actionButtonConstraints.append(buttonHonstraint)
100 |
101 | // 给一个最小高度,当按钮字体很小时,如果还按照上面的高度计算,高度会比较小
102 | let minHConstraint = NSLayoutConstraint.init(item: actionButton, attribute: .height, relatedBy: .greaterThanOrEqual, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: SP_ACTION_HEIGHT+topBottom_insetsSum)
103 | minHConstraint.priority = UILayoutPriority.required
104 | self.addConstraints(actionButtonConstraints)
105 | }
106 |
107 | private func edgeInsetsAddEdgeInsets(i1: UIEdgeInsets, i2: UIEdgeInsets) -> UIEdgeInsets {
108 | var bottom: CGFloat = i1.bottom
109 | if bottom > 21 {// 34的高度太大,这里转为21
110 | bottom = 21
111 | }
112 | return .init(top: i1.top+i2.top, left: i1.left+i2.left, bottom: bottom+i2.bottom, right: i1.right+i2.right)
113 | }
114 |
115 |
116 | lazy var actionButton: UIButton = {
117 | let btn = UIButton.init(type: .custom)
118 | if #available(iOS 13, *) {
119 | btn.backgroundColor = .tertiarySystemBackground
120 | } else {
121 | btn.backgroundColor = SP_NORMAL_COLOR
122 | }
123 |
124 | btn.translatesAutoresizingMaskIntoConstraints = false
125 | btn.titleLabel?.textAlignment = .center
126 | btn.titleLabel?.adjustsFontSizeToFitWidth = true
127 | btn.titleLabel?.baselineAdjustment = .alignCenters
128 | btn.titleLabel?.minimumScaleFactor = 0.5
129 | btn.addTarget(self, action: #selector(touchUpInside), for: .touchUpInside)
130 | btn.addTarget(self, action: #selector(touchDown), for: [.touchDown, .touchDragInside])
131 | btn.addTarget(self, action: #selector(touchDragExit), for: [.touchDragExit, .touchUpOutside, .touchCancel])
132 | self.addSubview(btn)
133 | return btn
134 | }()
135 |
136 | public var action: SPAlertAction! {
137 | didSet {
138 | self.actionButton.titleLabel?.font = action.titleFont
139 | if action.isEnabled == true {
140 | self.actionButton.setTitleColor(action.titleColor, for: .normal)
141 | } else {
142 | self.actionButton.setTitleColor(.lightGray, for: .normal)
143 | }
144 |
145 | // 注意不能赋值给按钮的titleEdgeInsets,当只有文字时,按钮的titleEdgeInsets设置top和bottom值无效
146 | self.actionButton.contentEdgeInsets = action.titleEdgeInsets
147 | self.actionButton.isEnabled = action.isEnabled
148 | if action.attributedTitle != nil {
149 | // 这里之所以要设置按钮颜色为黑色,是因为如果外界在addAction:之后设置按钮的富文本,那么富文本的颜色在没有采用NSForegroundColorAttributeName的情况下会自动读取按钮上普通文本的颜色,在addAction:之前设置会保持默认色(黑色),为了在addAction:前后设置富文本保持统一,这里先将按钮置为黑色,富文本就会是黑色
150 | self.actionButton.setTitleColor(.black, for: .normal)
151 | if action.attributedTitle!.string.contains("\n") || action.attributedTitle!.string.contains("\r") {
152 | self.actionButton.titleLabel?.lineBreakMode = .byWordWrapping
153 | }
154 | self.actionButton.setAttributedTitle(action.attributedTitle!, for: .normal)
155 | // 设置完富文本之后,还原按钮普通文本的颜色,其实这行代码加不加都不影响,只是为了让按钮普通文本的颜色保持跟action.titleColor一致
156 | self.actionButton.setTitleColor(action.titleColor, for: .normal)
157 | } else {
158 |
159 | if let title = action.title {
160 | if title.contains("\n") || title.contains("\r") {
161 | self.actionButton.titleLabel?.lineBreakMode = .byWordWrapping
162 | }
163 | self.actionButton.setTitle(title, for: .normal)
164 | }
165 |
166 | }
167 | self.actionButton.setImage(action.image, for: .normal)
168 | self.actionButton.titleEdgeInsets = .init(top: 0, left: action.imageTitleSpacing, bottom: 0, right: -action.imageTitleSpacing)
169 | self.actionButton.imageEdgeInsets = .init(top: 0, left: -action.imageTitleSpacing, bottom: 0, right: action.imageTitleSpacing)
170 | }
171 | }
172 | }
173 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/SPAlertController/SPAlertControllerDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SPAlertControllerDelegate.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2019/12/6.
6 | // Copyright © 2019 lidongxi. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | //: NSObject
12 | protocol SPAlertControllerDelegate{
13 |
14 | }
15 |
16 | extension SPAlertControllerDelegate {
17 |
18 | /// 将要present
19 | func willPresentAlertController(alertController: SPAlertController) {
20 |
21 | }
22 | /// 已经present
23 | func didPresentAlertController(alertController: SPAlertController) {
24 |
25 | }
26 | /// 将要dismiss
27 | func willDismissAlertController(alertController: SPAlertController) {
28 |
29 | }
30 | /// 已经dismiss
31 | func didDismissAlertController(alertController: SPAlertController) {
32 |
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/SPAlertController/SPAlertPresentationController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SPAlertPresentationController.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2019/12/6.
6 | // Copyright © 2019 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | // UIPresentationController控制控制器跳转的类,是iOS8新增的一个API,用来控制 controller之间的跳转特效,
12 | // 例如:显示一个模态窗口,大小和位置是自定义的,遮罩在原来的页面
13 | class SPAlertPresentationController: UIPresentationController {
14 |
15 | /// 自定义背景蒙版
16 | var customOverlayView: UIView?
17 | convenience init(customOverlay: UIView?, presentedViewController: UIViewController, presenting presentingViewController: UIViewController?) {
18 | self.init(presentedViewController: presentedViewController, presenting: presentingViewController)
19 | self.customOverlayView = customOverlay
20 | }
21 |
22 |
23 | override init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController?) {
24 | super.init(presentedViewController: presentedViewController, presenting: presentingViewController)
25 | }
26 |
27 | override func containerViewWillLayoutSubviews() {
28 | super.containerViewWillLayoutSubviews()
29 | if let containerV = self.containerView {
30 | self.overlayView.frame = containerV.bounds
31 | //self.customOverlayView?.frame = containerV.bounds
32 | }
33 | }
34 |
35 | override func containerViewDidLayoutSubviews() {
36 | super.containerViewDidLayoutSubviews()
37 | }
38 |
39 | // MARK: - 1.将要开始弹出
40 | override func presentationTransitionWillBegin() {
41 | super.presentationTransitionWillBegin()
42 |
43 | let alertController = self.presentedViewController as! SPAlertController
44 | if customOverlayView == nil {
45 | (overlayView as! SPOverlayView).setAppearanceStyle(appearanceStyle: alertController.backgroundViewAppearanceStyle, alpha: alertController.backgroundViewAlpha)
46 | }
47 |
48 | // 遮罩的alpha值从0~1变化,UIViewControllerTransitionCoordinator协是一个过渡协调器,当执行模态过渡或push过渡时,可以对视图中的其他部分做动画
49 | let coordinator = self.presentedViewController.transitionCoordinator
50 | if let coordinatorT = coordinator {
51 | coordinatorT.animate(alongsideTransition: { (context) in
52 | self.overlayView.alpha = 1.0
53 | }, completion: nil)
54 | } else {
55 | self.overlayView.alpha = 1.0
56 | }
57 | alertController.delegate?.willPresentAlertController(alertController: alertController)
58 |
59 | }
60 | // MARK: - 2.已经弹出
61 | override func presentationTransitionDidEnd(_ completed: Bool) {
62 | super.presentationTransitionDidEnd(completed)
63 |
64 | let alertController = self.presentedViewController as! SPAlertController
65 | alertController.delegate?.didPresentAlertController(alertController: alertController)
66 | }
67 |
68 | // MARK: - 3.即将dismiss
69 | override func dismissalTransitionWillBegin() {
70 | super.dismissalTransitionWillBegin()
71 |
72 | let alertController = self.presentedViewController as! SPAlertController
73 | // 遮罩的alpha值从1~0变化,UIViewControllerTransitionCoordinator协议执行动画可以保证和转场动画同步
74 | let coordinator = self.presentedViewController.transitionCoordinator
75 | if let coordinatorT = coordinator {
76 | coordinatorT.animate(alongsideTransition: { (context) in
77 | self.overlayView.alpha = 0.0
78 | }, completion: nil)
79 | } else {
80 | self.overlayView.alpha = 0.0
81 | }
82 | alertController.delegate?.willDismissAlertController(alertController: alertController)
83 | }
84 | // MARK: - 4.已经dismissed
85 | override func dismissalTransitionDidEnd(_ completed: Bool) {
86 | super.dismissalTransitionDidEnd(completed)
87 |
88 | if completed {
89 | self.overlayView.removeFromSuperview()
90 | }
91 | let alertController = self.presentedViewController as! SPAlertController
92 | alertController.delegate?.didDismissAlertController(alertController: alertController)
93 | }
94 |
95 |
96 | override var frameOfPresentedViewInContainerView: CGRect{
97 | return self.presentedView!.frame
98 | }
99 |
100 | // private lazy var overlayView: CustomOverlayView = {
101 | // let overlay = CustomOverlayView.init()
102 | // overlay.autoresizingMask = [.flexibleWidth, .flexibleHeight]
103 | // let tap = UITapGestureRecognizer.init(target: self, action: #selector(tapOverlayView))
104 | // overlay.addGestureRecognizer(tap)
105 | // self.containerView?.insertSubview(overlay, at: 0)
106 | // // self.containerView?.addSubview(overlay)
107 | // return overlay
108 | // }()
109 | var _overlayView: UIView?
110 | private var overlayView: UIView {
111 | if _overlayView == nil {
112 | if let customView = customOverlayView {
113 | _overlayView = customView
114 | } else {
115 | _overlayView = SPOverlayView.init()
116 | }
117 | _overlayView!.autoresizingMask = [.flexibleWidth, .flexibleHeight]
118 | let tap = UITapGestureRecognizer.init(target: self, action: #selector(tapOverlayView))
119 | _overlayView!.addGestureRecognizer(tap)
120 | self.containerView?.insertSubview(_overlayView!, at: 0)
121 | }
122 | return _overlayView!
123 | }
124 |
125 | // lazy var overlayView: SPOverlayView = {
126 | // let overlay = SPOverlayView.init()
127 | // overlay.autoresizingMask = [.flexibleWidth, .flexibleHeight]
128 | // let tap = UITapGestureRecognizer.init(target: self, action: #selector(tapOverlayView))
129 | // overlay.addGestureRecognizer(tap)
130 | // self.containerView?.addSubview(overlay)
131 | // return overlay
132 | // }()
133 |
134 |
135 | @objc func tapOverlayView() {
136 | let alertController = self.presentedViewController as! SPAlertController
137 | if alertController.tapBackgroundViewDismiss {
138 | alertController.dismiss(animated: true, completion: nil)
139 | }
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/SPAlertController/SPConstant.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SPConstant.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2019/11/27.
6 | // Copyright © 2019 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | let SP_SCREEN_WIDTH: CGFloat = UIScreen.main.bounds.size.width
12 | let SP_SCREEN_HEIGHT: CGFloat = UIScreen.main.bounds.size.height
13 | let SP_LINE_COLOR: UIColor = UIColor.gray.withAlphaComponent(0.3)
14 | let SP_NORMAL_COLOR: UIColor = UIColor.white.withAlphaComponent(0.7)
15 |
16 | let SP_SELECTED_COLOR: UIColor = UIColor.init(white: 1.0, alpha: 0.4)
17 | let SP_LINE_WIDTH: CGFloat = 1.0/UIScreen.main.scale
18 | let Is_iPhoneX: Bool = SP_SCREEN_HEIGHT >= 812.0
19 | let SP_STATUS_BAR_HEIGHT: CGFloat = Is_iPhoneX ? 44.0 : 20.0
20 | let SP_ACTION_TITLE_FONTSIZE: CGFloat = 18.0
21 | let SP_ACTION_HEIGHT: CGFloat = 55.0
22 |
23 | public enum SPAlertControllerStyle {
24 | case actionSheet
25 | case alert
26 | }
27 |
28 | public enum SPAlertAnimationType: Int {
29 | case `default`
30 | case fromBottom
31 | case fromTop
32 | case fromRight
33 | case fromLeft
34 |
35 | case shrink
36 | case expand
37 | case fade
38 | case none
39 | }
40 |
41 | public enum SPAlertActionStyle {
42 | case `default`
43 | case cancel
44 | case destructive
45 | }
46 |
47 | public enum SPBackgroundViewAppearanceStyle {
48 | case translucent
49 | case blurDark
50 | case blurExtraLight
51 | case blurLight
52 | }
53 |
54 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/SPAlertController/SPInteractiveTransition.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SPInteractiveTransition.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2020/1/16.
6 | // Copyright © 2020 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | // Handles interactive transition triggered via pan gesture recognizer on dialog
11 | class SPInteractiveTransition: UIPercentDrivenInteractiveTransition {
12 | // If the interactive transition was started
13 | var hasStarted = false
14 |
15 | // If the interactive transition
16 | var shouldFinish = false
17 |
18 | // The view controller containing the views
19 | // with attached gesture recognizers weak
20 | var viewController: SPAlertController?
21 |
22 | @objc func handlePan(_ sender: UIPanGestureRecognizer) {
23 |
24 | guard let vc = viewController else { return }
25 |
26 | guard let progress = calculateProgress(sender: sender) else { return }
27 | switch sender.state {
28 | case .began:
29 | hasStarted = true
30 | vc.dismiss(animated: true, completion: nil)
31 | case .changed:
32 | shouldFinish = progress > 0.3
33 | update(progress)
34 | case .cancelled:
35 | hasStarted = false
36 | cancel()
37 | case .ended:
38 | hasStarted = false
39 | completionSpeed = 0.55
40 | shouldFinish ? finish() : cancel()
41 | default:
42 | break
43 | }
44 | }
45 | }
46 |
47 | extension SPInteractiveTransition {
48 |
49 | /*!
50 | Translates the pan gesture recognizer position to the progress percentage
51 | - parameter sender: A UIPanGestureRecognizer
52 | - returns: Progress
53 | */
54 | func calculateProgress(sender: UIPanGestureRecognizer) -> CGFloat? {
55 | guard let vc = viewController else { return nil }
56 |
57 | // http://www.thorntech.com/2016/02/ios-tutorial-close-modal-dragging/
58 | let translation = sender.translation(in: vc.view)
59 | let verticalMovement: CGFloat = translation.y / vc.view.bounds.height
60 |
61 | var downwardMovement: Float = 0.0
62 | if viewController?.animationType == .fromTop && viewController?.preferredStyle == .actionSheet {
63 | downwardMovement = fmaxf(Float(-verticalMovement), 0.0)
64 | } else {
65 | downwardMovement = fmaxf(Float(verticalMovement), 0.0)
66 | }
67 | let downwardMovementPercent = fminf(downwardMovement, 1.0)
68 |
69 | let progress = CGFloat(downwardMovementPercent)
70 |
71 | return progress
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/SPAlertController/SPInterfaceActionItemSeparatorView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SPInterfaceActionItemSeparatorView.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2019/11/27.
6 | // Copyright © 2019 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class SPInterfaceActionItemSeparatorView: UIView {
12 |
13 | override init(frame: CGRect) {
14 | super.init(frame: frame)
15 |
16 | self.backgroundColor = SP_LINE_COLOR
17 | }
18 |
19 | required init?(coder: NSCoder) {
20 | fatalError("init(coder:) has not been implemented")
21 | }
22 |
23 | override func layoutSubviews() {
24 | super.layoutSubviews()
25 |
26 | self.backgroundColor = self.frame.size.height > SP_LINE_WIDTH ? UIColor.gray.withAlphaComponent(0.15) : SP_LINE_COLOR
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/SPAlertController/SPOverlayView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SPOverlayView.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2019/12/6.
6 | // Copyright © 2019 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class SPOverlayView: UIView {
12 |
13 | private var presentedView: UIView?
14 | private var effectView: UIVisualEffectView?
15 |
16 | override init(frame: CGRect) {
17 | super.init(frame: frame)
18 |
19 | self.isUserInteractionEnabled = true
20 | }
21 |
22 | required init?(coder: NSCoder) {
23 | fatalError("init(coder:) has not been implemented")
24 | }
25 |
26 | func setAppearanceStyle(appearanceStyle: SPBackgroundViewAppearanceStyle, alpha: CGFloat) {
27 | switch appearanceStyle {
28 | case .translucent:
29 | self.effectView?.removeFromSuperview()
30 | self.effectView = nil
31 | var tempAlpha: CGFloat = alpha
32 | if alpha < 0 {
33 | tempAlpha = 0.5
34 | }
35 | self.backgroundColor = .init(white: 0, alpha: tempAlpha)
36 | self.alpha = 0
37 | case .blurExtraLight:
38 | let blur = UIBlurEffect.init(style: .extraLight)
39 | self.creatVisualEffectView(withBlu: blur, alpha: alpha)
40 |
41 | case .blurLight:
42 | let blur = UIBlurEffect.init(style: .light)
43 | self.creatVisualEffectView(withBlu: blur, alpha: alpha)
44 | case .blurDark:
45 | let blur = UIBlurEffect.init(style: .dark)
46 | self.creatVisualEffectView(withBlu: blur, alpha: alpha)
47 | }
48 | }
49 |
50 | func creatVisualEffectView(withBlu blur: UIBlurEffect, alpha: CGFloat) {
51 | self.backgroundColor = .clear
52 | let effectV = UIVisualEffectView.init(frame: self.bounds)
53 | effectV.effect = blur
54 | effectV.autoresizingMask = [.flexibleWidth, .flexibleHeight]
55 | effectV.isUserInteractionEnabled = false
56 | effectV.alpha = alpha
57 | self.addSubview(effectV)
58 | effectView = effectV
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController.xcodeproj/project.xcworkspace/xcuserdata/ETrans.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController.xcodeproj/project.xcworkspace/xcuserdata/ETrans.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController.xcodeproj/xcshareddata/xcschemes/SPAlertController.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
45 |
51 |
52 |
53 |
54 |
60 |
61 |
67 |
68 |
69 |
70 |
72 |
73 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController.xcodeproj/xcuserdata/ETrans.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
9 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController.xcodeproj/xcuserdata/ETrans.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SPAlertController.xcscheme_^#shared#^_
8 |
9 | isShown
10 |
11 | orderHint
12 | 0
13 |
14 | Swift_SPAlertController.xcscheme
15 |
16 | isShown
17 |
18 | orderHint
19 | 0
20 |
21 |
22 | SuppressBuildableAutocreation
23 |
24 | D6315172238E4FD30043D403
25 |
26 | primary
27 |
28 |
29 | D6A5A3B727F8009E00967937
30 |
31 | primary
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2019/11/27.
6 | // Copyright © 2019 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 | var window: UIWindow?
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 |
23 |
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/AppIcon-1.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_0.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "publish_0@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "publish_0@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_0.imageset/publish_0@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_0.imageset/publish_0@2x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_0.imageset/publish_0@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_0.imageset/publish_0@3x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_1.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "publish_1@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "publish_1@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_1.imageset/publish_1@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_1.imageset/publish_1@2x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_1.imageset/publish_1@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_1.imageset/publish_1@3x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_10.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "publish_10@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "publish_10@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_10.imageset/publish_10@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_10.imageset/publish_10@2x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_10.imageset/publish_10@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_10.imageset/publish_10@3x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_11.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "publish_11@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "publish_11@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_11.imageset/publish_11@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_11.imageset/publish_11@2x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_11.imageset/publish_11@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_11.imageset/publish_11@3x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_2.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "publish_2@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "publish_2@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_2.imageset/publish_2@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_2.imageset/publish_2@2x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_2.imageset/publish_2@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_2.imageset/publish_2@3x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_3.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "publish_3@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "publish_3@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_3.imageset/publish_3@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_3.imageset/publish_3@2x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_3.imageset/publish_3@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_3.imageset/publish_3@3x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_4.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "publish_4@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "publish_4@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_4.imageset/publish_4@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_4.imageset/publish_4@2x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_4.imageset/publish_4@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_4.imageset/publish_4@3x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_5.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "publish_5@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "publish_5@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_5.imageset/publish_5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_5.imageset/publish_5@2x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_5.imageset/publish_5@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_5.imageset/publish_5@3x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_6.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "publish_6@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "publish_6@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_6.imageset/publish_6@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_6.imageset/publish_6@2x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_6.imageset/publish_6@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_6.imageset/publish_6@3x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_7.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "publish_7@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "publish_7@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_7.imageset/publish_7@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_7.imageset/publish_7@2x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_7.imageset/publish_7@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_7.imageset/publish_7@3x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_8.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "publish_8@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "publish_8@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_8.imageset/publish_8@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_8.imageset/publish_8@2x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_8.imageset/publish_8@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_8.imageset/publish_8@3x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_9.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "publish_9@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "publish_9@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_9.imageset/publish_9@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_9.imageset/publish_9@2x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_9.imageset/publish_9@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/publish_9.imageset/publish_9@3x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/success.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "勾.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/success.imageset/勾.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/success.imageset/勾.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/telephone.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "telephone@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "telephone@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/telephone.imageset/telephone@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/telephone.imageset/telephone@2x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/telephone.imageset/telephone@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/telephone.imageset/telephone@3x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/video.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "video@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "video@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/video.imageset/video@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/video.imageset/video@2x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/video.imageset/video@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/video.imageset/video@3x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/wechatLogo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "wechatLogo@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "wechatLogo@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/wechatLogo.imageset/wechatLogo@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/wechatLogo.imageset/wechatLogo@2x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/wechatLogo.imageset/wechatLogo@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/wechatLogo.imageset/wechatLogo@3x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/zhiwen.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "zhiwen@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "zhiwen@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/zhiwen.imageset/zhiwen@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/zhiwen.imageset/zhiwen@2x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/zhiwen.imageset/zhiwen@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/zhiwen.imageset/zhiwen@3x.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/减号.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "减号.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "减号-1.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "减号-2.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/减号.imageset/减号-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/减号.imageset/减号-1.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/减号.imageset/减号-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/减号.imageset/减号-2.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/减号.imageset/减号.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/减号.imageset/减号.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/加号.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "加号-1.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "加号-3.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "加号-4.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/加号.imageset/加号-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/加号.imageset/加号-1.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/加号.imageset/加号-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/加号.imageset/加号-3.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/加号.imageset/加号-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/加号.imageset/加号-4.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/取消.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "叉-1.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "叉-2.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "叉-3.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/取消.imageset/叉-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/取消.imageset/叉-1.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/取消.imageset/叉-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/取消.imageset/叉-2.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/取消.imageset/叉-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/取消.imageset/叉-3.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/苹果logo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "苹果logo.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/苹果logo.imageset/苹果logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Assets.xcassets/苹果logo.imageset/苹果logo.png
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/CustomOverlayView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CustomOverlayView.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2020/1/17.
6 | // Copyright © 2020 HeFahu. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class CustomOverlayView: UIView {
12 |
13 | // MARK: - Appearance
14 |
15 | /// Turns the blur of the overlay view on or off
16 | @objc public dynamic var blurEnabled: Bool {
17 | get { return !blurView.isHidden }
18 | set { blurView.isHidden = !newValue }
19 | }
20 |
21 | /// The blur radius of the overlay view
22 | @objc public dynamic var blurRadius: CGFloat {
23 | get { return blurView.blurRadius }
24 | set { blurView.blurRadius = newValue }
25 | }
26 |
27 | /// Whether the blur view should allow for
28 | /// live rendering of the background
29 | @objc public dynamic var liveBlurEnabled: Bool {
30 | get { return blurView.trackingMode == .common }
31 | set {
32 | if newValue {
33 | blurView.trackingMode = .common
34 | } else {
35 | blurView.trackingMode = .none
36 | }
37 | }
38 | }
39 |
40 | /// The background color of the overlay view
41 | @objc public dynamic var color: UIColor? {
42 | get { return overlay.backgroundColor }
43 | set { overlay.backgroundColor = newValue }
44 | }
45 |
46 | /// The opacity of the overlay view
47 | @objc public dynamic var opacity: CGFloat {
48 | get { return overlay.alpha }
49 | set { overlay.alpha = newValue }
50 | }
51 |
52 | // MARK: - Views
53 |
54 | internal lazy var blurView: DynamicBlurView = {
55 | let blurView = DynamicBlurView(frame: .zero)
56 | blurView.blurRadius = 8
57 | blurView.trackingMode = .none
58 | blurView.isDeepRendering = true
59 | blurView.tintColor = .clear
60 | blurView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
61 | return blurView
62 | }()
63 |
64 | internal lazy var overlay: UIView = {
65 | let overlay = UIView(frame: .zero)
66 | overlay.backgroundColor = .black
67 | overlay.alpha = 0.7
68 | overlay.autoresizingMask = [.flexibleHeight, .flexibleWidth]
69 | return overlay
70 | }()
71 |
72 | // MARK: - Inititalizers
73 |
74 | override init(frame: CGRect) {
75 | super.init(frame: frame)
76 | setupView()
77 | }
78 |
79 | required public init?(coder aDecoder: NSCoder) {
80 | fatalError("init(coder:) has not been implemented")
81 | }
82 |
83 | // MARK: - View setup
84 |
85 | fileprivate func setupView() {
86 |
87 | autoresizingMask = [.flexibleHeight, .flexibleWidth]
88 | backgroundColor = .clear
89 | alpha = 0
90 |
91 | addSubview(blurView)
92 | addSubview(overlay)
93 | }
94 |
95 | }
96 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/CustomViews/CustomView1/SendAlertView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SendAlertView.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2020/1/11.
6 | // Copyright © 2020 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class SendAlertView: UIView,Nibloadable {
12 |
13 | @IBOutlet weak var userIconView: UIImageView!
14 | @IBOutlet weak var nameLabel: UILabel!
15 | @IBOutlet weak var contentImageView: UIImageView!
16 | @IBOutlet weak var contentHeightConstraint: NSLayoutConstraint!
17 | @IBOutlet weak var textViewHeightConstraint: NSLayoutConstraint!
18 |
19 | @IBOutlet weak var textView: UITextView!
20 |
21 | var contentImage: UIImage? {
22 | didSet{
23 | contentImageView.image = contentImage
24 | guard let img = contentImage else { return }
25 | var contentH: CGFloat = 0
26 | let imgRatio: CGFloat = img.size.height/img.size.width
27 | let contentW: CGFloat = bounds.size.width-30// 30是contentImageView的左右间距之和
28 | if img.size.height < contentW {
29 | contentH = img.size.height
30 | } else {
31 | contentH = imgRatio * contentW
32 | }
33 | if contentH > UIScreen.main.bounds.size.height-300 {
34 | contentH = UIScreen.main.bounds.size.height-300
35 | }
36 | // 更新图片的高度约束
37 | self.contentHeightConstraint.constant = contentH
38 | }
39 | }
40 |
41 | override func awakeFromNib() {
42 | super.awakeFromNib()
43 |
44 | userIconView.layer.cornerRadius = 4.0
45 | userIconView.layer.masksToBounds = true
46 | textView.delegate = self
47 | textView.layer.borderWidth = 0.5/UIScreen.main.scale
48 | // textView.layer.borderColor = UIColor
49 | // textView.placeholder = "给朋友留言"
50 | // textView.placeholderColor = .l
51 | /*
52 | self.textView.layer.borderColor = [[UIColor grayColor] colorWithAlphaComponent:0.3].CGColor;
53 | self.textView.placeholder = @"给朋友留言";
54 | self.textView.placeholderColor = [UIColor lightGrayColor];
55 | */
56 | }
57 |
58 |
59 |
60 |
61 |
62 | }
63 |
64 | extension SendAlertView: UITextViewDelegate {
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/CustomViews/CustomView2/MyView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MyView.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2020/1/13.
6 | // Copyright © 2020 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class MyView: UIView, Nibloadable {
12 |
13 | @IBOutlet weak var cancelButton: UIButton!
14 |
15 |
16 | override func awakeFromNib() {
17 | super.awakeFromNib()
18 |
19 |
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/CustomViews/CustomView2/PassWordView.h:
--------------------------------------------------------------------------------
1 | //
2 | // WCLPassWordView.h
3 | // Youqun
4 | //
5 | // Created by 乐升平 on 16/6/1.
6 | // Copyright © 2016年 iDress. All rights reserved.
7 | //
8 |
9 | #import
10 | @class PassWordView;
11 |
12 | @protocol PassWordViewDelegate
13 |
14 | @optional
15 | /**
16 | * 监听输入的改变
17 | */
18 | - (void)passWordDidChange:(PassWordView *)passWord;
19 |
20 | /**
21 | * 监听输入的完成时
22 | */
23 | - (void)passWordCompleteInput:(PassWordView *)passWord;
24 |
25 | /**
26 | * 监听开始输入
27 | */
28 | - (void)passWordBeginInput:(PassWordView *)passWord;
29 |
30 |
31 | @end
32 |
33 | IB_DESIGNABLE
34 |
35 | @interface PassWordView : UIView
36 |
37 | @property (assign, nonatomic) IBInspectable NSUInteger passWordNum;//密码的位数
38 | @property (assign, nonatomic) IBInspectable CGFloat squareWidth;//正方形的大小
39 | @property (assign, nonatomic) IBInspectable CGFloat pointRadius;//黑点的半径
40 | @property (strong, nonatomic) IBInspectable UIColor *pointColor;//黑点的颜色
41 | @property (strong, nonatomic) IBInspectable UIColor *rectColor;//边框的颜色
42 | @property (weak, nonatomic) IBOutlet id delegate;
43 | @property (strong, nonatomic, readonly) NSMutableString *textStore;//保存密码的字符串
44 |
45 | @end
46 |
47 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/CustomViews/CustomView2/PassWordView.m:
--------------------------------------------------------------------------------
1 | //
2 | // WCLPassWordView.m
3 | // Youqun
4 | //
5 | // Created by 乐升平 on 16/6/1.
6 | // Copyright © 2016年 iDress. All rights reserved.
7 | //
8 |
9 | #import "PassWordView.h"
10 |
11 | @interface PassWordView ()
12 |
13 | @property (strong, nonatomic) NSMutableString *textStore;// 保存密码的字符串
14 |
15 | @end
16 |
17 | @implementation PassWordView
18 |
19 | static NSString * const MONEYNUMBERS = @"0123456789";
20 |
21 | - (instancetype)initWithCoder:(NSCoder *)coder {
22 | self = [super initWithCoder:coder];
23 | if (self) {
24 | self.textStore = [NSMutableString string];
25 | self.squareWidth = 45;
26 | self.passWordNum = 6;
27 | self.pointRadius = 6;
28 | self.rectColor = [UIColor colorWithRed:51.0/255.0 green:51.0/255.0 blue:51.0/255.0 alpha:1.0];
29 | self.pointColor = [UIColor colorWithRed:223.0/255.0 green:223.0/255.0 blue:223.0/255.0 alpha:1.0];
30 | [self becomeFirstResponder];
31 | }
32 | return self;
33 | }
34 |
35 | /**
36 | * 设置正方形的边长
37 | */
38 | - (void)setSquareWidth:(CGFloat)squareWidth {
39 | _squareWidth = squareWidth;
40 | [self setNeedsDisplay];
41 | }
42 |
43 | /**
44 | * 设置键盘的类型
45 | */
46 | - (UIKeyboardType)keyboardType {
47 | return UIKeyboardTypeNumberPad;
48 | }
49 |
50 | /**
51 | * 设置密码的位数
52 | */
53 | - (void)setPassWordNum:(NSUInteger)passWordNum {
54 | _passWordNum = passWordNum;
55 | [self setNeedsDisplay];
56 | }
57 |
58 | - (BOOL)becomeFirstResponder {
59 | if ([self.delegate respondsToSelector:@selector(passWordBeginInput:)]) {
60 | [self.delegate passWordBeginInput:self];
61 | }
62 | return [super becomeFirstResponder];
63 | }
64 |
65 | /**
66 | * 是否能成为第一响应者
67 | */
68 | - (BOOL)canBecomeFirstResponder {
69 | return YES;
70 | }
71 |
72 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
73 | if (![self isFirstResponder]) {
74 | [self becomeFirstResponder];
75 | }
76 | }
77 |
78 | #pragma mark - UIKeyInput
79 | /**
80 | * 用于显示的文本对象是否有任何文本
81 | */
82 | - (BOOL)hasText {
83 | return self.textStore.length > 0;
84 | }
85 |
86 | /**
87 | * 插入文本
88 | */
89 | - (void)insertText:(NSString *)text {
90 | if (self.textStore.length < self.passWordNum) {
91 | //判断是否是数字
92 | NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:MONEYNUMBERS] invertedSet];
93 | NSString*filtered = [[text componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];
94 | BOOL basicTest = [text isEqualToString:filtered];
95 | if(basicTest) {
96 | [self.textStore appendString:text];
97 | if ([self.delegate respondsToSelector:@selector(passWordDidChange:)]) {
98 | [self.delegate passWordDidChange:self];
99 | }
100 | if (self.textStore.length == self.passWordNum) {
101 | if ([self.delegate respondsToSelector:@selector(passWordCompleteInput:)]) {
102 | [self.delegate passWordCompleteInput:self];
103 | }
104 | }
105 | [self setNeedsDisplay];
106 | }
107 | }
108 | }
109 |
110 | /**
111 | * 删除文本
112 | */
113 | - (void)deleteBackward {
114 | if (self.textStore.length > 0) {
115 | [self.textStore deleteCharactersInRange:NSMakeRange(self.textStore.length - 1, 1)];
116 | if ([self.delegate respondsToSelector:@selector(passWordDidChange:)]) {
117 | [self.delegate passWordDidChange:self];
118 | }
119 | }
120 | [self setNeedsDisplay];
121 | }
122 |
123 | // Only override drawRect: if you perform custom drawing.
124 | - (void)drawRect:(CGRect)rect {
125 | CGFloat height = rect.size.height;
126 | CGFloat width = rect.size.width;
127 | CGFloat x = (width - self.squareWidth*self.passWordNum)/2.0;
128 | CGFloat y = (height - self.squareWidth)/2.0;
129 | CGContextRef context = UIGraphicsGetCurrentContext();
130 | //画外框
131 | CGContextAddRect(context, CGRectMake( x, y, self.squareWidth*self.passWordNum, self.squareWidth));
132 | CGContextSetLineWidth(context, 1);
133 | CGContextSetStrokeColorWithColor(context, self.rectColor.CGColor);
134 | CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
135 | //画竖条
136 | for (int i = 1; i <= self.passWordNum; i++) {
137 | CGContextMoveToPoint(context, x+i*self.squareWidth, y);
138 | CGContextAddLineToPoint(context, x+i*self.squareWidth, y+self.squareWidth);
139 | CGContextClosePath(context);
140 | }
141 | CGContextDrawPath(context, kCGPathFillStroke);
142 | CGContextSetFillColorWithColor(context, self.pointColor.CGColor);
143 | //画黑点
144 | for (int i = 1; i <= self.textStore.length; i++) {
145 | CGContextAddArc(context, x+i*self.squareWidth - self.squareWidth/2.0, y+self.squareWidth/2, self.pointRadius, 0, M_PI*2, YES);
146 | CGContextDrawPath(context, kCGPathFill);
147 | }
148 | }
149 |
150 |
151 | @end
152 |
153 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/CustomViews/CustomView2/Swift_SPAlertController-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // Use this file to import your target's public headers that you would like to expose to Swift.
3 | //
4 |
5 | #import "PassWordView.h"
6 | #import "HCSStarRatingView.h"
7 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/CustomViews/CustomView3/ShoppingCartCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ShoppingCartCell.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2020/1/13.
6 | // Copyright © 2020 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ShoppingCartCell: UITableViewCell {
12 |
13 | @IBOutlet weak var foodNameLabel: UILabel!
14 | @IBOutlet weak var priceLabel: UILabel!
15 | @IBOutlet weak var countLabel: UILabel!
16 |
17 | override func awakeFromNib() {
18 | super.awakeFromNib()
19 |
20 | }
21 |
22 | override func setSelected(_ selected: Bool, animated: Bool) {
23 | super.setSelected(selected, animated: animated)
24 |
25 | // Configure the view for the selected state
26 | }
27 |
28 | @IBAction func reduceAction(_ sender: Any) {
29 |
30 |
31 | }
32 |
33 |
34 | @IBAction func addAction(_ sender: Any) {
35 |
36 |
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/CustomViews/CustomView3/ShoppingCartView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ShoppingCartView.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2020/1/13.
6 | // Copyright © 2020 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ShoppingCartView: UIView {
12 |
13 | override init(frame: CGRect) {
14 | super.init(frame: frame)
15 |
16 | self.addSubview(topLabel)
17 | self.addSubview(tableView)
18 | }
19 |
20 | required init?(coder: NSCoder) {
21 | fatalError("init(coder:) has not been implemented")
22 | }
23 |
24 | override func layoutSubviews() {
25 | super.layoutSubviews()
26 |
27 | var topLabelY: CGFloat = 0.0
28 | if #available(iOS 11, *) {
29 | topLabelY = self.safeAreaInsets.top
30 | } else {
31 | topLabelY = 20
32 | }
33 | topLabel.frame = CGRect.init(x: 0, y: topLabelY, width: self.bounds.size.width, height: 44)
34 | let tableViewY: CGFloat = topLabel.frame.maxY
35 | tableView.frame = CGRect.init(x: 0, y: tableViewY, width: self.bounds.size.width, height: self.bounds.size.height-tableViewY)
36 | }
37 |
38 | lazy var topLabel: UILabel = {
39 | let label = UILabel()
40 | label.backgroundColor = UIColor.init(red: 244.0/255.0, green: 244.0/255.0, blue: 244.0/255.0, alpha: 1.0)
41 | label.text = "购物车"
42 | label.textAlignment = .center
43 | return label
44 | }()
45 |
46 | lazy var tableView: UITableView = {
47 | let tableV = UITableView.init(frame: .zero, style: .plain)
48 | tableV.delegate = self
49 | tableV.dataSource = self
50 | tableV.showsVerticalScrollIndicator = false
51 | tableV.register(UINib.init(nibName: "ShoppingCartCell", bundle: nil), forCellReuseIdentifier: "ShoppingCartCell")
52 | return tableV
53 | }()
54 | }
55 |
56 | extension ShoppingCartView: UITableViewDelegate, UITableViewDataSource {
57 |
58 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
59 | return 15
60 | }
61 |
62 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
63 | let cell = tableView.dequeueReusableCell(withIdentifier: "ShoppingCartCell")!
64 | return cell
65 | }
66 | func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
67 | return 50
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/CustomViews/CustomView4/CommodityListView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CommodityListView.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2020/1/13.
6 | // Copyright © 2020 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class CommodityListView: UIView {
12 |
13 | override init(frame: CGRect) {
14 | super.init(frame: frame)
15 |
16 | self.addSubview(scrollView)
17 | }
18 |
19 | override func layoutSubviews() {
20 | super.layoutSubviews()
21 |
22 | scrollView.frame = self.bounds
23 | let imageViewW: CGFloat = bounds.size.width/2-20
24 | let imageViewH: CGFloat = bounds.size.height
25 | var imageViewY: CGFloat = 0
26 | if #available(iOS 11, *) {
27 | imageViewY = self.safeAreaInsets.top
28 | }
29 | var lastImageView: UIImageView!
30 | for (index,imgView) in imageViews.enumerated() {
31 | imgView.frame = CGRect.init(x: (imageViewW + 10.0) * CGFloat(index), y: imageViewY, width: imageViewW, height: imageViewH)
32 | if index == self.imageViews.count-1 {
33 | lastImageView = imgView
34 | }
35 | }
36 | scrollView.contentSize = CGSize.init(width: lastImageView.frame.maxX, height: 0)
37 | }
38 |
39 | required init?(coder: NSCoder) {
40 | fatalError("init(coder:) has not been implemented")
41 | }
42 |
43 | var imageViews = [UIImageView]()
44 | let images = ["image0.jpg", "image1.jpg", "image2.jpg", "image3.jpg", "image4.jpg", "image5.jpg", "image6.jpg", "image7.jpg", "image8.jpg", "image9.jpg"]
45 |
46 | lazy var scrollView: UIScrollView = {
47 | let scrollV = UIScrollView()
48 | scrollV.backgroundColor = UIColor.init(red: 244.0/255.0, green: 244.0/255.0, blue: 244.0/255.0, alpha: 1.0)
49 | scrollV.showsVerticalScrollIndicator = false
50 |
51 | for (index,imgName) in images.enumerated() {
52 | let imageView = UIImageView.init(image: UIImage.init(named: imgName))
53 | imageView.backgroundColor = .red
54 | scrollV.addSubview(imageView)
55 | imageViews.append(imageView)
56 | }
57 | return scrollV
58 | }()
59 | }
60 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/CustomViews/CustomView5/PickerView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PickerView.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2020/1/13.
6 | // Copyright © 2020 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class PickerView: UIView, Nibloadable {
12 |
13 | @IBOutlet weak var pickView: UIPickerView!
14 |
15 | var cancelClickedClosure: (()->Void)?
16 | var doneClickedClosure: (()->Void)?
17 |
18 | override func awakeFromNib() {
19 | super.awakeFromNib()
20 |
21 | pickView.delegate = self
22 | pickView.dataSource = self
23 | }
24 |
25 | @IBAction func cancelClick(_ sender: Any) {
26 | cancelClickedClosure?()
27 | }
28 |
29 | @IBAction func doneClick(_ sender: Any) {
30 | doneClickedClosure?()
31 | }
32 | }
33 |
34 | extension PickerView: UIPickerViewDelegate, UIPickerViewDataSource {
35 | func numberOfComponents(in pickerView: UIPickerView) -> Int {
36 | return 1
37 | }
38 | func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
39 | return 2
40 | }
41 |
42 | func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
43 | return ["男","女"][row]
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/CustomViews/CustomView5/PickerView.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/CustomViews/CustomView6/HCSStarRatingView.h:
--------------------------------------------------------------------------------
1 | // HCSStarRatingView.h
2 | //
3 | // Copyright (c) 2015 Hugo Sousa
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
13 | // all 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
21 | // THE SOFTWARE.
22 |
23 | @import UIKit;
24 |
25 | typedef BOOL(^HCSStarRatingViewShouldBeginGestureRecognizerBlock)(UIGestureRecognizer *gestureRecognizer);
26 |
27 | IB_DESIGNABLE
28 | @interface HCSStarRatingView : UIControl
29 | @property (nonatomic) IBInspectable NSUInteger maximumValue;
30 | @property (nonatomic) IBInspectable CGFloat minimumValue;
31 | @property (nonatomic) IBInspectable CGFloat value;
32 | @property (nonatomic) IBInspectable CGFloat spacing;
33 | @property (nonatomic) IBInspectable BOOL allowsHalfStars;
34 | @property (nonatomic) IBInspectable BOOL accurateHalfStars;
35 | @property (nonatomic) IBInspectable BOOL continuous;
36 |
37 | @property (nonatomic) BOOL shouldBecomeFirstResponder;
38 |
39 | // Optional: if `nil` method will return `NO`.
40 | @property (nonatomic, copy) HCSStarRatingViewShouldBeginGestureRecognizerBlock shouldBeginGestureRecognizerBlock;
41 |
42 | @property (nonatomic, strong) IBInspectable UIColor *starBorderColor;
43 | @property (nonatomic) IBInspectable CGFloat starBorderWidth;
44 |
45 | @property (nonatomic, strong) IBInspectable UIColor *emptyStarColor;
46 |
47 | @property (nonatomic, strong) IBInspectable UIImage *emptyStarImage;
48 | @property (nonatomic, strong) IBInspectable UIImage *halfStarImage;
49 | @property (nonatomic, strong) IBInspectable UIImage *filledStarImage;
50 | @end
51 |
52 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/CustomViews/CustomView6/ScoreView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ScoreView.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2020/1/13.
6 | // Copyright © 2020 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ScoreView: UIView {
12 |
13 | var finishClickedClosure: (()->Void)?
14 |
15 | override init(frame: CGRect) {
16 | super.init(frame: frame)
17 |
18 | self.addSubview(starRatingView)
19 | self.addSubview(lineView)
20 | self.addSubview(finishButton)
21 | }
22 |
23 | required init?(coder: NSCoder) {
24 | fatalError("init(coder:) has not been implemented")
25 | }
26 |
27 | @objc func finishButtonAction() {
28 | finishClickedClosure?()
29 | }
30 |
31 | override func updateConstraints() {
32 | super.updateConstraints()
33 |
34 | // 星星
35 | starRatingView.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 40).isActive = true
36 | starRatingView.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -40).isActive = true
37 | starRatingView.topAnchor.constraint(equalTo: self.topAnchor, constant: 0).isActive = true
38 | starRatingView.bottomAnchor.constraint(equalTo: lineView.topAnchor, constant: 0).isActive = true
39 | starRatingView.heightAnchor.constraint(equalToConstant: 50).isActive = true
40 |
41 | // 线
42 | let lineH: CGFloat = 1.0/UIScreen.main.scale
43 | lineView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
44 | lineView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
45 | lineView.bottomAnchor.constraint(equalTo: finishButton.topAnchor).isActive = true
46 | lineView.heightAnchor.constraint(equalToConstant: lineH).isActive = true
47 |
48 | // 完成
49 | finishButton.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
50 | finishButton.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
51 | finishButton.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
52 | finishButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
53 | }
54 |
55 | lazy var starRatingView: HCSStarRatingView = {
56 | let starRatingV = HCSStarRatingView()
57 | starRatingV.translatesAutoresizingMaskIntoConstraints = false
58 | starRatingV.maximumValue = 5
59 | starRatingV.minimumValue = 0
60 | starRatingV.value = 2
61 | starRatingV.spacing = 20
62 | starRatingV.tintColor = UIColor.init(red: 0.0, green: 0.48, blue: 1.0, alpha: 1.0)
63 | starRatingV.allowsHalfStars = true
64 | return starRatingV
65 | }()
66 |
67 | lazy var lineView: UIView = {
68 | let line = UIView()
69 | line.translatesAutoresizingMaskIntoConstraints = false
70 | line.backgroundColor = UIColor.lightGray
71 | line.alpha = 0.3
72 | return line
73 | }()
74 |
75 | lazy var finishButton: UIButton = {
76 | let btn = UIButton.init(type: .custom)
77 | btn.translatesAutoresizingMaskIntoConstraints = false
78 | btn.backgroundColor = UIColor.white
79 | let titleColor = UIColor.init(red: 0.0, green: 0.48, blue: 1.0, alpha: 1.0)
80 | btn.setTitleColor(titleColor, for: .normal)
81 | btn.setTitle("完成", for: .normal)
82 | btn.addTarget(self, action: #selector(finishButtonAction), for: .touchUpInside)
83 | return btn
84 | }()
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/CustomViews/CustomView7/MyCenterView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MyCenterView.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2020/1/13.
6 | // Copyright © 2020 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class MyCenterView: UIView, UITableViewDataSource {
12 |
13 | override init(frame: CGRect) {
14 | super.init(frame: frame)
15 |
16 | self.addSubview(tableView)
17 | }
18 |
19 | required init?(coder: NSCoder) {
20 | fatalError("init(coder:) has not been implemented")
21 | }
22 |
23 | override func layoutSubviews() {
24 | super.layoutSubviews()
25 |
26 | tableView.frame = self.bounds
27 | }
28 |
29 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
30 | return 10
31 | }
32 |
33 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
34 | var cell = tableView.dequeueReusableCell(withIdentifier: "myCell")
35 | if cell == nil {
36 | cell = UITableViewCell.init(style: .value1, reuseIdentifier: "myCell")
37 | }
38 | cell!.textLabel!.text = "第\(indexPath.row)行"
39 | cell!.textLabel!.font = UIFont.systemFont(ofSize: 14)
40 | cell!.detailTextLabel!.text = "这是自定义tableView"
41 | cell!.detailTextLabel!.font = UIFont.systemFont(ofSize: 12)
42 | return cell!
43 | }
44 |
45 | lazy var tableView: UITableView = {
46 | let tableV = UITableView.init(frame: .zero, style: .plain)
47 | tableV.dataSource = self
48 | tableV.showsVerticalScrollIndicator = false
49 | return tableV
50 | }()
51 | }
52 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/DLog.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DLog.swift
3 | // IsuzuAuto
4 | //
5 | // Created by lidongxi on 2019/8/17.
6 | // Copyright © 2019 lidongxi. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public protocol LogLevel {
12 | func myDescription(level: Int) -> String
13 | }
14 |
15 | //封装的日志输出功能(T表示不指定日志信息参数类型)
16 | public func DLog(_ message:T, file:String = #file, function:String = #function,
17 | line:Int = #line) {
18 | #if DEBUG
19 | let fileName = (file as NSString).lastPathComponent
20 | if message is Dictionary {
21 | print("[\(fileName):line:\(line)]- \((message as! Dictionary).myDescription(level: 0))")
22 | }else if message is Array {
23 | print("[\(fileName):line:\(line)]- \((message as! Array ).myDescription(level: 0))")
24 | }else if message is CustomStringConvertible {
25 | print("[\(fileName):line:\(line)]- \((message as! CustomStringConvertible).description)")
26 | }else {
27 | print("[\(fileName):line:\(line)]- \(message)")
28 | }
29 | #endif
30 | }
31 |
32 |
33 | // MARK: - 重写可选型description
34 | extension Optional: CustomStringConvertible {
35 | public var description: String {
36 | switch self {
37 | case .none:
38 | return "Optional(null)"
39 | case .some(let obj):
40 | if let obj = obj as? CustomStringConvertible, obj is Dictionary {
41 | return "Optional:" + "\((obj as! Dictionary).myDescription(level: 0))"
42 | }
43 | if let obj = obj as? CustomStringConvertible, obj is Array {
44 | return "Optional:" + "\((obj as! Array).myDescription(level: 0))"
45 | }
46 | return "Optional" + "(\(obj))"
47 | }
48 | }
49 | }
50 |
51 | // MARK: - 重写字典型description
52 | extension Dictionary: LogLevel {
53 | public var description: String {
54 | var str = ""
55 | str.append(contentsOf: "{\n")
56 | for (key, value) in self {
57 | if value is String {
58 | let s = value as! String
59 | str.append(contentsOf: String.init(format: "\t%@ = \"%@\",\n", key as! CVarArg, s.unicodeStr))
60 | }else if value is Dictionary {
61 | str.append(contentsOf: String.init(format: "\t%@ = \"%@\",\n", key as! CVarArg, (value as! Dictionary).description))
62 | }else if value is Array {
63 | str.append(contentsOf: String.init(format: "\t%@ = \"%@\",\n", key as! CVarArg, (value as! Array).description))
64 | }else {
65 | str.append(contentsOf: String.init(format: "\t%@ = \"%@\",\n", key as! CVarArg, "\(value)"))
66 | }
67 | }
68 | str.append(contentsOf: "}")
69 | return str
70 | }
71 |
72 | public func myDescription(level: Int) -> String{
73 | var str = ""
74 | var tab = ""
75 | for _ in 0.. {
86 | str.append(contentsOf: String.init(format: "%@\t%@ = %@,\n", tab, key as! CVarArg, (value as! Array).myDescription(level: level + 1)))
87 | }else {
88 | str.append(contentsOf: String.init(format: "%@\t%@ = %@,\n", tab, key as! CVarArg, "\(value)"))
89 | }
90 | }
91 | str.append(contentsOf: String.init(format: "%@}", tab))
92 | return str
93 | }
94 | }
95 |
96 | extension Array: LogLevel {
97 | public func myDescription(level: Int) -> String {
98 | var str = ""
99 | var tab = ""
100 | str.append(contentsOf: "[\n")
101 | for _ in 0.. {
109 | str.append(contentsOf: String.init(format: "%@\t%@,\n", tab, (value as! Dictionary).myDescription(level: level + 1)))
110 | }else if value is Array {
111 | str.append(contentsOf: String.init(format: "%@\t%@,\n", tab, (value as! Array).myDescription(level: level + 1)))
112 | }else {
113 | str.append(contentsOf: String.init(format: "%@\t%@,\n", tab, "\(value)"))
114 | }
115 | }
116 | str.append(contentsOf: String.init(format: "%@]", tab))
117 | return str
118 | }
119 |
120 | public var description: String {
121 | var str = ""
122 | str.append(contentsOf: "[\n")
123 | for (_, value) in self.enumerated() {
124 | if value is String {
125 | let s = value as! String
126 | str.append(contentsOf: String.init(format: "\t\"%@\",\n", s.unicodeStr))
127 | }else if value is Dictionary {
128 | str.append(contentsOf: String.init(format: "\t%@,\n", (value as! Dictionary).description))
129 | }else if value is Array {
130 | str.append(contentsOf: String.init(format: "\t%@,\n", (value as! Array).description))
131 | }else {
132 | str.append(contentsOf: String.init(format: "\t%@,\n", "\(value)"))
133 | }
134 | }
135 | str.append(contentsOf: "]")
136 | return str
137 | }
138 | }
139 |
140 | // MARK: - unicode转码
141 | extension String {
142 | func unicodeStrWith(level: Int) -> String {
143 | let s = self
144 | let data = s.data(using: .utf8)
145 | if let data = data {
146 | if let id = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments) {
147 | if id is Array {
148 | return (id as! Array).myDescription(level: level + 1)
149 | }else if id is Dictionary {
150 | return (id as! Dictionary).myDescription(level: level + 1)
151 | }
152 | }
153 | }
154 | let tempStr1 = self.replacingOccurrences(of: "\\u", with: "\\U")
155 | let tempStr2 = tempStr1.replacingOccurrences(of: "\"", with: "\\\"")
156 | let tempStr3 = "\"".appending(tempStr2).appending("\"")
157 | let tempData = tempStr3.data(using: String.Encoding.utf8)
158 | var returnStr:String = ""
159 | do {
160 | returnStr = try PropertyListSerialization.propertyList(from: tempData!, options: [.mutableContainers], format: nil) as! String
161 | } catch {
162 | print(error)
163 | }
164 | return returnStr.replacingOccurrences(of: "\\r\\n", with: "\n")
165 | }
166 | var unicodeStr:String {
167 | return self.unicodeStrWith(level: 1)
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/DynamicBlurView/BlurLayer.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BlurLayer.swift
3 | // DynamicBlurView
4 | //
5 | // Created by Kyohei Ito on 2017/08/14.
6 | // Copyright © 2017年 kyohei_ito. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | private extension CGRect {
12 | func rectangle(_ s: CGSize) -> CGRect {
13 | let x = origin.x / s.width
14 | let y = origin.y / s.height
15 | let width = size.width / s.width
16 | let height = size.height / s.height
17 | return CGRect(x: x, y: y, width: width, height: height)
18 | }
19 | }
20 |
21 | class BlurLayer: CALayer {
22 | private static let blurRadiusKey = "blurRadius"
23 | private static let blurLayoutKey = "blurLayout"
24 | @NSManaged var blurRadius: CGFloat
25 | @NSManaged private var blurLayout: CGFloat
26 |
27 | private var fromBlurRadius: CGFloat?
28 | var presentationRadius: CGFloat {
29 | if let radius = fromBlurRadius {
30 | if let layer = presentation() {
31 | return layer.blurRadius
32 | } else {
33 | return radius
34 | }
35 | } else {
36 | return blurRadius
37 | }
38 | }
39 |
40 | override class func needsDisplay(forKey key: String) -> Bool {
41 | if key == blurRadiusKey || key == blurLayoutKey {
42 | return true
43 | }
44 | return super.needsDisplay(forKey: key)
45 | }
46 |
47 | open override func action(forKey event: String) -> CAAction? {
48 | if event == BlurLayer.blurRadiusKey {
49 | fromBlurRadius = nil
50 |
51 | if let action = super.action(forKey: "opacity") as? CABasicAnimation {
52 | fromBlurRadius = (presentation() ?? self).blurRadius
53 |
54 | action.keyPath = event
55 | action.fromValue = fromBlurRadius
56 | return action
57 | }
58 | }
59 |
60 | if event == BlurLayer.blurLayoutKey, let action = super.action(forKey: "opacity") as? CABasicAnimation {
61 | action.keyPath = event
62 | action.fromValue = 0
63 | action.toValue = 1
64 | return action
65 | }
66 |
67 | return super.action(forKey: event)
68 | }
69 | }
70 |
71 | extension BlurLayer {
72 | func draw(_ image: UIImage, fixes isFixes: Bool, baseLayer: CALayer?) {
73 | contents = image.cgImage
74 | contentsScale = image.scale
75 |
76 | if isFixes, let blurLayer = presentation() {
77 | contentsRect = blurLayer.convert(blurLayer.bounds, to: baseLayer).rectangle(image.size)
78 | }
79 | }
80 |
81 | func refresh() {
82 | fromBlurRadius = nil
83 | }
84 |
85 | func animate() {
86 | UIView.performWithoutAnimation {
87 | blurLayout = 0
88 | }
89 | blurLayout = 1
90 | }
91 |
92 | func render(in context: CGContext, for layer: CALayer) {
93 | let layers = hideOverlappingLayers(layer.sublayers)
94 | layer.render(in: context)
95 | layers.forEach {
96 | $0.isHidden = false
97 | }
98 | }
99 |
100 | private func hideOverlappingLayers(_ layers: [CALayer]?) -> [CALayer] {
101 | var hiddenLayers: [CALayer] = []
102 | guard let layers = layers else {
103 | return hiddenLayers
104 | }
105 |
106 | for layer in layers.reversed() {
107 | if isHang(to: layer) {
108 | return hiddenLayers + hideOverlappingLayers(layer.sublayers)
109 | }
110 | if layer.isHidden == false {
111 | layer.isHidden = true
112 | hiddenLayers.append(layer)
113 | }
114 | if layer == self {
115 | return hiddenLayers
116 | }
117 | }
118 | return hiddenLayers
119 | }
120 |
121 | private func isHang(to target: CALayer) -> Bool {
122 | var layer = superlayer
123 | while layer != nil {
124 | if layer == target {
125 | return true
126 | }
127 | layer = layer?.superlayer
128 | }
129 | return false
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/DynamicBlurView/CGContext+CGImage.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CGContext+CGImage.swift
3 | // DynamicBlurView
4 | //
5 | // Created by Kyohei Ito on 2017/08/17.
6 | // Copyright © 2017年 kyohei_ito. All rights reserved.
7 | //
8 | import UIKit
9 | extension CGContext {
10 | static func imageContext(with quality: CaptureQuality, rect: CGRect, opaque: Bool) -> CGContext? {
11 | UIGraphicsBeginImageContextWithOptions(rect.size, opaque, quality.imageScale)
12 | guard let context = UIGraphicsGetCurrentContext() else {
13 | return nil
14 | }
15 |
16 | context.translateBy(x: -rect.origin.x, y: -rect.origin.y)
17 | context.interpolationQuality = quality.interpolationQuality
18 |
19 | return context
20 | }
21 |
22 | func makeImage(with blendColor: UIColor?, blendMode: CGBlendMode, size: CGSize) -> CGImage? {
23 | if let color = blendColor {
24 | setFillColor(color.cgColor)
25 | setBlendMode(blendMode)
26 | fill(CGRect(origin: .zero, size: size))
27 | }
28 |
29 | return makeImage()
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/DynamicBlurView/CGImage+Accelerate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CGImage+Accelerate.swift
3 | // DynamicBlurView
4 | //
5 | // Created by Kyohei Ito on 2017/08/17.
6 | // Copyright © 2017年 kyohei_ito. All rights reserved.
7 | //
8 |
9 | import Accelerate
10 | import UIKit
11 | extension CGImage {
12 | var area: Int {
13 | return width * height
14 | }
15 |
16 | private var size: CGSize {
17 | return CGSize(width: width, height: height)
18 | }
19 |
20 | private var bytes: Int {
21 | return bytesPerRow * height
22 | }
23 |
24 | private func imageBuffer(from data: UnsafeMutableRawPointer!) -> vImage_Buffer {
25 | return vImage_Buffer(data: data, height: vImagePixelCount(height), width: vImagePixelCount(width), rowBytes: bytesPerRow)
26 | }
27 |
28 | func blurred(with boxSize: UInt32, iterations: Int, blendColor: UIColor?, blendMode: CGBlendMode) -> CGImage? {
29 | guard let providerData = dataProvider?.data else {
30 | return nil
31 | }
32 |
33 | let inData = malloc(bytes)
34 | var inBuffer = imageBuffer(from: inData)
35 |
36 | let outData = malloc(bytes)
37 | var outBuffer = imageBuffer(from: outData)
38 |
39 | let tempSize = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, nil, 0, 0, boxSize, boxSize, nil, vImage_Flags(kvImageEdgeExtend + kvImageGetTempBufferSize))
40 | let tempData = malloc(tempSize)
41 |
42 | defer {
43 | free(inData)
44 | free(outData)
45 | free(tempData)
46 | }
47 |
48 | let source = CFDataGetBytePtr(providerData)
49 | memcpy(inBuffer.data, source, bytes)
50 |
51 | for _ in 0..
10 |
11 | //! Project version number for DynamicBlurView.
12 | FOUNDATION_EXPORT double DynamicBlurViewVersionNumber;
13 |
14 | //! Project version string for DynamicBlurView.
15 | FOUNDATION_EXPORT const unsigned char DynamicBlurViewVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/DynamicBlurView/DynamicBlurView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DynamicBlurView.swift
3 | // DynamicBlurView
4 | //
5 | // Created by Kyohei Ito on 2015/04/08.
6 | // Copyright (c) 2015年 kyohei_ito. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | open class DynamicBlurView: UIView {
12 | open override class var layerClass : AnyClass {
13 | return BlurLayer.self
14 | }
15 |
16 | private var staticImage: UIImage?
17 | private var displayLink: CADisplayLink?
18 | private var blurLayer: BlurLayer {
19 | return layer as! BlurLayer
20 | }
21 | private let mainQueue = DispatchQueue.main
22 | private let globalQueue: DispatchQueue = {
23 | if #available (iOS 8.0, *) {
24 | return .global(qos: .userInteractive)
25 | } else {
26 | return .global(priority: .high)
27 | }
28 | }()
29 | private var renderingTarget: UIView? {
30 | if isDeepRendering {
31 | return window
32 | } else {
33 | return superview
34 | }
35 | }
36 |
37 | /// When true, it captures displays image and blur it asynchronously. Try to set true if needs more performance.
38 | /// Asynchronous drawing is possibly crash when needs to process on main thread that drawing with animation for example.
39 | open var drawsAsynchronously: Bool = false
40 | /// Radius of blur.
41 | open var blurRadius: CGFloat {
42 | set { blurLayer.blurRadius = newValue }
43 | get { return blurLayer.blurRadius }
44 | }
45 | /// Default is none.
46 | open var trackingMode: TrackingMode = .none {
47 | didSet {
48 | if trackingMode != oldValue {
49 | linkForDisplay()
50 | }
51 | }
52 | }
53 | /// Blend color.
54 | open var blendColor: UIColor?
55 | /// Blend mode.
56 | open var blendMode: CGBlendMode = .plusLighter
57 | /// Default is 3.
58 | open var iterations: Int = 3
59 | /// If the view want to render beyond the layer, should be true.
60 | open var isDeepRendering: Bool = false
61 | /// When none of tracking mode, it can change the radius of blur with the ratio. Should set from 0 to 1.
62 | open var blurRatio: CGFloat = 1 {
63 | didSet {
64 | if let image = staticImage, oldValue != blurRatio {
65 | draw(image, blurRadius: blurRadius, fixes: false, baseLayer: renderingTarget?.layer)
66 | }
67 | }
68 | }
69 | /// Quality of captured image.
70 | open var quality: CaptureQuality = .medium
71 |
72 | public override init(frame: CGRect) {
73 | super.init(frame: frame)
74 | isUserInteractionEnabled = false
75 | }
76 |
77 | public required init?(coder aDecoder: NSCoder) {
78 | super.init(coder: aDecoder)
79 | isUserInteractionEnabled = false
80 | }
81 |
82 | open override func didMoveToWindow() {
83 | super.didMoveToWindow()
84 |
85 | if let view = renderingTarget, window != nil && trackingMode == .none {
86 | staticImage = snapshotImage(for: view.layer, conversion: !isDeepRendering)
87 | }
88 | }
89 |
90 | open override func didMoveToSuperview() {
91 | super.didMoveToSuperview()
92 |
93 | if superview == nil {
94 | displayLink?.invalidate()
95 | displayLink = nil
96 | } else {
97 | linkForDisplay()
98 | }
99 | }
100 |
101 | private func async(on queue: DispatchQueue, actions: @escaping () -> Void) {
102 | if drawsAsynchronously {
103 | queue.async(execute: actions)
104 | } else {
105 | actions()
106 | }
107 | }
108 |
109 | private func sync(on queue: DispatchQueue, actions: () -> Void) {
110 | if drawsAsynchronously {
111 | queue.sync(execute: actions)
112 | } else {
113 | actions()
114 | }
115 | }
116 |
117 | private func draw(_ image: UIImage, blurRadius radius: CGFloat, fixes isFixes: Bool, baseLayer: CALayer?) {
118 | async(on: globalQueue) { [weak self] in
119 | if let me = self, let blurredImage = image.blurred(radius: radius, iterations: me.iterations, ratio: me.blurRatio, blendColor: me.blendColor, blendMode: me.blendMode) {
120 | me.sync(on: me.mainQueue) {
121 | me.blurLayer.draw(blurredImage, fixes: isFixes, baseLayer: baseLayer)
122 | }
123 | }
124 | }
125 | }
126 |
127 | private func blurLayerRect(to layer: CALayer, conversion: Bool) -> CGRect {
128 | if conversion {
129 | let presentationLayer = blurLayer.presentation() ?? blurLayer
130 | return presentationLayer.convert(presentationLayer.bounds, to: layer)
131 | } else {
132 | return layer.bounds
133 | }
134 | }
135 |
136 | private func snapshotImage(for layer: CALayer, conversion: Bool) -> UIImage? {
137 | let rect = blurLayerRect(to: layer, conversion: conversion)
138 | guard let context = CGContext.imageContext(with: quality, rect: rect, opaque: isOpaque) else {
139 | return nil
140 | }
141 |
142 | blurLayer.render(in: context, for: layer)
143 |
144 | defer {
145 | UIGraphicsEndImageContext()
146 | }
147 |
148 | return UIGraphicsGetImageFromCurrentImageContext()
149 | }
150 | }
151 |
152 | extension DynamicBlurView {
153 | open override func display(_ layer: CALayer) {
154 | let blurRadius = blurLayer.presentationRadius
155 | let isFixes = isDeepRendering && staticImage != nil
156 | if let view = renderingTarget, let image = staticImage ?? snapshotImage(for: view.layer, conversion: !isFixes) {
157 | draw(image, blurRadius: blurRadius, fixes: isFixes, baseLayer: view.layer)
158 | }
159 | }
160 | }
161 |
162 | extension DynamicBlurView {
163 | private func linkForDisplay() {
164 | displayLink?.invalidate()
165 | displayLink = UIScreen.main.displayLink(withTarget: self, selector: #selector(DynamicBlurView.displayDidRefresh(_:)))
166 | displayLink?.add(to: .main, forMode: RunLoop.Mode(rawValue: trackingMode.description))
167 | }
168 |
169 | @objc private func displayDidRefresh(_ displayLink: CADisplayLink) {
170 | display(layer)
171 | }
172 | }
173 |
174 | extension DynamicBlurView {
175 | /// Remove cache of blur image then get it again.
176 | open func refresh() {
177 | blurLayer.refresh()
178 | staticImage = nil
179 | blurRatio = 1
180 | display(layer)
181 | }
182 |
183 | /// Remove cache of blur image.
184 | open func remove() {
185 | blurLayer.refresh()
186 | staticImage = nil
187 | blurRatio = 1
188 | layer.contents = nil
189 | }
190 |
191 | /// Should use when needs to change layout with animation when is set none of tracking mode.
192 | public func animate() {
193 | blurLayer.animate()
194 | }
195 | }
196 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/DynamicBlurView/TrackingMode.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TrackingMode.swift
3 | // DynamicBlurView
4 | //
5 | // Created by Kyohei Ito on 2017/08/17.
6 | // Copyright © 2017年 kyohei_ito. All rights reserved.
7 | //
8 |
9 | public enum TrackingMode: CustomStringConvertible {
10 | case tracking
11 | case common
12 | case none
13 |
14 | public var description: String {
15 | switch self {
16 | case .tracking:
17 | return RunLoop.Mode.tracking.rawValue
18 | case .common:
19 | return RunLoop.Mode.common.rawValue
20 | case .none:
21 | return ""
22 | }
23 | }
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/DynamicBlurView/UIImage+Blur.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+Blur.swift
3 | // DynamicBlurView
4 | //
5 | // Created by Kyohei Ito on 2017/08/11.
6 | // Copyright © 2017年 kyohei_ito. All rights reserved.
7 | //
8 | import UIKit
9 | public extension UIImage {
10 | func blurred(radius: CGFloat, iterations: Int, ratio: CGFloat, blendColor color: UIColor?, blendMode mode: CGBlendMode) -> UIImage? {
11 | guard let cgImage = cgImage else {
12 | return nil
13 | }
14 |
15 | if cgImage.area <= 0 || radius <= 0 {
16 | return self
17 | }
18 |
19 | var boxSize = UInt32(radius * scale * ratio)
20 | if boxSize % 2 == 0 {
21 | boxSize += 1
22 | }
23 |
24 | return cgImage.blurred(with: boxSize, iterations: iterations, blendColor: color, blendMode: mode).map {
25 | UIImage(cgImage: $0, scale: scale, orientation: imageOrientation)
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Images/image0.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Images/image0.jpg
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Images/image1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Images/image1.jpg
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Images/image2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Images/image2.jpg
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Images/image3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Images/image3.jpg
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Images/image4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Images/image4.jpg
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Images/image5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Images/image5.jpg
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Images/image6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Images/image6.jpg
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Images/image7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Images/image7.jpg
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Images/image8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Images/image8.jpg
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Images/image9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Images/image9.jpg
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Images/send0.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Images/send0.jpeg
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Images/send1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Images/send1.jpeg
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Images/背景1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Images/背景1.jpg
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Images/背景2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dongxiexidu/SPAlertController/1970af814cbbc30b23a982dfab0095bdbde7f366/Swift_SPAlertController/Swift_SPAlertController/Images/背景2.jpg
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/Nibloadable.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Nibloadable.swift
3 | // FashionMall
4 | //
5 | // Created by fashion on 2018/1/17.
6 | // Copyright © 2018年 shangZhu. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | protocol Nibloadable {}
11 |
12 | // 自定义View,遵守此协议,便可以用此方法加载Nib文件
13 | extension Nibloadable where Self : UIView{
14 | static func loadFromNib() -> Self {
15 | return Bundle.main.loadNibNamed("\(self)", owner: nil, options: nil)?.first as! Self
16 | }
17 | }
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/ViewController+Alert.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController+Alert.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2020/1/10.
6 | // Copyright © 2020 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension ViewController{
12 |
13 |
14 | //示例9:alert 默认动画(收缩动画)
15 | func alertTest1() {
16 |
17 | let alert = SPAlertController.alertController(withTitle: "我是主标题", message: "我是副标题", preferredStyle: .alert, animationType: .default)
18 | alert.needDialogBlur = lookBlur
19 | let action1 = SPAlertAction.action(withTitle: "确定", style: .default) { (action) in
20 | print("点击了确定")
21 | }
22 | let action2 = SPAlertAction.action(withTitle: "取消", style: .cancel) { (action) in
23 | print("点击了取消")
24 | }
25 | if customBlur {
26 | alert.customOverlayView = CustomOverlayView()
27 | }
28 | // 设置第2个action的颜色
29 | action2.titleColor = SYSTEM_COLOR
30 | alert.addAction(action: action1)
31 | alert.addAction(action: action2)
32 | self.present(alert, animated: true, completion: nil)
33 | }
34 |
35 | //示例10:alert 发散动画
36 | func alertTest2() {
37 | let alert = SPAlertController.alertController(withTitle: "我是主标题", message: "我是副标题", preferredStyle: .alert, animationType: .expand)
38 |
39 | let action1 = SPAlertAction.action(withTitle: "第1个", style: .default) { (action) in
40 | print("点击了第1个")
41 | }
42 |
43 | let action2 = SPAlertAction.action(withTitle: "抖动动画", style: .destructive) { (action) in
44 | // 抖动动画
45 | alert.shake()
46 | }
47 | action2.dismissOnTap = false
48 |
49 | let action3 = SPAlertAction.action(withTitle: "第3个", style: .default) { (action) in
50 | print("点击了第3个")
51 | }
52 | let action4 = SPAlertAction.action(withTitle: "第4个", style: .default) { (action) in
53 | print("点击了第4个")
54 | }
55 | if customBlur {
56 | alert.customOverlayView = CustomOverlayView()
57 | }
58 | // 设置第2个action的颜色
59 | action1.titleColor = SYSTEM_COLOR
60 | alert.addAction(action: action1)
61 | alert.addAction(action: action2)
62 | alert.addAction(action: action3)
63 | alert.addAction(action: action4)
64 | alert.tapBackgroundViewDismiss = false
65 | self.present(alert, animated: true, completion: nil)
66 | }
67 |
68 | //示例11:alert 渐变动画
69 | func alertTest3() {
70 | let alert = SPAlertController.alertController(withTitle: "我是主标题", message: "我是副标题", preferredStyle: .alert, animationType: .fade)
71 | alert.needDialogBlur = lookBlur
72 | let action1 = SPAlertAction.action(withTitle: "确定", style: .default) { (action) in
73 | print("点击了确定")
74 | }
75 | // 设置第1个action的颜色
76 | action1.titleColor = SYSTEM_COLOR
77 | let action2 = SPAlertAction.action(withTitle: "取消", style: .destructive) { (action) in
78 | print("点击了取消")
79 | }
80 | if customBlur {
81 | alert.customOverlayView = CustomOverlayView()
82 | }
83 | action2.titleColor = .red
84 | alert.addAction(action: action1)
85 | alert.addAction(action: action2)
86 | self.present(alert, animated: true, completion: nil)
87 | }
88 |
89 | //示例12:alert 垂直排列2个按钮
90 | func alertTest4() {
91 | let alert = SPAlertController.alertController(withTitle: "我是主标题", message: "我是副标题", preferredStyle: .alert, animationType: .expand)
92 | // 2个按钮时默认是水平排列,这里强制垂直排列
93 | alert.actionAxis = .vertical
94 | let action1 = SPAlertAction.action(withTitle: "确定", style: .default) { (action) in
95 | print("点击了确定")
96 | }
97 | // 设置第1个action的颜色
98 | action1.titleColor = .red
99 | let action2 = SPAlertAction.action(withTitle: "取消", style: .destructive) { (action) in
100 | print("点击了取消")
101 | }
102 | if customBlur {
103 | alert.customOverlayView = CustomOverlayView()
104 | }
105 | action2.titleColor = SYSTEM_COLOR
106 | alert.addAction(action: action1)
107 | alert.addAction(action: action2)
108 | self.present(alert, animated: true, completion: nil)
109 | }
110 |
111 | //示例13:alert 水平排列2个以上的按钮(默认超过2个按钮是垂直排列)
112 | func alertTest5() {
113 | let alert = SPAlertController.alertController(withTitle: "我是主标题", message: "我是副标题", preferredStyle: .alert, animationType: .expand)
114 | // 2个按钮时默认是水平排列,这里强制水平排列
115 | alert.actionAxis = .horizontal
116 | let action1 = SPAlertAction.action(withTitle: "第1个", style: .default) { (action) in
117 | print("点击了第1个")
118 | }
119 | // 设置第1个action的颜色
120 | action1.titleColor = SYSTEM_COLOR
121 | let action2 = SPAlertAction.action(withTitle: "第2个", style: .destructive) { (action) in
122 | print("点击了第2个")
123 | }
124 | action2.titleColor = .magenta
125 | let action3 = SPAlertAction.action(withTitle: "第3个", style: .destructive) { (action) in
126 | print("点击了第3个")
127 | }
128 | if customBlur {
129 | alert.customOverlayView = CustomOverlayView()
130 | }
131 | alert.addAction(action: action1)
132 | alert.addAction(action: action2)
133 | alert.addAction(action: action3)
134 | self.present(alert, animated: true, completion: nil)
135 | }
136 |
137 |
138 | //示例14:alert 设置头部图标
139 | func alertTest6() {
140 | let alert = SPAlertController.alertController(withTitle: "“支付宝”的触控 ID", message: "请验证已有指纹", preferredStyle: .alert, animationType: .shrink)
141 | alert.image = UIImage.init(named: "zhiwen")
142 | let action = SPAlertAction.action(withTitle: "取消", style: .cancel) { (action) in
143 | print("点击了取消")
144 | }
145 | if customBlur {
146 | alert.customOverlayView = CustomOverlayView()
147 | }
148 | action.titleColor = SYSTEM_COLOR
149 | alert.addAction(action: action)
150 | self.present(alert, animated: true, completion: nil)
151 | }
152 |
153 | //示例15:alert 含有文本输入框
154 | func alertTest7() {
155 | let alert = SPAlertController.alertController(withTitle: "我是主标题", message: "我是副标题", preferredStyle: .alert, animationType: .default)
156 | let action1 = SPAlertAction.action(withTitle: "确定", style: .default) { (action) in
157 | print("点击了确定")
158 | }
159 | action1.isEnabled = false
160 | self.sureAction = action1
161 | // 设置第1个action的颜色
162 | action1.titleColor = SYSTEM_COLOR
163 | let action2 = SPAlertAction.action(withTitle: "取消", style: .destructive) { (action) in
164 | print("点击了取消")
165 | }
166 | action2.titleColor = .red
167 | alert.addAction(action: action2)
168 | alert.addAction(action: action1)
169 |
170 | alert.addTextFieldWithConfigurationHandler { (textField) in
171 | DLog("第1个文本输入框回调")
172 | // 这个block只会回调一次,因此可以在这里自由定制textFiled,如设置textField的相关属性,设置代理,添加addTarget,监听通知等
173 | self.phoneNumberTextField = textField
174 | textField.placeholder = "请输入手机号码"
175 | textField.clearButtonMode = .always
176 | textField.addTarget(self, action: #selector(self.textFieldDidChanged(textField:)), for: .editingChanged)
177 | }
178 | alert.addTextFieldWithConfigurationHandler { (textField) in
179 | DLog("第2个文本输入框回调")
180 | self.passwordTextField = textField
181 | textField.placeholder = "请输入密码"
182 | textField.clearButtonMode = .always
183 | textField.addTarget(self, action: #selector(self.textFieldDidChanged(textField:)), for: .editingChanged)
184 | }
185 | if customBlur {
186 | alert.customOverlayView = CustomOverlayView()
187 | }
188 | self.present(alert, animated: true, completion: nil)
189 | }
190 |
191 | @objc func textFieldDidChanged(textField: UITextField) {
192 | self.sureAction.isEnabled = false
193 | guard let phoneNumber = phoneNumberTextField.text else { return }
194 | guard let password = passwordTextField.text else { return }
195 | if password.count > 0 && phoneNumber.count > 0 {
196 | self.sureAction.isEnabled = true
197 | }
198 | }
199 | }
200 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/ViewController+Attributed.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController+Attributed.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2020/1/10.
6 | // Copyright © 2020 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension ViewController {
12 | // 示例16:富文本(action设置富文本)
13 | func attributedStringTest1() {
14 | let alertController = SPAlertController.alertController(withTitle: nil, message: nil, preferredStyle: .actionSheet, animationType: .default)
15 | let action1 = SPAlertAction.action(withTitle: nil, style: .default) { (action) in
16 | print("点击了拍摄")
17 | }
18 | let mainTitle1 = "拍摄"
19 | let subTitle1 = "照片或视频"
20 | let totalTitle1 = mainTitle1+"\n"+subTitle1
21 | let attrTitle1 = NSMutableAttributedString.init(string: totalTitle1)
22 | let paragraphStyle1 = NSMutableParagraphStyle.init()
23 | paragraphStyle1.lineSpacing = 3
24 | paragraphStyle1.lineBreakMode = .byWordWrapping
25 | paragraphStyle1.alignment = .center
26 | // 段落样式
27 | attrTitle1.addAttribute(.paragraphStyle, value: paragraphStyle1, range: .init(location: 0, length: totalTitle1.count))
28 | // 设置富文本子标题的字体
29 | attrTitle1.addAttribute(.font, value: UIFont.systemFont(ofSize: 12), range: NSRange.init(location: mainTitle1.count, length: subTitle1.count+1))
30 | attrTitle1.addAttribute(.foregroundColor, value: UIColor.gray, range: NSRange.init(location: mainTitle1.count, length: subTitle1.count+1))
31 |
32 | action1.attributedTitle = attrTitle1
33 |
34 |
35 | let action2 = SPAlertAction.action(withTitle: "从手机相册选择个", style: .default) { (action) in
36 | print("点击了`从手机相册选择`")
37 | }
38 | let action3 = SPAlertAction.action(withTitle: nil, style: .default) { (action) in
39 | print("点击了'用微视拍摄'")
40 | }
41 |
42 | let mainTitle3 = "用微视拍摄"
43 | let subTitle3 = "推广"
44 | let totalTitle3 = mainTitle3+"\n"+subTitle3
45 | let attrTitle3 = NSMutableAttributedString.init(string: totalTitle3)
46 | let paragraphStyle3 = NSMutableParagraphStyle.init()
47 | paragraphStyle3.lineSpacing = 3
48 | paragraphStyle3.lineBreakMode = .byWordWrapping
49 | paragraphStyle3.alignment = .center
50 | // 段落样式
51 | attrTitle1.addAttribute(.paragraphStyle, value: paragraphStyle3, range: .init(location: 0, length: totalTitle3.count))
52 | // 设置富文本子标题的字体
53 | attrTitle3.addAttribute(.font, value: UIFont.systemFont(ofSize: 12), range: NSRange.init(location: mainTitle3.count, length: subTitle3.count+1))
54 | attrTitle3.addAttribute(.foregroundColor, value: UIColor.gray, range: NSRange.init(location: mainTitle3.count, length: subTitle3.count+1))
55 |
56 | action3.attributedTitle = attrTitle3
57 |
58 | let action4 = SPAlertAction.action(withTitle: "取消", style: .cancel) { (action) in
59 | print("点击了取消")
60 | }
61 | if customBlur {
62 | alertController.customOverlayView = CustomOverlayView()
63 | }
64 | alertController.addAction(action: action1)
65 | alertController.addAction(action: action2)
66 | alertController.addAction(action: action3)
67 | alertController.addAction(action: action4)
68 | self.present(alertController, animated: true, completion: nil)
69 | }
70 |
71 |
72 | // 示例17:富文本(头部设置富文本)
73 | func attributedStringTest2() {
74 | let alertController = SPAlertController.alertController(withTitle: "", message: "确定拨打吗?", preferredStyle: .alert, animationType: .default)
75 | let num = "15012345689"
76 | let desc = "可能是一个电话号码"
77 | let totalTitle = num+"\n"+desc
78 | let attrTitle = NSMutableAttributedString.init(string: totalTitle)
79 |
80 | // 设置富文本子标题的字体
81 | attrTitle.addAttribute(.foregroundColor, value: SYSTEM_COLOR, range: NSRange.init(location: 0, length: num.count))
82 | alertController.attributedTitle = attrTitle
83 |
84 | if customBlur {
85 | alertController.customOverlayView = CustomOverlayView()
86 | }
87 | let action1 = SPAlertAction.action(withTitle: "取消", style: .destructive) { (action) in
88 | print("点击了`取消`")
89 | }
90 | let action2 = SPAlertAction.action(withTitle: "确定", style: .default) { (action) in
91 | print("点击了'确定'")
92 | }
93 | action2.titleColor = SYSTEM_COLOR
94 | alertController.addAction(action: action1)
95 | alertController.addAction(action: action2)
96 | self.present(alertController, animated: true, completion: nil)
97 | }
98 |
99 |
100 | }
101 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/ViewController+Custom.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController+Custom.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2020/1/11.
6 | // Copyright © 2020 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension ViewController {
12 |
13 | // 示例18:自定义头部(xib)
14 | func customTest1() {
15 | let sendAlertView = SendAlertView.loadFromNib()
16 | // sendAlertView.contentImage = UIImage.init(named: "send0.jpeg")
17 | let alertController = SPAlertController.alertController(withCustomHeaderView: sendAlertView, preferredStyle: .alert, animationType: .default)
18 | alertController.needDialogBlur = false
19 | // let fittingSize = sendAlertView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
20 | // alertController.updateCustomViewSize(size: fittingSize)
21 | let action1 = SPAlertAction.action(withTitle: "发送", style: .default) { (action) in
22 | print("点击了发送")
23 | }
24 | let action2 = SPAlertAction.action(withTitle: "取消", style: .destructive) { (action) in
25 | print("点击了取消")
26 | }
27 | if customBlur {
28 | alertController.customOverlayView = CustomOverlayView()
29 | }
30 | alertController.addAction(action: action2)
31 | alertController.addAction(action: action1)
32 | self.present(alertController, animated: true, completion: nil)
33 | }
34 | // 示例19:自定义整个对话框(alert样式)
35 | func customTest2() {
36 | let myView = MyView.loadFromNib()
37 | myView.cancelButton.addTarget(self, action: #selector(cancelButtonInCustomHeaderViewClicked), for: .touchUpInside)
38 | let alertController = SPAlertController.alertController(withCustomAlertView: myView, preferredStyle: .alert, animationType: .default)
39 | alertController.offsetForAlert = CGPoint.init(x: 0, y: -100)
40 | if customBlur {
41 | alertController.customOverlayView = CustomOverlayView()
42 | }
43 | self.present(alertController, animated: true, completion: nil)
44 | }
45 |
46 | @objc func cancelButtonInCustomHeaderViewClicked() {
47 | self.dismiss(animated: true, completion: nil)
48 | }
49 |
50 | // 示例20:自定义整个对话框(actionSheet样式从底部弹出)
51 | func customTest3() {
52 | let shoppingCartView = ShoppingCartView()
53 | let alertController = SPAlertController.alertController(withCustomAlertView: shoppingCartView, preferredStyle: .actionSheet, animationType: .fromBottom)
54 | alertController.needDialogBlur = false
55 | alertController.updateCustomViewSize(size: CGSize.init(width: ScreenWidth, height: ScreenHeight*2/3))
56 | if customBlur {
57 | alertController.customOverlayView = CustomOverlayView()
58 | }
59 | self.present(alertController, animated: true, completion: nil)
60 | }
61 |
62 | // 示例21:自定义整个对话框(actionSheet样式从右边弹出)
63 | func customTest4() {
64 | let shoppingCartView = ShoppingCartView.init(frame: CGRect.init(x: 0, y: 0, width: ScreenWidth-70, height: ScreenHeight))
65 | shoppingCartView.backgroundColor = .white
66 | let alertController = SPAlertController.alertController(withCustomAlertView: shoppingCartView, preferredStyle: .actionSheet, animationType: .fromRight)
67 | if customBlur {
68 | alertController.customOverlayView = CustomOverlayView()
69 | }
70 | self.present(alertController, animated: true, completion: nil)
71 | }
72 | // 示例22:自定义整个对话框(actionSheet样式从左边弹出)
73 | func customTest5() {
74 | let shoppingCartView = ShoppingCartView.init(frame: CGRect.init(x: 0, y: 0, width: ScreenWidth-70, height: ScreenHeight))
75 | shoppingCartView.backgroundColor = .white
76 | let alertController = SPAlertController.alertController(withCustomAlertView: shoppingCartView, preferredStyle: .actionSheet, animationType: .fromLeft)
77 | if customBlur {
78 | alertController.customOverlayView = CustomOverlayView()
79 | }
80 | self.present(alertController, animated: true, completion: nil)
81 | }
82 |
83 | // 示例23:自定义整个对话框(actionSheet样式从顶部弹出)
84 | func customTest6() {
85 | let shoppingCartView = CommodityListView.init(frame: CGRect.init(x: 0, y: 0, width: ScreenWidth, height: 200))
86 | shoppingCartView.backgroundColor = .white
87 | let alertController = SPAlertController.alertController(withCustomAlertView: shoppingCartView, preferredStyle: .actionSheet, animationType: .fromTop)
88 | if customBlur {
89 | alertController.customOverlayView = CustomOverlayView()
90 | }
91 | self.present(alertController, animated: true, completion: nil)
92 | }
93 |
94 | // 示例24:自定义整个对话框(pickerView)
95 | func customTest7() {
96 | let pickerView = PickerView.loadFromNib()
97 | pickerView.backgroundColor = .white
98 | pickerView.cancelClickedClosure = { [weak self] in
99 | self?.presentedViewController?.dismiss(animated: true, completion: nil)
100 | }
101 | pickerView.doneClickedClosure = { [weak self] in
102 | self?.presentedViewController?.dismiss(animated: true, completion: nil)
103 | }
104 | let alertController = SPAlertController.alertController(withCustomAlertView: pickerView, preferredStyle: .actionSheet, animationType: .fromBottom)
105 | if customBlur {
106 | alertController.customOverlayView = CustomOverlayView()
107 | }
108 | self.present(alertController, animated: true, completion: nil)
109 | }
110 | // 示例25:自定义action部分
111 | func customTest8() {
112 | // scoreview的子控件采用的是自动布局,由于高度上能够由子控件撑起来,所以高度可以给0,如果宽度也能撑起,宽度也可以给0
113 | let scoreView = ScoreView.init(frame: CGRect.init(x: 0, y: 0, width: 275, height: 0))
114 | scoreView.backgroundColor = .white
115 | scoreView.finishClickedClosure = { [weak self] in
116 | self?.presentedViewController?.dismiss(animated: true, completion: nil)
117 | }
118 |
119 | let alertController = SPAlertController.alertController(withCustomActionSequenceView: scoreView, title: "提示", message: "请给我们的app打分", preferredStyle: .alert, animationType: .default)
120 | alertController.needDialogBlur = false
121 | if customBlur {
122 | alertController.customOverlayView = CustomOverlayView()
123 | }
124 | self.present(alertController, animated: true, completion: nil)
125 | }
126 | // 示例25:插入一个组件
127 | func customTest9() {
128 | let centerView = MyCenterView.init(frame: CGRect.init(x: 0, y: 0, width: ScreenWidth-40, height: 200))
129 | let alertController = SPAlertController.alertController(withTitle: "我是主标题", message: "我是副标题", preferredStyle: .alert, animationType: .default)
130 | // 插入一个view
131 | alertController.insertComponentView(centerView)
132 |
133 | let action1 = SPAlertAction.action(withTitle: "第1个", style: .default) { (action) in
134 | print("点击了第1个")
135 | }
136 | action1.titleColor = SYSTEM_COLOR
137 | let action2 = SPAlertAction.action(withTitle: "第2个", style: .destructive) { (action) in
138 | print("点击了第2个")
139 | }
140 | action2.titleColor = .red
141 | if customBlur {
142 | alertController.customOverlayView = CustomOverlayView()
143 | }
144 | alertController.addAction(action: action1)
145 | alertController.addAction(action: action2)
146 | self.present(alertController, animated: true, completion: nil)
147 | }
148 |
149 | }
150 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/ViewController+Special.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController+Special.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2020/1/14.
6 | // Copyright © 2020 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension ViewController {
12 |
13 | // 示例26:当按钮过多时
14 | func specialtest1() {
15 | let alertController = SPAlertController.alertController(withTitle: "请滑动查看更多内容", message: "谢谢", preferredStyle: .actionSheet, animationType: .default)
16 | alertController.minDistanceToEdges = 100
17 | for i in 0..<15 {
18 | let action = SPAlertAction.action(withTitle: "第\(i)个", style: .default) { (action) in
19 | print("点击了第\(i)个")
20 | }
21 | alertController.addAction(action: action)
22 | }
23 | let cancelAction = SPAlertAction.action(withTitle: "取消", style: .cancel) { (action) in
24 | print("点击了cancel")
25 | }
26 | if customBlur {
27 | alertController.customOverlayView = CustomOverlayView()
28 | }
29 | alertController.addAction(action: cancelAction)
30 | self.present(alertController, animated: true, completion: nil)
31 | }
32 |
33 | // 示例27:当文字和按钮同时过多时,文字占据更多位置
34 | func specialtest2() {
35 | let alertController = SPAlertController.alertController(withTitle: "请滑动查看更多内容", message: "谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢", preferredStyle: .actionSheet, animationType: .default)
36 | // alertController.minDistanceToEdges = 100
37 | for i in 0..<5 {
38 | let action = SPAlertAction.action(withTitle: "第\(i)个", style: .default) { (action) in
39 | print("点击了第\(i)个")
40 | }
41 | alertController.addAction(action: action)
42 | }
43 | let cancelAction = SPAlertAction.action(withTitle: "取消", style: .cancel) { (action) in
44 | print("点击了cancel")
45 | }
46 | if customBlur {
47 | alertController.customOverlayView = CustomOverlayView()
48 | }
49 | alertController.addAction(action: cancelAction)
50 | self.present(alertController, animated: true, completion: nil)
51 | }
52 |
53 | // 示例28:action上的文字过长(垂直)
54 | func specialtest4() {
55 | let alertController = SPAlertController.alertController(withTitle: "提示", message: "SPAlertControllerStyleAlert样式下2个按钮默认是水平排列,如果存在按钮文字过长,则自动会切换为垂直排列,除非外界设置了'actionAxis'。如果垂直排列后文字依然过长,则会压缩字体适应宽度,压缩到0.5倍封顶", preferredStyle: .alert, animationType: .default)
56 | alertController.messageColor = .red
57 | let action1 = SPAlertAction.action(withTitle: "明白", style: .default) { (action) in
58 | print("点击了明白")
59 | }
60 | let action2 = SPAlertAction.action(withTitle: "我的文字太长了,所以垂直排列显示更多文字,垂直后依然显示不全则压缩字体,压缩到0.5倍封顶", style: .default) { (action) in
61 | print("点击了'上九天揽月,下五洋捉鳖")
62 | }
63 | if customBlur {
64 | alertController.customOverlayView = CustomOverlayView()
65 | }
66 | action2.titleColor = SYSTEM_COLOR
67 | alertController.addAction(action: action1)
68 | alertController.addAction(action: action2)
69 | self.present(alertController, animated: true, completion: nil)
70 | }
71 | // 示例29:action上的文字过长(水平)
72 | func specialtest5() {
73 | let alertController = SPAlertController.alertController(withTitle: "提示", message: "SPAlertControllerStyleAlert样式下2个按钮默认是水平排列,如果存在按钮文字过长,则自动会切换为垂直排列,本例之所以为水平排列,是因为外界设置了'actionAxis'为UILayoutConstraintAxisHorizontal", preferredStyle: .alert, animationType: .default)
74 | alertController.messageColor = .red
75 | alertController.actionAxis = .horizontal
76 | let action1 = SPAlertAction.action(withTitle: "明白", style: .default) { (action) in
77 | print("点击了明白")
78 | }
79 | let action2 = SPAlertAction.action(withTitle: "我的文字太长了,会压缩字体", style: .default) { (action) in
80 | print("点击了'我的文字太长了,会压缩字体")
81 | }
82 | if customBlur {
83 | alertController.customOverlayView = CustomOverlayView()
84 | }
85 | action2.titleColor = SYSTEM_COLOR
86 | alertController.addAction(action: action1)
87 | alertController.addAction(action: action2)
88 | self.present(alertController, animated: true, completion: nil)
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/Swift_SPAlertController/Swift_SPAlertController/ViewController+background.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController+background.swift
3 | // Swift_SPAlertController
4 | //
5 | // Created by lidongxi on 2020/1/14.
6 | // Copyright © 2020 lidongxi. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | extension ViewController {
11 |
12 | func background(appearanceStyle: SPBackgroundViewAppearanceStyle) {
13 |
14 | let alertController = SPAlertController.alertController(withTitle: "我是主标题", message: "我是副标题", preferredStyle: .actionSheet)
15 | alertController.needDialogBlur = lookBlur
16 | let action1 = SPAlertAction.action(withTitle: "Default", style: .default) { (action) in
17 | print("点击了Default")
18 | }
19 | let action2 = SPAlertAction.action(withTitle: "Destructive", style: .destructive) { (action) in
20 | print("点击了Destructive")
21 | }
22 | let action3 = SPAlertAction.action(withTitle: "Cancel", style: .cancel) { (action) in
23 | print("点击了Cancel------")
24 | }
25 |
26 | alertController.addAction(action: action1)
27 | alertController.addAction(action: action3)
28 | alertController.addAction(action: action2)
29 | if customBlur {
30 | alertController.customOverlayView = CustomOverlayView()
31 | } else {
32 | if appearanceStyle == .translucent {
33 | // 0.5是半透明(默认),设置1为不透明,0为全透明
34 | alertController.setBackgroundViewAppearanceStyle(appearanceStyle, alpha: 0.5)
35 | } else {
36 | alertController.setBackgroundViewAppearanceStyle(appearanceStyle, alpha: 1.0)
37 | }
38 | }
39 | self.present(alertController, animated: true, completion: nil)
40 |
41 | }
42 | }
43 |
--------------------------------------------------------------------------------