├── .gitignore
├── Example
├── Example.storyboard
└── ExampleActionSheetVC.swift
├── LICENSE
├── MMActionSheet.podspec
├── Package.swift
├── README.md
├── Sources
└── MMActionSheet
│ ├── MMActionSheet.swift
│ ├── MMButton.swift
│ ├── MMButtonItem.swift
│ ├── MMButtonTitleColor.swift
│ ├── MMButtonType.swift
│ ├── MMTitleItem.swift
│ └── MMTools.swift
├── Tests
└── MMActionSheetTests
│ └── MMActionSheetTests.swift
├── gifs
├── mmactionsheet.png
├── mmactionsheet_1.gif
├── mmactionsheet_2.gif
├── mmactionsheet_3.gif
├── mmactionsheet_4.gif
├── mmactionsheet_5.gif
├── mmactionsheet_6.gif
├── mmactionsheet_7.gif
└── mmactionsheet_8.gif
├── swiftui.xcodeproj
├── project.pbxproj
└── project.xcworkspace
│ └── contents.xcworkspacedata
└── swiftui
├── AppDelegate.swift
├── Assets.xcassets
└── AppIcon.appiconset
│ └── Contents.json
├── Base.lproj
└── LaunchScreen.storyboard
└── Info.plist
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | swiftui.xcodeproj/project.xcworkspace/xcuserdata
3 | swiftui.xcodeproj/project.xcworkspace/xcshareddata
4 | swiftui.xcworkspace/xcuserdata/
5 | swiftui.xcworkspace/xcshareddata/
6 | swiftui.xcodeproj/xcshareddata/
7 | swiftui.xcodeproj/xcuserdata/
8 |
--------------------------------------------------------------------------------
/Example/Example.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
42 |
61 |
80 |
99 |
118 |
137 |
156 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
--------------------------------------------------------------------------------
/Example/ExampleActionSheetVC.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ExampleActionSheetVC.swift
3 | // swiftui
4 | //
5 | // Created by 郭永红 on 2017/10/9.
6 | // Copyright © 2017年 keeponrunning. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ExampleActionSheetVC: UIViewController {
12 | override func viewDidLoad() {
13 | super.viewDidLoad()
14 | view.backgroundColor = UIColor.white
15 | // Do any additional setup after loading the view.
16 | }
17 |
18 | @IBAction func presentActionSheet(_ sender: Any) {
19 | let buttons = [
20 | MMButtonItem(title: "拍照", titleColor: .default, buttonType: .default(index: 0)),
21 | MMButtonItem(title: "相册", titleColor: .default, buttonType: .default(index: 1)),
22 | ]
23 |
24 | let titleItem = MMTitleItem(title: "请选择照片", titleColor: .red)
25 | let cancelButton = MMButtonItem(title: "取消", titleColor: .default, buttonType: .cancel)
26 |
27 | let mmActionSheet = MMActionSheet(title: titleItem, buttons: buttons, duration: nil, cancelButton: cancelButton)
28 | mmActionSheet.selectionClosure = { item in
29 | if let currentItem = item, let type = currentItem.buttonType {
30 | switch type {
31 | case let .default(index):
32 | print("== default index \(index) ==")
33 | case .cancel:
34 | print("cancel")
35 | }
36 | }
37 | }
38 | mmActionSheet.present()
39 | }
40 |
41 | @IBAction func showWechatActionSheet(_ sender: Any) {
42 | let buttons = [
43 | MMButtonItem(title: "发送给朋友", titleColor: .default, buttonType: .default(index: 0)),
44 | MMButtonItem(title: "收藏", titleColor: .default, buttonType: .default(index: 1)),
45 | MMButtonItem(title: "保存图片", titleColor: .default, buttonType: .default(index: 2)),
46 | MMButtonItem(title: "打开", titleColor: .default, buttonType: .default(index: 3)),
47 | MMButtonItem(title: "编辑", titleColor: .default, buttonType: .default(index: 4)),
48 | MMButtonItem(title: "定位到聊天位置", titleColor: .default, buttonType: .default(index: 5)) ]
49 | let cancelButton = MMButtonItem(title: "取消", titleColor: .danger, buttonType: .cancel)
50 | let mmActionSheet1 = MMActionSheet(title: nil, buttons: buttons, duration: nil, cancelButton: cancelButton)
51 | mmActionSheet1.selectionClosure = { item in
52 | if let currentItem = item, let type = currentItem.buttonType {
53 | switch type {
54 | case let .default(index):
55 | print("== default index \(index) ==")
56 | case .cancel:
57 | print("cancel")
58 | }
59 | }
60 | }
61 | mmActionSheet1.present()
62 | }
63 |
64 | @IBAction func showNoTitleActionSheet(_ sender: Any) {
65 | let buttons = [
66 | MMButtonItem(title: "微信", titleColor: .default, buttonType: .default(index: 0)),
67 | MMButtonItem(title: "QQ", titleColor: .default, buttonType: .default(index: 1)),
68 | MMButtonItem(title: "支付宝", titleColor: .default, buttonType: .default(index: 2)),
69 | MMButtonItem(title: "新浪微博", titleColor: .default, buttonType: .default(index: 3)),
70 | ]
71 |
72 | let mmActionSheet2 = MMActionSheet(title: nil, buttons: buttons, duration: nil, cancelButton: nil)
73 | mmActionSheet2.selectionClosure = { item in
74 | if let currentItem = item, let type = currentItem.buttonType {
75 | switch type {
76 | case let .default(index):
77 | print("== default index \(index) ==")
78 | case .cancel:
79 | print("cancel")
80 | }
81 | }
82 | }
83 | mmActionSheet2.present()
84 | }
85 |
86 | @IBAction func showNoCancelActionSheet(_ sender: Any) {
87 | let buttons = [
88 | MMButtonItem(title: "男", titleColor: .blue, buttonType: .default(index: 0)),
89 | MMButtonItem(title: "女", titleColor: .danger, buttonType: .default(index: 1)),
90 | ]
91 |
92 | let titleItem = MMTitleItem(title: "请选择性别", titleColor: .purple)
93 |
94 | let mmActionSheet3 = MMActionSheet(title: titleItem, buttons: buttons, duration: nil, cancelButton: nil)
95 | mmActionSheet3.selectionClosure = { item in
96 | if let currentItem = item, let type = currentItem.buttonType {
97 | switch type {
98 | case let .default(index):
99 | print("== default index \(index) ==")
100 | case .cancel:
101 | print("cancel")
102 | }
103 | }
104 | }
105 | mmActionSheet3.present()
106 | }
107 |
108 | @IBAction func showColorTitleActionSheet(_ sender: Any) {
109 | let buttons = [
110 | MMButtonItem(title: "查看", titleColor: .custom(.red), buttonType: .default(index: 0)),
111 | MMButtonItem(title: "编辑", titleColor: .custom(.green), buttonType: .default(index: 1)),
112 | MMButtonItem(title: "删除", titleColor: .custom(.brown), buttonType: .default(index: 2)),
113 | ]
114 |
115 | let titleItem = MMTitleItem(title: "文件管理", titleColor: .orange, titleFont: .systemFont(ofSize: 18.0))
116 | let cancelButton = MMButtonItem(title: "返回", titleColor: .custom(.orange), buttonType: .cancel)
117 |
118 | let mmActionSheet4 = MMActionSheet(title: titleItem, buttons: buttons, duration: nil, cancelButton: cancelButton)
119 | mmActionSheet4.selectionClosure = { item in
120 | if let currentItem = item, let type = currentItem.buttonType {
121 | switch type {
122 | case let .default(index):
123 | print("== default index \(index) ==")
124 | case .cancel:
125 | print("cancel")
126 | }
127 | }
128 | }
129 | mmActionSheet4.present()
130 | }
131 |
132 | @IBAction func showColorBgTitleActionSheet(_ sender: Any) {
133 | let buttons = [
134 | MMButtonItem(
135 | title: "查看",
136 | buttonType: .default(index: 0),
137 | backgroudImageColorNormal:.custom(.purple),
138 | backgroudImageColorHighlight:.custom(.yellow)
139 | ),
140 | MMButtonItem(
141 | title: "编辑",
142 | buttonType: .default(index: 1),
143 | backgroudImageColorNormal:.custom(.green)
144 | ),
145 | MMButtonItem(
146 | title: "删除",
147 | buttonType: .default(index: 2),
148 | backgroudImageColorNormal:.custom(.red),
149 | backgroudImageColorHighlight:.custom(.orange)
150 | )
151 | ]
152 |
153 | let titleItem = MMTitleItem(title: "文件管理", titleFont: .systemFont(ofSize: 18.0),backgroundColor: .custom(.cyan))
154 | let cancelButton = MMButtonItem(
155 | title: "返回",
156 | titleColor: .custom(.orange),
157 | buttonType: .cancel,
158 | backgroudImageColorNormal:.custom(.blue)
159 | )
160 |
161 | let mmActionSheet4 = MMActionSheet(title: titleItem, buttons: buttons, duration: nil, cancelButton: cancelButton)
162 | mmActionSheet4.selectionClosure = { item in
163 | if let currentItem = item, let type = currentItem.buttonType {
164 | switch type {
165 | case let .default(index):
166 | print("== default index \(index) ==")
167 | case .cancel:
168 | print("cancel")
169 | }
170 | }
171 | }
172 | mmActionSheet4.present()
173 | }
174 |
175 | @IBAction func showManyTitleActionSheet(_ sender: Any) {
176 | let buttons = [
177 | MMButtonItem(title: "发送给朋友", titleColor: .default, buttonType: .default(index: 0)),
178 | MMButtonItem(title: "收藏", titleColor: .default, buttonType: .default(index: 1)),
179 | MMButtonItem(title: "保存图片", titleColor: .default, buttonType: .default(index: 2)),
180 | MMButtonItem(title: "打开", titleColor: .default, buttonType: .default(index: 3)),
181 | MMButtonItem(title: "编辑", titleColor: .default, buttonType: .default(index: 4)),
182 | MMButtonItem(title: "定位到聊天位置", titleColor: .default, buttonType: .default(index: 5)),
183 | MMButtonItem(title: "发送给朋友", titleColor: .default, buttonType: .default(index: 0)),
184 | MMButtonItem(title: "收藏", titleColor: .default, buttonType: .default(index: 1)),
185 | MMButtonItem(title: "保存图片", titleColor: .default, buttonType: .default(index: 2)),
186 | MMButtonItem(title: "打开", titleColor: .default, buttonType: .default(index: 3)),
187 | MMButtonItem(title: "编辑", titleColor: .default, buttonType: .default(index: 4)),
188 | MMButtonItem(title: "定位到聊天位置", titleColor: .default, buttonType: .default(index: 5))
189 | ]
190 |
191 | let titleItem = MMTitleItem(title: "多个选项滚动列表", titleColor: .purple)
192 | let cancelButton = MMButtonItem(title: "取消", titleColor: .danger, buttonType: .cancel)
193 | let mmActionSheet1 = MMActionSheet(title: titleItem, buttons: buttons, duration: nil, cancelButton: cancelButton)
194 | mmActionSheet1.selectionClosure = { item in
195 | if let currentItem = item, let type = currentItem.buttonType {
196 | switch type {
197 | case let .default(index):
198 | print("== default index \(index) ==")
199 | case .cancel:
200 | print("cancel")
201 | }
202 | }
203 | }
204 | mmActionSheet1.present()
205 | }
206 |
207 | @IBAction func showTopCornerActionSheet(_ sender: Any) {
208 | let buttons = [
209 | MMButtonItem(title: "查看", buttonType: .default(index: 0)),
210 | MMButtonItem(title: "编辑", buttonType: .default(index: 1)),
211 | MMButtonItem(title: "删除", buttonType: .default(index: 2))
212 | ]
213 |
214 | let titleItem = MMTitleItem(title: "文件管理", titleFont: .systemFont(ofSize: 18.0), backgroundColor: .custom(MMTools.DefaultColor.normalColor))
215 | let cancelButton = MMButtonItem(title: "返回", buttonType: .cancel)
216 |
217 | let mmActionSheet1 = MMActionSheet(title: titleItem, buttons: buttons, duration: nil, cancelButton: cancelButton)
218 | mmActionSheet1.topCornerRadius = 20
219 | mmActionSheet1.selectionClosure = { item in
220 | if let currentItem = item, let type = currentItem.buttonType {
221 | switch type {
222 | case let .default(index):
223 | print("== default index \(index) ==")
224 | case .cancel:
225 | print("cancel")
226 | }
227 | }
228 | }
229 | mmActionSheet1.present()
230 | }
231 | }
232 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 小冒
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/MMActionSheet.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 |
3 | s.name = "MMActionSheet"
4 | s.version = "2.0.0"
5 | s.summary = "MMActionSheet is an simple pop-up selection box(ActionSheet) written in pure Swift"
6 | s.homepage = "https://github.com/MinMao-Hub"
7 | s.license = "MIT"
8 | s.author = { "gyh" => "m12860gyh@gmail.com" }
9 | s.platform = :ios, "8.0"
10 | s.swift_version = '4.0'
11 | s.source = { :git => "https://github.com/MinMao-Hub/MMActionSheet.git", :tag => "#{s.version}" }
12 | s.source_files = "Sources/MMActionSheet"
13 | end
14 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.3
2 | // The swift-tools-version declares the minimum version of Swift required to build this package.
3 |
4 | import PackageDescription
5 |
6 | let package = Package(
7 | name: "MMActionSheet",
8 | products: [
9 | // Products define the executables and libraries a package produces, and make them visible to other packages.
10 | .library(
11 | name: "MMActionSheet",
12 | targets: ["MMActionSheet"]),
13 | ],
14 | dependencies: [
15 | // Dependencies declare other packages that this package depends on.
16 | // .package(url: /* package url */, from: "1.0.0"),
17 | ],
18 | targets: [
19 | // Targets are the basic building blocks of a package. A target can define a module or a test suite.
20 | // Targets can depend on other targets in this package, and on products in packages this package depends on.
21 | .target(
22 | name: "MMActionSheet",
23 | dependencies: []),
24 | .testTarget(
25 | name: "MMActionSheetTests",
26 | dependencies: ["MMActionSheet"]),
27 | ]
28 | )
29 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | [](https://cocoapods.org/pods/MMActionSheet)
4 | [](https://github.com/MinMao-Hub/MMActionSheet)
5 | [](https://cocoapods.org/pods/MMActionSheet)
6 | [](https://github.com/MinMao-Hub/MMActionSheet)
7 | [](http://opensource.org/licenses/MIT)
8 |
9 | ### Introduction
10 |
11 | MMActionSheet 是一个简单的弹出选择框,使用纯swift编写,类似于微信的actionsheet
12 |
13 | MMActionSheet is an simple pop-up selection box(ActionSheet) written in pure Swift. Similar to the wechat actionsheet
14 |
15 | ### Rquirements
16 |
17 | * iOS 8.0+
18 | * swift 4.0+
19 |
20 |
21 | ### Installation
22 |
23 | #### Swift Package Manager
24 |
25 | To install with Swift Package Manager, add this package to your project’s 'Swift Packages' section. Or add the following line to your Package.swift:
26 |
27 | ```
28 | .package(url: "https://github.com/MinMao-Hub/MMActionSheet.git", from: "2.0.0")
29 | ```
30 |
31 |
32 | #### Install with Cocoapods
33 |
34 | * To install MMActionSheet using CocoaPods, integrate it in your existing Podfile, or create a new Podfile:
35 |
36 | ```
37 | platform :ios, '8.0'
38 | use_frameworks!
39 |
40 | target 'MyApp' do
41 | pod 'MMActionSheet', '~> 2.0'
42 | end
43 | ```
44 | * Execute command:
45 | * `pod repo update master`
46 | * `pod install`
47 | * Import MMActionSheet in you code
48 | * `import MMActionSheet`
49 |
50 |
51 | #### Manual import
52 |
53 | Just [clone](https://github.com/MinMao-Hub/MMActionSheet.git) and add components dir to your project.
54 |
55 | ### Example
56 |
57 | |desc|preview|
58 | |:--:|:--:|
59 | |Has `Cancel` buttons and `Title`
【有标题和取消按钮】||
60 | |Has a `Cancel` button but no `Title`
【无标题有取消按钮】||
61 | |No `Cancel` button and no `Title`
【无标题无取消按钮】||
62 | |Has a `Title` but no `Cancel` button
【有标题无取消按钮】||
63 | |Customize text color
【自定义文本颜色】||
64 | |Customize title background color, etc
【自定义背景色、选中背景色等】||
65 | |Multi data scrolling
【多数据滚动】||
66 | |Set top CornerRadius
【设置顶部圆角】||
67 |
68 |
69 |
70 | ### Usage
71 |
72 | ```swift
73 | let buttons = [
74 | MMButtonItem(title: "拍照", titleColor: .default, buttonType: .default(index: 0)),
75 | MMButtonItem(title: "相册", titleColor: .default, buttonType: .default(index: 1)),
76 | ]
77 |
78 | let titleItem = MMTitleItem(title: "请选择照片", titleColor: .red)
79 | let cancelButton = MMButtonItem(title: "取消", titleColor: .default, buttonType: .cancel)
80 |
81 | let mmActionSheet = MMActionSheet(title: titleItem, buttons: buttons, duration: nil, cancelButton: cancelButton)
82 | mmActionSheet.selectionClosure = { item in
83 | if let currentItem = item, let type = currentItem.buttonType {
84 | switch type {
85 | case let .default(index):
86 | print("== default index \(index) ==")
87 | case .cancel:
88 | print("cancel")
89 | }
90 | }
91 | }
92 | mmActionSheet.present()
93 |
94 | ```
95 |
96 | *PS:注释*
97 |
98 | * create actionsheet && init 【创建并初始化】
99 |
100 | `MMActionSheet(title: titleItem, buttons: buttons, duration: nil, cancelButton: cancelButton)`
101 |
102 | * argument【参数描述】
103 |
104 | * `title` 头部标题,类型为 `MMTitleItem `
105 | * `buttons` 事件按钮数组,类型为`Array`,里面包含每一个按钮的具体属性:
106 |
107 | ```
108 | public var title: String?
109 | public var titleColor: MMButtonTitleColor? = .default
110 | public var titleFont: UIFont? = .systemFont(ofSize: 16.0)
111 | public var buttonType: MMButtonType?
112 | public var backgroudImageColorNormal: MMButtonTitleColor? = .custom(MMTools.DefaultColor.normalColor)
113 | public var backgroudImageColorHighlight: MMButtonTitleColor? = .custom(MMTools.DefaultColor.highlightColor)
114 | ```
115 | * `title` 按钮标题
116 | * `titleColor ` 按钮颜色
117 | * `titleFont ` 按钮字体
118 | * `type` 按钮类型(展示不同的标题颜色)【枚举类型 - `default`,`blue`,`danger`, `custom`】
119 | * `backgroudImageColorNormal` 正常背景色
120 | * `backgroudImageColorHighlight` 选中背景色
121 | * `duration ` 动画时长
122 | * `cancelBtn ` 取消按钮属性,属性跟上述buttons内部button属性一致;若设置为`nil`则不显示该按钮
123 | * callback【回调】
124 |
125 | ```
126 | mmActionSheet.selectionClosure = { item in
127 | if let currentItem = item, let type = currentItem.buttonType {
128 | switch type {
129 | case let .default(index):
130 | print("== default index \(index) ==")
131 | case .cancel:
132 | print("cancel")
133 | }
134 | }
135 | }
136 | ```
137 | `item ` 该handler即为buttons里面的`MMButtonItem`,对应的回调过来
138 |
139 | * present【弹出actionsheet】
140 |
141 | `mmActionSheet.present()`
142 |
143 |
144 | ### Contribution
145 |
146 | You are welcome to fork and submit pull requests.
147 |
148 | ### License
149 |
150 | MMActionSheet is open-sourced software licensed under the MIT license.
151 |
--------------------------------------------------------------------------------
/Sources/MMActionSheet/MMActionSheet.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MMActionSheet.swift
3 | // swiftui
4 | //
5 | // Created by 郭永红 on 2017/10/9.
6 | // Copyright © 2017年 keeponrunning. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public class MMActionSheet: UIView {
12 | /// MMSelectionClosure
13 | public typealias MMSelectionClosure = (_ item: MMButtonItem?) -> Void
14 | /// SelectionClosure
15 | public var selectionClosure: MMSelectionClosure?
16 | /// top cornerRadius
17 | public var topCornerRadius: CGFloat = 0
18 |
19 | /// Parmeters
20 | private var title: MMTitleItem?
21 | private var buttons: [MMButtonItem] = []
22 | private var duration: Double?
23 | private var cancelButton: MMButtonItem?
24 |
25 | /// Constants
26 | private struct Constants {
27 | /// 按钮与按钮之间的分割线高度
28 | static let mmdivideLineHeight: CGFloat = 1
29 | /// 屏幕Bounds
30 | static let mmscreenBounds = UIScreen.main.bounds
31 | /// 屏幕大小
32 | static let mmscreenSize = UIScreen.main.bounds.size
33 | /// 屏幕宽度
34 | static let mmscreenWidth = mmscreenBounds.width
35 | /// 屏幕高度
36 | static let mmscreenHeight = mmscreenBounds.height
37 | /// button高度
38 | static let mmbuttonHeight: CGFloat = 48.0 * mmscreenBounds.width / 375
39 | /// 标题的高度
40 | static let mmtitleHeight: CGFloat = 40.0 * mmscreenBounds.width / 375
41 | /// 取消按钮与其他按钮之间的间距
42 | static let mmbtnPadding: CGFloat = 5 * mmscreenBounds.width / 375
43 | /// mmdefaultDuration
44 | static let mmdefaultDuration = 0.25
45 | /// sheet的最大高度
46 | static let mmmaxHeight = mmscreenHeight * 0.62
47 | /// 适配iphoneX
48 | static let paddng_bottom: CGFloat = MMTools.isIphoneX ? 34.0 : 0.0
49 | }
50 |
51 | /// ActionSheet
52 | private var actionSheetView: UIView = UIView()
53 | private var actionSheetHeight: CGFloat = 0
54 |
55 | public var actionSheetViewBackgroundColor: UIColor? = MMTools.DefaultColor.backgroundColor
56 |
57 | /// scrollView
58 | private var scrollView: UIScrollView = UIScrollView()
59 |
60 | public var buttonBackgroundColor: UIColor?
61 |
62 | /// Init
63 | override init(frame: CGRect) {
64 | super.init(frame: frame)
65 | }
66 |
67 | public required init?(coder aDecoder: NSCoder) {
68 | fatalError("init(coder:) has not been implemented")
69 | }
70 |
71 | /// 初始化
72 | ///
73 | /// - Parameters:
74 | /// - title: 标题
75 | /// - buttons: 按钮数组
76 | /// - duration: 动画时长
77 | /// - cancel: 是否需要取消按钮
78 | public convenience init(
79 | title: MMTitleItem?,
80 | buttons: [MMButtonItem],
81 | duration: Double?,
82 | cancelButton: MMButtonItem?
83 | ) {
84 | /// 半透明背景
85 | self.init(frame: Constants.mmscreenBounds)
86 | self.title = title
87 | self.buttons = buttons
88 |
89 | self.duration = duration ?? Constants.mmdefaultDuration
90 | self.cancelButton = cancelButton
91 |
92 | /// 添加单击事件,隐藏sheet
93 | let singleTap = UITapGestureRecognizer(target: self, action: #selector(singleTapDismiss))
94 | singleTap.delegate = self
95 | addGestureRecognizer(singleTap)
96 |
97 | /// actionSheet
98 | initActionSheet()
99 | /// 初始化UI
100 | initUI()
101 | }
102 |
103 | func initActionSheet() {
104 | let btnCount = buttons.count
105 |
106 | var tHeight: CGFloat = 0.0
107 | if title != nil {
108 | tHeight = Constants.mmtitleHeight
109 | }
110 |
111 | var cancelHeight: CGFloat = 0.0
112 | if cancelButton != nil {
113 | cancelHeight = Constants.mmbuttonHeight + Constants.mmbtnPadding
114 | }
115 |
116 | let contentHeight = CGFloat(btnCount) * Constants.mmbuttonHeight + CGFloat(btnCount) * Constants.mmdivideLineHeight
117 | let height = min(contentHeight, Constants.mmmaxHeight - tHeight - cancelHeight)
118 |
119 | scrollView.frame = CGRect(x: 0, y: tHeight, width: Constants.mmscreenWidth, height: height)
120 | actionSheetView.addSubview(scrollView)
121 |
122 | actionSheetHeight = tHeight + height + cancelHeight + Constants.paddng_bottom
123 |
124 | let aFrame: CGRect = CGRect(x: 0, y: Constants.mmscreenHeight, width: Constants.mmscreenWidth, height: actionSheetHeight)
125 | actionSheetView.frame = aFrame
126 | addSubview(actionSheetView)
127 |
128 | /// 根据内容高度计算动画时长
129 | duration = duration ?? (Constants.mmdefaultDuration * Double(actionSheetHeight / 216))
130 | }
131 |
132 | func initUI() {
133 | /// setTitleView
134 | setTitleView()
135 | /// setButtons
136 | setButtons()
137 | /// Cancel Button
138 | setCancelButton()
139 | /// setExtraView
140 | setExtraView()
141 | }
142 |
143 | /// Title
144 | private func setTitleView() {
145 | /// 标题不为空,则添加标题
146 | if title != nil {
147 | let titleFrame = CGRect(x: 0, y: 0, width: Constants.mmscreenWidth, height: Constants.mmtitleHeight)
148 | let titlelabel = UILabel(frame: titleFrame)
149 | titlelabel.text = title!.text
150 | titlelabel.textAlignment = title!.textAlignment!
151 | titlelabel.textColor = title!.textColor
152 | titlelabel.font = title!.textFont
153 | titlelabel.backgroundColor = title!.backgroundColor?.rawValue
154 | actionSheetView.addSubview(titlelabel)
155 | }
156 | }
157 |
158 | /// Buttons
159 | private func setButtons() {
160 | let contentHeight = CGFloat(buttons.count) * Constants.mmbuttonHeight + CGFloat(buttons.count) * Constants.mmdivideLineHeight
161 | let view = UIView(frame: CGRect(x: 0, y: 0, width: Constants.mmscreenWidth, height: contentHeight))
162 | view.clipsToBounds = true
163 | scrollView.addSubview(view)
164 | scrollView.contentSize = CGSize(width: Constants.mmscreenWidth, height: contentHeight)
165 |
166 | let buttonsCount = buttons.count
167 | for index in 0 ..< buttonsCount {
168 | let item = buttons[index]
169 | let origin_y = Constants.mmbuttonHeight * CGFloat(index) + Constants.mmdivideLineHeight * CGFloat(index)
170 |
171 | let button = MMButton(type: .custom)
172 | button.frame = CGRect(x: 0.0, y: origin_y, width: Constants.mmscreenWidth, height: Constants.mmbuttonHeight)
173 | /// Button Item
174 | button.item = item
175 | button.addTarget(self, action: #selector(actionClick), for: .touchUpInside)
176 | view.addSubview(button)
177 | }
178 | }
179 |
180 | /// ExtraView
181 | private func setExtraView() {
182 | guard MMTools.isIphoneX else { return }
183 | let frame = CGRect(x: 0, y: self.actionSheetView.bounds.size.height - Constants.paddng_bottom, width: Constants.mmscreenWidth, height: Constants.paddng_bottom)
184 | let extraView = UIView()
185 | extraView.frame = frame
186 | if cancelButton != nil {
187 | extraView.backgroundColor = cancelButton?.backgroudImageColorNormal?.rawValue
188 | } else {
189 | let bgColor = buttons.first?.backgroudImageColorNormal?.rawValue
190 | extraView.backgroundColor = bgColor
191 | }
192 | self.actionSheetView.addSubview(extraView)
193 | }
194 |
195 | /// Cancel Button
196 | private func setCancelButton() {
197 | /// 如果取消为ture则添加取消按钮
198 | if cancelButton != nil {
199 | let button = MMButton(type: .custom)
200 | button.frame = CGRect(x: 0, y: actionSheetView.bounds.size.height - Constants.mmbuttonHeight - Constants.paddng_bottom, width: Constants.mmscreenWidth, height: Constants.mmbuttonHeight)
201 | button.item = cancelButton
202 | button.addTarget(self, action: #selector(actionClick), for: .touchUpInside)
203 | actionSheetView.addSubview(button)
204 | }
205 | }
206 |
207 | private func updateTopCornerMask() {
208 | guard topCornerRadius > 0 else { return }
209 | let shape = CAShapeLayer()
210 | let path = UIBezierPath(roundedRect: actionSheetView.bounds, byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: topCornerRadius, height: topCornerRadius))
211 | shape.path = path.cgPath
212 | shape.frame = actionSheetView.bounds
213 | actionSheetView.layer.mask = shape
214 | }
215 |
216 | /// 修改样式
217 | override public func layoutSubviews() {
218 | super.layoutSubviews()
219 |
220 | /// 顶部圆角
221 | updateTopCornerMask()
222 | }
223 | }
224 |
225 | //MARK: Event
226 | extension MMActionSheet {
227 | /// items action
228 | @objc func actionClick(button: MMButton) {
229 | dismiss()
230 | guard let item = button.item else { return }
231 | /// Callback
232 | selectionClosure?(item)
233 | }
234 |
235 | //tap action
236 | @objc func singleTapDismiss() {
237 | dismiss()
238 | /// Callback
239 | selectionClosure?(nil)
240 | }
241 | }
242 |
243 | //MARK: present, dismiss
244 | extension MMActionSheet {
245 | /// 显示
246 | public func present() {
247 | if #available(iOS 13.0, *) {
248 | if let keyWindow = UIApplication.shared.windows.filter({ $0.isKeyWindow }).first {
249 | keyWindow.addSubview(self)
250 | }
251 | } else {
252 | UIApplication.shared.keyWindow?.addSubview(self)
253 | }
254 |
255 | UIView.animate(withDuration: 0.1, animations: { [self] in
256 | /// backgroundColor
257 | self.actionSheetView.backgroundColor = actionSheetViewBackgroundColor
258 | }) { (_: Bool) in
259 | UIView.animate(withDuration: self.duration!) {
260 | self.backgroundColor = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.3)
261 | self.actionSheetView.transform = CGAffineTransform(translationX: 0, y: -self.actionSheetView.frame.size.height)
262 | }
263 | }
264 | }
265 |
266 | /// 隐藏
267 | func dismiss() {
268 | UIView.animate(withDuration: duration!, animations: {
269 | self.backgroundColor = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.0)
270 | self.actionSheetView.transform = .identity
271 | }) { (_: Bool) in
272 | self.removeFromSuperview()
273 | }
274 | }
275 | }
276 |
277 |
278 | // MARK: - UIGestureRecognizerDelegate
279 | extension MMActionSheet: UIGestureRecognizerDelegate {
280 | public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
281 | guard touch.view == actionSheetView else { return true }
282 | return false
283 | }
284 | }
285 |
--------------------------------------------------------------------------------
/Sources/MMActionSheet/MMButton.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DDButton.swift
3 | // swiftui
4 | //
5 | // Created by 郭永红 on 2017/10/9.
6 | // Copyright © 2017年 keeponrunning. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class MMButton: UIButton {
12 | /// item
13 | public var item: MMButtonItem? {
14 | willSet { updateButton(newValue) }
15 | }
16 |
17 | override init(frame: CGRect) {
18 | super.init(frame: frame)
19 | }
20 |
21 | required init?(coder aDecoder: NSCoder) {
22 | fatalError("init(coder:) has not been implemented")
23 | }
24 |
25 | override func layoutSubviews() {
26 | super.layoutSubviews()
27 | }
28 |
29 | private func updateButton(_ item: MMButtonItem?) {
30 | guard let newItem = item else { return }
31 | /// Button Title
32 | setTitle(newItem.title, for: .normal)
33 | /// Button Title Color
34 | setTitleColor(newItem.titleColor?.rawValue, for: .normal)
35 | /// Button Title Font
36 | titleLabel?.font = item?.titleFont
37 | /// BackgroudImage Color
38 | let noramlColor = newItem.backgroudImageColorNormal?.rawValue ?? MMTools.DefaultColor.normalColor
39 | let highlightColor = newItem.backgroudImageColorHighlight?.rawValue ?? MMTools.DefaultColor.highlightColor
40 |
41 | setBackgroundImage(MMTools.imageWithColor(color: noramlColor, size: bounds.size), for: .normal)
42 | setBackgroundImage(MMTools.imageWithColor(color: highlightColor, size: bounds.size), for: .highlighted)
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Sources/MMActionSheet/MMButtonItem.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MMButtonItem.swift
3 | // swiftui
4 | //
5 | // Created by JefferDevs on 2021/9/13.
6 | // Copyright © 2021 keeponrunning. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public struct MMButtonItem {
12 | /// title
13 | public var title: String?
14 | /// titleColor
15 | public var titleColor: MMButtonTitleColor? = .default
16 | /// title font
17 | public var titleFont: UIFont? = .systemFont(ofSize: 16.0)
18 | /// MMButtonType
19 | public var buttonType: MMButtonType?
20 | /// BackgroudImageColor Normal
21 | public var backgroudImageColorNormal: MMButtonTitleColor? = .custom(MMTools.DefaultColor.normalColor)
22 | /// BackgroudImageColor Highlight
23 | public var backgroudImageColorHighlight: MMButtonTitleColor? = .custom(MMTools.DefaultColor.highlightColor)
24 |
25 | public init(title: String?,
26 | titleColor: MMButtonTitleColor? = .default,
27 | titleFont: UIFont? = .systemFont(ofSize: 16.0),
28 | buttonType: MMButtonType?,
29 | backgroudImageColorNormal: MMButtonTitleColor? = .custom(MMTools.DefaultColor.normalColor),
30 | backgroudImageColorHighlight: MMButtonTitleColor? = .custom(MMTools.DefaultColor.highlightColor)) {
31 | self.title = title
32 | self.titleColor = titleColor
33 | self.titleFont = titleFont
34 | self.buttonType = buttonType
35 | self.backgroudImageColorNormal = backgroudImageColorNormal
36 | self.backgroudImageColorHighlight = backgroudImageColorHighlight
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Sources/MMActionSheet/MMButtonTitleColor.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MMButtonTitleColor.swift
3 | // swiftui
4 | //
5 | // Created by JefferDevs on 2021/9/13.
6 | // Copyright © 2021 keeponrunning. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public enum MMButtonTitleColor {
12 | /// `default`
13 | case `default`
14 | /// blue
15 | case blue
16 | /// danger
17 | case danger
18 | /// custom
19 | case custom(UIColor)
20 | }
21 |
22 | extension MMButtonTitleColor: RawRepresentable {
23 | public typealias RawValue = UIColor
24 |
25 | public init?(rawValue: UIColor) {
26 | switch rawValue {
27 | case UIColor(red: 0.000, green: 0.000, blue: 0.004, alpha: 1.00): self = .default
28 | case UIColor(red: 0.082, green: 0.494, blue: 0.984, alpha: 1.00): self = .blue
29 | case UIColor.red: self = .danger
30 | case let color: self = .custom(color)
31 | }
32 | }
33 |
34 | public var rawValue: UIColor {
35 | switch self {
36 | case .default: return UIColor(red: 0.000, green: 0.000, blue: 0.004, alpha: 1.00)
37 | case .blue: return UIColor(red: 0.082, green: 0.494, blue: 0.984, alpha: 1.00)
38 | case .danger: return UIColor.red
39 | case let .custom(customColor): return customColor
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Sources/MMActionSheet/MMButtonType.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MMButtonType.swift
3 | // swiftui
4 | //
5 | // Created by JefferDevs on 2021/9/13.
6 | // Copyright © 2021 keeponrunning. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public enum MMButtonType {
12 | /// `default`
13 | case `default`(index: Int)
14 | /// cancel
15 | case cancel
16 | }
17 |
--------------------------------------------------------------------------------
/Sources/MMActionSheet/MMTitleItem.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MMTitleItem.swift
3 | // swiftui
4 | //
5 | // Created by JefferDevs on 2021/9/13.
6 | // Copyright © 2021 keeponrunning. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public struct MMTitleItem {
12 | /// text
13 | public var text: String?
14 | /// text color
15 | public var textColor: UIColor?
16 | /// textFont
17 | public var textFont: UIFont? = .systemFont(ofSize: 14.0)
18 | /// textAlignment
19 | public var textAlignment: NSTextAlignment? = .center
20 | /// backgroundColor
21 | public var backgroundColor: MMButtonTitleColor? = .custom(UIColor.clear)
22 |
23 | public init(title: String?,
24 | titleColor: UIColor? = MMButtonTitleColor.default.rawValue,
25 | titleFont: UIFont? = .systemFont(ofSize: 14.0),
26 | textAlignment: NSTextAlignment? = .center,
27 | backgroundColor: MMButtonTitleColor? = .custom(UIColor.clear)
28 | ) {
29 | self.text = title
30 | self.textColor = titleColor
31 | self.textFont = titleFont
32 | self.textAlignment = textAlignment
33 | self.backgroundColor = backgroundColor ?? .custom(UIColor.clear)
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Sources/MMActionSheet/MMTools.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MMTools.swift
3 | // swiftui
4 | //
5 | // Created by JefferDevs on 2021/9/13.
6 | // Copyright © 2021 keeponrunning. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public struct MMTools {
12 | /// Default
13 | public struct DefaultColor {
14 | public static let backgroundColor = UIColor(red: 0.937, green: 0.937, blue: 0.941, alpha: 0.90).withAlphaComponent(0.9)
15 | public static let normalColor = UIColor(red: 1.000, green: 1.000, blue: 1.000, alpha: 0.80)
16 | public static let highlightColor = UIColor(red: 0.780, green: 0.733, blue: 0.745, alpha: 0.80)
17 | }
18 |
19 | static var isIphoneX: Bool {
20 | if #available(iOS 11.0, *) {
21 | let keyWindow = UIApplication.shared.windows.filter { $0.isKeyWindow }.first
22 | return keyWindow?.safeAreaInsets.bottom ?? 0 > 0
23 | } else {
24 | // Fallback on earlier versions
25 | return false
26 | }
27 | }
28 |
29 | static func imageWithColor(color: UIColor, size: CGSize) -> UIImage {
30 | let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
31 | UIGraphicsBeginImageContext(rect.size)
32 | let context = UIGraphicsGetCurrentContext()
33 | context!.setFillColor(color.cgColor)
34 | context!.fill(rect)
35 | let image = UIGraphicsGetImageFromCurrentImageContext()
36 | UIGraphicsEndImageContext()
37 | return image!
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Tests/MMActionSheetTests/MMActionSheetTests.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 | @testable import MMActionSheet
3 |
4 | final class MMActionSheetTests: XCTestCase {
5 | func testExample() {
6 | // This is an example of a functional test case.
7 | // Use XCTAssert and related functions to verify your tests produce the correct
8 | // results.
9 | // XCTAssertEqual(MMActionSheet().text, "Hello, World!")
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/gifs/mmactionsheet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MinMao-Hub/MMActionSheet/0b104c72f6f30374df5127588be53f2a76d8c275/gifs/mmactionsheet.png
--------------------------------------------------------------------------------
/gifs/mmactionsheet_1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MinMao-Hub/MMActionSheet/0b104c72f6f30374df5127588be53f2a76d8c275/gifs/mmactionsheet_1.gif
--------------------------------------------------------------------------------
/gifs/mmactionsheet_2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MinMao-Hub/MMActionSheet/0b104c72f6f30374df5127588be53f2a76d8c275/gifs/mmactionsheet_2.gif
--------------------------------------------------------------------------------
/gifs/mmactionsheet_3.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MinMao-Hub/MMActionSheet/0b104c72f6f30374df5127588be53f2a76d8c275/gifs/mmactionsheet_3.gif
--------------------------------------------------------------------------------
/gifs/mmactionsheet_4.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MinMao-Hub/MMActionSheet/0b104c72f6f30374df5127588be53f2a76d8c275/gifs/mmactionsheet_4.gif
--------------------------------------------------------------------------------
/gifs/mmactionsheet_5.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MinMao-Hub/MMActionSheet/0b104c72f6f30374df5127588be53f2a76d8c275/gifs/mmactionsheet_5.gif
--------------------------------------------------------------------------------
/gifs/mmactionsheet_6.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MinMao-Hub/MMActionSheet/0b104c72f6f30374df5127588be53f2a76d8c275/gifs/mmactionsheet_6.gif
--------------------------------------------------------------------------------
/gifs/mmactionsheet_7.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MinMao-Hub/MMActionSheet/0b104c72f6f30374df5127588be53f2a76d8c275/gifs/mmactionsheet_7.gif
--------------------------------------------------------------------------------
/gifs/mmactionsheet_8.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MinMao-Hub/MMActionSheet/0b104c72f6f30374df5127588be53f2a76d8c275/gifs/mmactionsheet_8.gif
--------------------------------------------------------------------------------
/swiftui.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 195CE25F26F8809B0025DD83 /* MMButtonTitleColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 195CE25826F8809B0025DD83 /* MMButtonTitleColor.swift */; };
11 | 195CE26026F8809B0025DD83 /* MMButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 195CE25926F8809B0025DD83 /* MMButton.swift */; };
12 | 195CE26126F8809B0025DD83 /* MMButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 195CE25A26F8809B0025DD83 /* MMButtonItem.swift */; };
13 | 195CE26226F8809B0025DD83 /* MMButtonType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 195CE25B26F8809B0025DD83 /* MMButtonType.swift */; };
14 | 195CE26326F8809B0025DD83 /* MMTools.swift in Sources */ = {isa = PBXBuildFile; fileRef = 195CE25C26F8809B0025DD83 /* MMTools.swift */; };
15 | 195CE26426F8809B0025DD83 /* MMActionSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 195CE25D26F8809B0025DD83 /* MMActionSheet.swift */; };
16 | 195CE26526F8809B0025DD83 /* MMTitleItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 195CE25E26F8809B0025DD83 /* MMTitleItem.swift */; };
17 | 1986B1601F8C3F2B00CBC6AE /* Example.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1986B15F1F8C3F2B00CBC6AE /* Example.storyboard */; };
18 | 19A84DF81F8AF08400475BEB /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A84DF71F8AF08400475BEB /* AppDelegate.swift */; };
19 | 19A84DFF1F8AF08400475BEB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 19A84DFE1F8AF08400475BEB /* Assets.xcassets */; };
20 | 19A84E021F8AF08400475BEB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 19A84E001F8AF08400475BEB /* LaunchScreen.storyboard */; };
21 | 19C6410E1F8B5B1C005C0E3B /* ExampleActionSheetVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19C6410D1F8B5B1C005C0E3B /* ExampleActionSheetVC.swift */; };
22 | /* End PBXBuildFile section */
23 |
24 | /* Begin PBXFileReference section */
25 | 195CE25826F8809B0025DD83 /* MMButtonTitleColor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MMButtonTitleColor.swift; sourceTree = ""; };
26 | 195CE25926F8809B0025DD83 /* MMButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MMButton.swift; sourceTree = ""; };
27 | 195CE25A26F8809B0025DD83 /* MMButtonItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MMButtonItem.swift; sourceTree = ""; };
28 | 195CE25B26F8809B0025DD83 /* MMButtonType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MMButtonType.swift; sourceTree = ""; };
29 | 195CE25C26F8809B0025DD83 /* MMTools.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MMTools.swift; sourceTree = ""; };
30 | 195CE25D26F8809B0025DD83 /* MMActionSheet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MMActionSheet.swift; sourceTree = ""; };
31 | 195CE25E26F8809B0025DD83 /* MMTitleItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MMTitleItem.swift; sourceTree = ""; };
32 | 1986B15F1F8C3F2B00CBC6AE /* Example.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Example.storyboard; sourceTree = ""; };
33 | 19A84DF41F8AF08400475BEB /* swiftui.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = swiftui.app; sourceTree = BUILT_PRODUCTS_DIR; };
34 | 19A84DF71F8AF08400475BEB /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
35 | 19A84DFE1F8AF08400475BEB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
36 | 19A84E011F8AF08400475BEB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
37 | 19A84E031F8AF08400475BEB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
38 | 19C6410D1F8B5B1C005C0E3B /* ExampleActionSheetVC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExampleActionSheetVC.swift; sourceTree = ""; };
39 | /* End PBXFileReference section */
40 |
41 | /* Begin PBXFrameworksBuildPhase section */
42 | 19A84DF11F8AF08400475BEB /* Frameworks */ = {
43 | isa = PBXFrameworksBuildPhase;
44 | buildActionMask = 2147483647;
45 | files = (
46 | );
47 | runOnlyForDeploymentPostprocessing = 0;
48 | };
49 | /* End PBXFrameworksBuildPhase section */
50 |
51 | /* Begin PBXGroup section */
52 | 1900C6BC1F8B0E5000DD81B5 /* Example */ = {
53 | isa = PBXGroup;
54 | children = (
55 | 19C6410D1F8B5B1C005C0E3B /* ExampleActionSheetVC.swift */,
56 | 1986B15F1F8C3F2B00CBC6AE /* Example.storyboard */,
57 | );
58 | path = Example;
59 | sourceTree = "";
60 | };
61 | 195CE25626F8809B0025DD83 /* Sources */ = {
62 | isa = PBXGroup;
63 | children = (
64 | 195CE25726F8809B0025DD83 /* MMActionSheet */,
65 | );
66 | path = Sources;
67 | sourceTree = "";
68 | };
69 | 195CE25726F8809B0025DD83 /* MMActionSheet */ = {
70 | isa = PBXGroup;
71 | children = (
72 | 195CE25826F8809B0025DD83 /* MMButtonTitleColor.swift */,
73 | 195CE25926F8809B0025DD83 /* MMButton.swift */,
74 | 195CE25A26F8809B0025DD83 /* MMButtonItem.swift */,
75 | 195CE25B26F8809B0025DD83 /* MMButtonType.swift */,
76 | 195CE25C26F8809B0025DD83 /* MMTools.swift */,
77 | 195CE25D26F8809B0025DD83 /* MMActionSheet.swift */,
78 | 195CE25E26F8809B0025DD83 /* MMTitleItem.swift */,
79 | );
80 | path = MMActionSheet;
81 | sourceTree = "";
82 | };
83 | 19A84DEB1F8AF08400475BEB = {
84 | isa = PBXGroup;
85 | children = (
86 | 1900C6BC1F8B0E5000DD81B5 /* Example */,
87 | 195CE25626F8809B0025DD83 /* Sources */,
88 | 19A84DF61F8AF08400475BEB /* swiftui */,
89 | 19A84DF51F8AF08400475BEB /* Products */,
90 | );
91 | sourceTree = "";
92 | };
93 | 19A84DF51F8AF08400475BEB /* Products */ = {
94 | isa = PBXGroup;
95 | children = (
96 | 19A84DF41F8AF08400475BEB /* swiftui.app */,
97 | );
98 | name = Products;
99 | sourceTree = "";
100 | };
101 | 19A84DF61F8AF08400475BEB /* swiftui */ = {
102 | isa = PBXGroup;
103 | children = (
104 | 19A84DF71F8AF08400475BEB /* AppDelegate.swift */,
105 | 19A84DFE1F8AF08400475BEB /* Assets.xcassets */,
106 | 19A84E001F8AF08400475BEB /* LaunchScreen.storyboard */,
107 | 19A84E031F8AF08400475BEB /* Info.plist */,
108 | );
109 | path = swiftui;
110 | sourceTree = "";
111 | };
112 | /* End PBXGroup section */
113 |
114 | /* Begin PBXNativeTarget section */
115 | 19A84DF31F8AF08400475BEB /* swiftui */ = {
116 | isa = PBXNativeTarget;
117 | buildConfigurationList = 19A84E061F8AF08400475BEB /* Build configuration list for PBXNativeTarget "swiftui" */;
118 | buildPhases = (
119 | 19A84DF01F8AF08400475BEB /* Sources */,
120 | 19A84DF11F8AF08400475BEB /* Frameworks */,
121 | 19A84DF21F8AF08400475BEB /* Resources */,
122 | );
123 | buildRules = (
124 | );
125 | dependencies = (
126 | );
127 | name = swiftui;
128 | productName = swiftui;
129 | productReference = 19A84DF41F8AF08400475BEB /* swiftui.app */;
130 | productType = "com.apple.product-type.application";
131 | };
132 | /* End PBXNativeTarget section */
133 |
134 | /* Begin PBXProject section */
135 | 19A84DEC1F8AF08400475BEB /* Project object */ = {
136 | isa = PBXProject;
137 | attributes = {
138 | LastSwiftUpdateCheck = 0830;
139 | LastUpgradeCheck = 0900;
140 | ORGANIZATIONNAME = keeponrunning;
141 | TargetAttributes = {
142 | 19A84DF31F8AF08400475BEB = {
143 | CreatedOnToolsVersion = 8.3.3;
144 | LastSwiftMigration = 0900;
145 | ProvisioningStyle = Automatic;
146 | };
147 | };
148 | };
149 | buildConfigurationList = 19A84DEF1F8AF08400475BEB /* Build configuration list for PBXProject "swiftui" */;
150 | compatibilityVersion = "Xcode 3.2";
151 | developmentRegion = English;
152 | hasScannedForEncodings = 0;
153 | knownRegions = (
154 | English,
155 | en,
156 | Base,
157 | );
158 | mainGroup = 19A84DEB1F8AF08400475BEB;
159 | productRefGroup = 19A84DF51F8AF08400475BEB /* Products */;
160 | projectDirPath = "";
161 | projectRoot = "";
162 | targets = (
163 | 19A84DF31F8AF08400475BEB /* swiftui */,
164 | );
165 | };
166 | /* End PBXProject section */
167 |
168 | /* Begin PBXResourcesBuildPhase section */
169 | 19A84DF21F8AF08400475BEB /* Resources */ = {
170 | isa = PBXResourcesBuildPhase;
171 | buildActionMask = 2147483647;
172 | files = (
173 | 19A84E021F8AF08400475BEB /* LaunchScreen.storyboard in Resources */,
174 | 19A84DFF1F8AF08400475BEB /* Assets.xcassets in Resources */,
175 | 1986B1601F8C3F2B00CBC6AE /* Example.storyboard in Resources */,
176 | );
177 | runOnlyForDeploymentPostprocessing = 0;
178 | };
179 | /* End PBXResourcesBuildPhase section */
180 |
181 | /* Begin PBXSourcesBuildPhase section */
182 | 19A84DF01F8AF08400475BEB /* Sources */ = {
183 | isa = PBXSourcesBuildPhase;
184 | buildActionMask = 2147483647;
185 | files = (
186 | 195CE26026F8809B0025DD83 /* MMButton.swift in Sources */,
187 | 195CE26226F8809B0025DD83 /* MMButtonType.swift in Sources */,
188 | 19C6410E1F8B5B1C005C0E3B /* ExampleActionSheetVC.swift in Sources */,
189 | 195CE25F26F8809B0025DD83 /* MMButtonTitleColor.swift in Sources */,
190 | 195CE26526F8809B0025DD83 /* MMTitleItem.swift in Sources */,
191 | 195CE26326F8809B0025DD83 /* MMTools.swift in Sources */,
192 | 19A84DF81F8AF08400475BEB /* AppDelegate.swift in Sources */,
193 | 195CE26426F8809B0025DD83 /* MMActionSheet.swift in Sources */,
194 | 195CE26126F8809B0025DD83 /* MMButtonItem.swift in Sources */,
195 | );
196 | runOnlyForDeploymentPostprocessing = 0;
197 | };
198 | /* End PBXSourcesBuildPhase section */
199 |
200 | /* Begin PBXVariantGroup section */
201 | 19A84E001F8AF08400475BEB /* LaunchScreen.storyboard */ = {
202 | isa = PBXVariantGroup;
203 | children = (
204 | 19A84E011F8AF08400475BEB /* Base */,
205 | );
206 | name = LaunchScreen.storyboard;
207 | sourceTree = "";
208 | };
209 | /* End PBXVariantGroup section */
210 |
211 | /* Begin XCBuildConfiguration section */
212 | 19A84E041F8AF08400475BEB /* Debug */ = {
213 | isa = XCBuildConfiguration;
214 | buildSettings = {
215 | ALWAYS_SEARCH_USER_PATHS = NO;
216 | CLANG_ANALYZER_NONNULL = YES;
217 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
218 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
219 | CLANG_CXX_LIBRARY = "libc++";
220 | CLANG_ENABLE_MODULES = YES;
221 | CLANG_ENABLE_OBJC_ARC = YES;
222 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
223 | CLANG_WARN_BOOL_CONVERSION = YES;
224 | CLANG_WARN_COMMA = YES;
225 | CLANG_WARN_CONSTANT_CONVERSION = YES;
226 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
227 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
228 | CLANG_WARN_EMPTY_BODY = YES;
229 | CLANG_WARN_ENUM_CONVERSION = YES;
230 | CLANG_WARN_INFINITE_RECURSION = YES;
231 | CLANG_WARN_INT_CONVERSION = YES;
232 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
233 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
234 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
235 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
236 | CLANG_WARN_STRICT_PROTOTYPES = YES;
237 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
238 | CLANG_WARN_UNREACHABLE_CODE = YES;
239 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
240 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
241 | COPY_PHASE_STRIP = NO;
242 | DEBUG_INFORMATION_FORMAT = dwarf;
243 | ENABLE_STRICT_OBJC_MSGSEND = YES;
244 | ENABLE_TESTABILITY = YES;
245 | GCC_C_LANGUAGE_STANDARD = gnu99;
246 | GCC_DYNAMIC_NO_PIC = NO;
247 | GCC_NO_COMMON_BLOCKS = YES;
248 | GCC_OPTIMIZATION_LEVEL = 0;
249 | GCC_PREPROCESSOR_DEFINITIONS = (
250 | "DEBUG=1",
251 | "$(inherited)",
252 | );
253 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
254 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
255 | GCC_WARN_UNDECLARED_SELECTOR = YES;
256 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
257 | GCC_WARN_UNUSED_FUNCTION = YES;
258 | GCC_WARN_UNUSED_VARIABLE = YES;
259 | IPHONEOS_DEPLOYMENT_TARGET = 10.3;
260 | MTL_ENABLE_DEBUG_INFO = YES;
261 | ONLY_ACTIVE_ARCH = YES;
262 | SDKROOT = iphoneos;
263 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
264 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
265 | TARGETED_DEVICE_FAMILY = "1,2";
266 | };
267 | name = Debug;
268 | };
269 | 19A84E051F8AF08400475BEB /* Release */ = {
270 | isa = XCBuildConfiguration;
271 | buildSettings = {
272 | ALWAYS_SEARCH_USER_PATHS = NO;
273 | CLANG_ANALYZER_NONNULL = YES;
274 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
275 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
276 | CLANG_CXX_LIBRARY = "libc++";
277 | CLANG_ENABLE_MODULES = YES;
278 | CLANG_ENABLE_OBJC_ARC = YES;
279 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
280 | CLANG_WARN_BOOL_CONVERSION = YES;
281 | CLANG_WARN_COMMA = YES;
282 | CLANG_WARN_CONSTANT_CONVERSION = YES;
283 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
284 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
285 | CLANG_WARN_EMPTY_BODY = YES;
286 | CLANG_WARN_ENUM_CONVERSION = YES;
287 | CLANG_WARN_INFINITE_RECURSION = YES;
288 | CLANG_WARN_INT_CONVERSION = YES;
289 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
290 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
291 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
292 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
293 | CLANG_WARN_STRICT_PROTOTYPES = YES;
294 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
295 | CLANG_WARN_UNREACHABLE_CODE = YES;
296 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
297 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
298 | COPY_PHASE_STRIP = NO;
299 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
300 | ENABLE_NS_ASSERTIONS = NO;
301 | ENABLE_STRICT_OBJC_MSGSEND = YES;
302 | GCC_C_LANGUAGE_STANDARD = gnu99;
303 | GCC_NO_COMMON_BLOCKS = YES;
304 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
305 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
306 | GCC_WARN_UNDECLARED_SELECTOR = YES;
307 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
308 | GCC_WARN_UNUSED_FUNCTION = YES;
309 | GCC_WARN_UNUSED_VARIABLE = YES;
310 | IPHONEOS_DEPLOYMENT_TARGET = 10.3;
311 | MTL_ENABLE_DEBUG_INFO = NO;
312 | SDKROOT = iphoneos;
313 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
314 | TARGETED_DEVICE_FAMILY = "1,2";
315 | VALIDATE_PRODUCT = YES;
316 | };
317 | name = Release;
318 | };
319 | 19A84E071F8AF08400475BEB /* Debug */ = {
320 | isa = XCBuildConfiguration;
321 | buildSettings = {
322 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
323 | CODE_SIGN_IDENTITY = "Apple Development";
324 | CODE_SIGN_STYLE = Automatic;
325 | DEVELOPMENT_TEAM = "";
326 | INFOPLIST_FILE = swiftui/Info.plist;
327 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
328 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
329 | PRODUCT_BUNDLE_IDENTIFIER = com.keeponrunning.swiftui;
330 | PRODUCT_NAME = "$(TARGET_NAME)";
331 | PROVISIONING_PROFILE_SPECIFIER = "";
332 | SWIFT_SWIFT3_OBJC_INFERENCE = Default;
333 | SWIFT_VERSION = 4.0;
334 | };
335 | name = Debug;
336 | };
337 | 19A84E081F8AF08400475BEB /* Release */ = {
338 | isa = XCBuildConfiguration;
339 | buildSettings = {
340 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
341 | CODE_SIGN_IDENTITY = "Apple Development";
342 | CODE_SIGN_STYLE = Automatic;
343 | DEVELOPMENT_TEAM = "";
344 | INFOPLIST_FILE = swiftui/Info.plist;
345 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
346 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
347 | PRODUCT_BUNDLE_IDENTIFIER = com.keeponrunning.swiftui;
348 | PRODUCT_NAME = "$(TARGET_NAME)";
349 | PROVISIONING_PROFILE_SPECIFIER = "";
350 | SWIFT_SWIFT3_OBJC_INFERENCE = Default;
351 | SWIFT_VERSION = 4.0;
352 | };
353 | name = Release;
354 | };
355 | /* End XCBuildConfiguration section */
356 |
357 | /* Begin XCConfigurationList section */
358 | 19A84DEF1F8AF08400475BEB /* Build configuration list for PBXProject "swiftui" */ = {
359 | isa = XCConfigurationList;
360 | buildConfigurations = (
361 | 19A84E041F8AF08400475BEB /* Debug */,
362 | 19A84E051F8AF08400475BEB /* Release */,
363 | );
364 | defaultConfigurationIsVisible = 0;
365 | defaultConfigurationName = Release;
366 | };
367 | 19A84E061F8AF08400475BEB /* Build configuration list for PBXNativeTarget "swiftui" */ = {
368 | isa = XCConfigurationList;
369 | buildConfigurations = (
370 | 19A84E071F8AF08400475BEB /* Debug */,
371 | 19A84E081F8AF08400475BEB /* Release */,
372 | );
373 | defaultConfigurationIsVisible = 0;
374 | defaultConfigurationName = Release;
375 | };
376 | /* End XCConfigurationList section */
377 | };
378 | rootObject = 19A84DEC1F8AF08400475BEB /* Project object */;
379 | }
380 |
--------------------------------------------------------------------------------
/swiftui.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/swiftui/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // swiftui
4 | //
5 | // Created by 郭永红 on 2017/10/9.
6 | // Copyright © 2017年 keeponrunning. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(_ application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(_ application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(_ application: UIApplication) {
33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(_ application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(_ application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/swiftui/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/swiftui/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | MarkerFelt-Wide
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/swiftui/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Example
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 |
--------------------------------------------------------------------------------