├── Tests
├── CheckCocoaPodsQualityIndexes.rb
├── LinuxMain.swift
└── BottomSheetTests
│ ├── XCTestManifests.swift
│ └── BottomSheetTests.swift
├── Asset
├── demo1.gif
├── demo2.gif
└── logo.png
├── iOS Example
├── Sources
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── SceneDelegate.swift
│ ├── AppDelegate.swift
│ ├── Base.lproj
│ │ └── LaunchScreen.storyboard
│ ├── ContentView.swift
│ ├── Info.plist
│ └── MapSettingView.swift
├── iOS Example.xcodeproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── project.pbxproj
└── iOS Example.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ └── IDEWorkspaceChecks.plist
├── CHANGELOG.md
├── BottomSheet.podspec
├── .travis.yml
├── Package.swift
├── Sources
└── BottomSheet
│ ├── RoundedCorner.swift
│ ├── ViewExtension.swift
│ └── BottomSheet.swift
├── LICENSE
├── CONTRIBUTING.md
├── README.md
└── .gitignore
/Tests/CheckCocoaPodsQualityIndexes.rb:
--------------------------------------------------------------------------------
1 | 404: Not Found
2 |
--------------------------------------------------------------------------------
/Asset/demo1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weitieda/bottom-sheet/HEAD/Asset/demo1.gif
--------------------------------------------------------------------------------
/Asset/demo2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weitieda/bottom-sheet/HEAD/Asset/demo2.gif
--------------------------------------------------------------------------------
/Asset/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weitieda/bottom-sheet/HEAD/Asset/logo.png
--------------------------------------------------------------------------------
/iOS Example/Sources/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Tests/LinuxMain.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 |
3 | import BottomSheetTests
4 |
5 | var tests = [XCTestCaseEntry]()
6 | tests += BottomSheetTests.allTests()
7 | XCTMain(tests)
8 |
--------------------------------------------------------------------------------
/Tests/BottomSheetTests/XCTestManifests.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 |
3 | #if !canImport(ObjectiveC)
4 | public func allTests() -> [XCTestCaseEntry] {
5 | return [
6 | testCase(BottomSheetTests.allTests),
7 | ]
8 | }
9 | #endif
10 |
--------------------------------------------------------------------------------
/iOS Example/iOS Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/iOS Example/iOS Example.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/iOS Example/iOS Example.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 | All notable changes to this project will be documented in this file.
3 | BottomSheet adheres to [Semantic Versioning](http://semver.org/).
4 |
5 | ## [Master](https://github.com/weitieda/BottomSheet)
6 | ### Added
7 |
8 | ### Changed
9 |
10 | Fix half-opened bottom sheet when returning from background.
11 |
12 | - 1.0.6
13 |
14 | Removing List padding on examples.
15 |
16 | ### Removed
17 |
--------------------------------------------------------------------------------
/Tests/BottomSheetTests/BottomSheetTests.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 | @testable import BottomSheet
3 |
4 | final class BottomSheetTests: 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 | }
10 |
11 | static var allTests = [
12 | ("testExample", testExample),
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/BottomSheet.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |spec|
2 |
3 | spec.name = "BottomSheet"
4 | spec.version = "1.0.6"
5 | spec.summary = "⬆️ A SwiftUI view component sliding in from bottom"
6 | spec.homepage = "http://www.github.com/weitieda/bottom-sheet"
7 | spec.license = { :type => "MIT", :file => "LICENSE" }
8 | spec.author = { "Tieda Wei" => "hi@tiedawei.com" }
9 | spec.platform = :ios, "13.0"
10 | spec.source = { :git => "https://github.com/weitieda/bottom-sheet.git", :tag => spec.version.to_s }
11 | spec.source_files = "Sources/BottomSheet/*.{swift}"
12 | spec.swift_versions = '5.0'
13 | end
14 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | os: osx
2 | osx_image: xcode11.1
3 | env:
4 | global:
5 | - WORKSPACE="./iOS Example/iOS Example.xcworkspace"
6 | - IOS_FRAMEWORK_SCHEME="iOS Example"
7 | - EXAMPLE_SCHEME="iOS Example"
8 | matrix:
9 | - DESTINATION="OS=13.1,name=iPhone 11"
10 | SCHEME="$IOS_FRAMEWORK_SCHEME"
11 | script:
12 | - set -o pipefail
13 | - xcodebuild -version
14 | - xcodebuild -showsdks
15 | - xcodebuild -list
16 | - xcodebuild -workspace "$WORKSPACE" -list
17 |
18 | # Build Example in Debug
19 | - xcodebuild -workspace "$WORKSPACE" -scheme "$EXAMPLE_SCHEME" -destination "$DESTINATION" -configuration Debug ONLY_ACTIVE_ARCH=NO build | xcpretty -c
20 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.1
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: "BottomSheet",
8 | platforms: [
9 | .iOS(.v13)
10 | ],
11 | products: [
12 | .library(
13 | name: "BottomSheet",
14 | targets: ["BottomSheet"]),
15 | ],
16 | dependencies: [],
17 | targets: [
18 | .target(
19 | name: "BottomSheet",
20 | dependencies: []),
21 | .testTarget(
22 | name: "BottomSheetTests",
23 | dependencies: ["BottomSheet"]),
24 | ]
25 | )
26 |
--------------------------------------------------------------------------------
/Sources/BottomSheet/RoundedCorner.swift:
--------------------------------------------------------------------------------
1 | //
2 | // RoundedCorner.swift
3 | // BottomSheet
4 | //
5 | // Created by Tieda Wei on 2020-04-25.
6 | // Copyright © 2020 Tieda Wei. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | #if !os(macOS)
12 | extension View {
13 | func cornerRadius(_ radius: CGFloat, corners: UIRectCorner) -> some View {
14 | clipShape(RoundedCorner(radius: radius, corners: corners))
15 | }
16 | }
17 |
18 | struct RoundedCorner: Shape {
19 | var radius: CGFloat = .infinity
20 | var corners: UIRectCorner = .allCorners
21 |
22 | func path(in rect: CGRect) -> Path {
23 | let path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
24 | return Path(path.cgPath)
25 | }
26 | }
27 | #endif
28 |
--------------------------------------------------------------------------------
/iOS Example/Sources/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // iOS Example
4 | //
5 | // Created by Tieda Wei on Apr 26, 2020.
6 | // Copyright © 2020 Tieda Wei. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import SwiftUI
11 |
12 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
13 |
14 | var window: UIWindow?
15 |
16 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
17 |
18 | let contentView = ContentView()
19 |
20 | if let windowScene = scene as? UIWindowScene {
21 | let window = UIWindow(windowScene: windowScene)
22 | window.rootViewController = UIHostingController(rootView: contentView)
23 | self.window = window
24 | window.makeKeyAndVisible()
25 | }
26 | }
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2020 Tieda Wei
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
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all 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.
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | All contributors are welcome. Please use issues and pull requests to contribute to the project. And update [CHANGELOG.md](CHANGELOG.md) when committing.
4 |
5 | ## Making a change
6 |
7 | When you commit a change, please add a note to [CHANGELOG.md](CHANGELOG.md).
8 |
9 | ## Release process
10 |
11 | 1. Confirm the build is [passing in travis](https://travis-ci.org/weitieda/BottomSheet)
12 | 1. This automatically checks the Podfile is building
13 | 2. Push a release commit
14 | 1. Create a new Master section at the top
15 | 2. Rename the old Master section like:
16 | ## [1.0.5](https://github.com/weitieda/BottomSheet/releases/tag/1.0.5)
17 | Released on 2019-10-15.
18 | 3. Update the Podspec version number
19 | 3. Create a GitHub release
20 | 1. Tag the release (like `1.0.5`)
21 | 2. Paste notes from [CHANGELOG.md](CHANGELOG.md)
22 | 3. Push the Podspec to CocoaPods
23 | 1. `pod trunk push`
24 | 4. Create Carthage binaries
25 | 1. `carthage build --no-skip-current`
26 | 2. `carthage archive __PROJECT_NAME__`
27 | 3. Add to the GitHub release
28 |
--------------------------------------------------------------------------------
/iOS Example/Sources/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // iOS Example
4 | //
5 | // Created by Tieda Wei on Apr 26, 2020.
6 | // Copyright © 2020 Tieda Wei. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
30 | // Called when the user discards a scene session.
31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/iOS Example/Sources/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 |
--------------------------------------------------------------------------------
/iOS Example/Sources/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // iOS Example
4 | //
5 | // Created by Tieda Wei on 2020-04-26.
6 | // Copyright © 2020 Tieda Wei. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 | import BottomSheet
11 |
12 | struct ContentView: View {
13 | @State var showList = false
14 | @State var showMapSetting = true
15 |
16 | var body: some View {
17 | NavigationView {
18 | List(0..<20) {
19 | Text("\($0)")
20 | }.listStyle(PlainListStyle())
21 | .bottomSheet(isPresented: $showList, height: 500) {
22 | List(20..<40) { Text("\($0)") }.listStyle(PlainListStyle())
23 | }
24 | .bottomSheet(
25 | isPresented: $showMapSetting,
26 | height: 370,
27 | topBarHeight: 16,
28 | topBarCornerRadius: 16,
29 | showTopIndicator: false
30 | ) {
31 | MapSettingView{ self.showMapSetting = false }
32 | }
33 | .navigationBarTitle("Bottom Sheet")
34 | .navigationBarItems(
35 | leading: Button(action: { self.showMapSetting = true }) { Text("Setting") },
36 | trailing: Button(action: { self.showList = true }) { Text("List") }
37 | )
38 | }
39 | }
40 | }
41 |
42 | struct ContentView_Previews: PreviewProvider {
43 | static var previews: some View {
44 | Group {
45 | ContentView()
46 | .previewDevice(PreviewDevice(rawValue: "iPhone 8"))
47 |
48 | ContentView()
49 | .previewDevice(PreviewDevice(rawValue: "iPhone XS Max"))
50 | .environment(\.colorScheme, .dark)
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | 
4 | [](LICENSE)
5 |
6 | 
7 | 
8 |
9 | ## Usage
10 |
11 | Same way as you use `Sheet` in `SwiftUI`
12 |
13 | ```swift
14 | NavigationView {
15 | List(0..<20) {
16 | Text("\($0)")
17 | }.listStyle(PlainListStyle())
18 | .bottomSheet(isPresented: $isPresented, height: 300) {
19 | List(20..<40) { Text("\($0)") }.listStyle(PlainListStyle())
20 | }
21 | .navigationBarTitle("Bottom Sheet")
22 | .navigationBarItems(
23 | trailing: Button(action: { self.isPresented = true }) {
24 | Text("Show")
25 | }
26 | )
27 | }
28 | ```
29 |
30 | ## Example
31 |
32 | > Both demo preview code are available in example project.
33 |
34 | To run the example project, clone this repo, and open iOS Example.xcworkspace from the iOS Example directory.
35 |
36 | ## Installation
37 |
38 | >📱 iOS 13.0+
39 |
40 | #### Swift Package Manager
41 | To install `BottomSheet` using [Swift Package Manager](https://swift.org/package-manager/), add
42 | `.package(name: "BottomSheet", url: "https://github.com/weitieda/bottom-sheet", from: "1.0.0"),"` to your Package.swift, then follow the integration tutorial [here](https://swift.org/package-manager#importing-dependencies).
43 |
44 | #### CocoaPods
45 | To install `BottomSheet` using [CocoaPods](http://cocoapods.org), add
46 | `pod 'BottomSheet', :git => 'https://github.com/weitieda/bottom-sheet.git'` to your Podfile, then follow the integration tutorial [here](https://guides.cocoapods.org/using/using-cocoapods.html).
47 |
48 | ## License
49 |
50 | BottomSheet is available under the MIT license. See [the LICENSE file](LICENSE) for more information.
51 |
--------------------------------------------------------------------------------
/iOS Example/Sources/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 | }
--------------------------------------------------------------------------------
/iOS Example/Sources/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 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | $(PRODUCT_MODULE_NAME).SceneDelegate
36 |
37 |
38 |
39 |
40 | UILaunchStoryboardName
41 | LaunchScreen
42 | UIRequiredDeviceCapabilities
43 |
44 | armv7
45 |
46 | UISupportedInterfaceOrientations
47 |
48 | UIInterfaceOrientationPortrait
49 | UIInterfaceOrientationLandscapeLeft
50 | UIInterfaceOrientationLandscapeRight
51 |
52 | UISupportedInterfaceOrientations~ipad
53 |
54 | UIInterfaceOrientationPortrait
55 | UIInterfaceOrientationPortraitUpsideDown
56 | UIInterfaceOrientationLandscapeLeft
57 | UIInterfaceOrientationLandscapeRight
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## User settings
6 | xcuserdata/
7 |
8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
9 | *.xcscmblueprint
10 | *.xccheckout
11 |
12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
13 | build/
14 | DerivedData/
15 | *.moved-aside
16 | *.pbxuser
17 | !default.pbxuser
18 | *.mode1v3
19 | !default.mode1v3
20 | *.mode2v3
21 | !default.mode2v3
22 | *.perspectivev3
23 | !default.perspectivev3
24 |
25 | ## Obj-C/Swift specific
26 | *.hmap
27 |
28 | ## App packaging
29 | *.ipa
30 | *.dSYM.zip
31 | *.dSYM
32 |
33 | ## Playgrounds
34 | timeline.xctimeline
35 | playground.xcworkspace
36 |
37 | # Swift Package Manager
38 | #
39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
40 | # Packages/
41 | # Package.pins
42 | # Package.resolved
43 | # *.xcodeproj
44 | #
45 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
46 | # hence it is not needed unless you have added a package configuration file to your project
47 | .swiftpm
48 |
49 | .build/
50 |
51 | # CocoaPods
52 | #
53 | # We recommend against adding the Pods directory to your .gitignore. However
54 | # you should judge for yourself, the pros and cons are mentioned at:
55 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
56 | #
57 | # Pods/
58 | #
59 | # Add this line if you want to avoid checking in source code from the Xcode workspace
60 | # *.xcworkspace
61 |
62 | # Carthage
63 | #
64 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
65 | # Carthage/Checkouts
66 |
67 | Carthage/Build/
68 |
69 | # Accio dependency management
70 | Dependencies/
71 | .accio/
72 |
73 | # fastlane
74 | #
75 | # It is recommended to not store the screenshots in the git repo.
76 | # Instead, use fastlane to re-generate the screenshots whenever they are needed.
77 | # For more information about the recommended setup visit:
78 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
79 |
80 | fastlane/report.xml
81 | fastlane/Preview.html
82 | fastlane/screenshots/**/*.png
83 | fastlane/test_output
84 |
85 | # Code Injection
86 | #
87 | # After new code Injection tools there's a generated folder /iOSInjectionProject
88 | # https://github.com/johnno1962/injectionforxcode
89 |
90 | iOSInjectionProject/
91 | BottomSheet.framework.zip
92 |
93 | **/.DS_Store
--------------------------------------------------------------------------------
/iOS Example/Sources/MapSettingView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MapSettingView.swift
3 | // iOS Example
4 | //
5 | // Created by tieda on 2020-09-20.
6 | // Copyright © 2020 Tieda Wei. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | struct MapSettingView: View {
12 | let dismiss: () -> Void
13 |
14 | var body: some View {
15 | VStack(alignment: .leading) {
16 | HStack {
17 | Text("Map Settings").font(.title).bold()
18 | Spacer()
19 | Image(systemName: "xmark.circle.fill")
20 | .foregroundColor(.gray)
21 | .font(.system(size: 26))
22 | .onTapGesture { dismiss() }
23 | }.padding(.horizontal)
24 | Picker(selection: .constant(0), label: Text("")) {
25 | Text("Map").tag(0)
26 | Text("Transit").tag(1)
27 | Text("Satellite").tag(2)
28 | }
29 | .pickerStyle(SegmentedPickerStyle())
30 | .padding(.horizontal)
31 | Divider()
32 | Toggle(isOn: .constant(true)) {
33 | Text("Traffic").font(.body)
34 | }.padding(.horizontal)
35 | Rectangle().frame(height: 8).foregroundColor(Color(UIColor.systemGray5))
36 | VStack {
37 | HStack {
38 | Button(action: { }) {
39 | Text("Mark My Location").font(.system(size: 16))
40 | }
41 | Spacer()
42 | }
43 | Divider()
44 | HStack {
45 | Button(action: { }) {
46 | Text("Add a Missing Place").font(.system(size: 16))
47 | }
48 | Spacer()
49 | }
50 | Divider()
51 | HStack {
52 | Button(action: { }) {
53 | Text("Report an Issue").font(.system(size: 16))
54 | }
55 | Spacer()
56 | }
57 | }.padding(.horizontal)
58 | Rectangle().frame(height: 8).foregroundColor(Color(UIColor.systemGray5))
59 | VStack(alignment: .leading) {
60 | Text("TomTom").font(.system(size: 14)).bold()
61 | Text("© OpenStreetMap and other data providers").font(.caption)
62 | }.padding(.horizontal)
63 | Spacer()
64 | }
65 | }
66 | }
67 |
68 | struct MapSettingView_Previews: PreviewProvider {
69 | static var previews: some View {
70 | MapSettingView(dismiss: {})
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/Sources/BottomSheet/ViewExtension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewExtension.swift
3 | // BottomSheet
4 | //
5 | // Created by Tieda Wei on 2020-04-25.
6 | // Copyright © 2020 Tieda Wei. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | #if !os(macOS)
12 | public extension View {
13 | func bottomSheet(
14 | isPresented: Binding,
15 | height: CGFloat,
16 | topBarHeight: CGFloat = 30,
17 | topBarCornerRadius: CGFloat? = nil,
18 | contentBackgroundColor: Color = Color(.systemBackground),
19 | topBarBackgroundColor: Color = Color(.systemBackground),
20 | showTopIndicator: Bool = true,
21 | onDismiss: (() -> Void)? = nil,
22 | @ViewBuilder content: @escaping () -> Content
23 | ) -> some View {
24 | ZStack {
25 | self
26 | BottomSheet(isPresented: isPresented,
27 | height: height,
28 | topBarHeight: topBarHeight,
29 | topBarCornerRadius: topBarCornerRadius,
30 | topBarBackgroundColor: topBarBackgroundColor,
31 | contentBackgroundColor: contentBackgroundColor,
32 | showTopIndicator: showTopIndicator,
33 | onDismiss: onDismiss,
34 | content: content)
35 | }
36 | }
37 |
38 | func bottomSheet(
39 | item: Binding- ,
40 | height: CGFloat,
41 | topBarHeight: CGFloat = 30,
42 | topBarCornerRadius: CGFloat? = nil,
43 | contentBackgroundColor: Color = Color(.systemBackground),
44 | topBarBackgroundColor: Color = Color(.systemBackground),
45 | showTopIndicator: Bool = true,
46 | onDismiss: (() -> Void)? = nil,
47 | @ViewBuilder content: @escaping (Item) -> Content
48 | ) -> some View {
49 | let isPresented = Binding {
50 | item.wrappedValue != nil
51 | } set: { value in
52 | if !value {
53 | item.wrappedValue = nil
54 | }
55 | }
56 |
57 | return bottomSheet(
58 | isPresented: isPresented,
59 | height: height,
60 | topBarHeight: topBarHeight,
61 | topBarCornerRadius: topBarCornerRadius,
62 | contentBackgroundColor: contentBackgroundColor,
63 | topBarBackgroundColor: topBarBackgroundColor,
64 | showTopIndicator: showTopIndicator,
65 | onDismiss: onDismiss
66 | ) {
67 | if let unwrappedItem = item.wrappedValue {
68 | content(unwrappedItem).disabled(isPresented.wrappedValue)
69 | } else {
70 | EmptyView()
71 | }
72 | }
73 | }
74 | }
75 | #endif
76 |
--------------------------------------------------------------------------------
/Sources/BottomSheet/BottomSheet.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BottomSheet.swift
3 | // BottomSheet
4 | //
5 | // Created by Tieda Wei on 2020-04-25.
6 | // Copyright © 2020 Tieda Wei. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | #if !os(macOS)
12 | public struct BottomSheet: View {
13 |
14 | private var dragToDismissThreshold: CGFloat { height * 0.2 }
15 | private var grayBackgroundOpacity: Double { isPresented ? (0.4 - Double(draggedOffset)/600) : 0 }
16 |
17 | @State private var draggedOffset: CGFloat = 0
18 | @State private var previousDragValue: DragGesture.Value?
19 |
20 | @Binding var isPresented: Bool
21 | private let height: CGFloat
22 | private let topBarHeight: CGFloat
23 | private let topBarCornerRadius: CGFloat
24 | private let content: Content
25 | private let contentBackgroundColor: Color
26 | private let topBarBackgroundColor: Color
27 | private let showTopIndicator: Bool
28 | private let animation: Animation
29 | private let onDismiss: (() -> Void)?
30 |
31 | public init(
32 | isPresented: Binding,
33 | height: CGFloat,
34 | topBarHeight: CGFloat = 30,
35 | topBarCornerRadius: CGFloat? = nil,
36 | topBarBackgroundColor: Color = Color(.systemBackground),
37 | contentBackgroundColor: Color = Color(.systemBackground),
38 | showTopIndicator: Bool,
39 | animation: Animation = .easeInOut(duration: 0.3),
40 | onDismiss: (() -> Void)? = nil,
41 | @ViewBuilder content: () -> Content
42 | ) {
43 | self.topBarBackgroundColor = topBarBackgroundColor
44 | self.contentBackgroundColor = contentBackgroundColor
45 | self._isPresented = isPresented
46 | self.height = height
47 | self.topBarHeight = topBarHeight
48 | if let topBarCornerRadius = topBarCornerRadius {
49 | self.topBarCornerRadius = topBarCornerRadius
50 | } else {
51 | self.topBarCornerRadius = topBarHeight / 3
52 | }
53 | self.showTopIndicator = showTopIndicator
54 | self.animation = animation
55 | self.onDismiss = onDismiss
56 | self.content = content()
57 | }
58 |
59 | public var body: some View {
60 | GeometryReader { geometry in
61 | if geometry.size != .zero {
62 | ZStack {
63 | self.fullScreenLightGrayOverlay()
64 | VStack(spacing: 0) {
65 | self.topBar(geometry: geometry)
66 | VStack(spacing: -8) {
67 | Spacer()
68 | self.content.padding(.bottom, geometry.safeAreaInsets.bottom)
69 | Spacer()
70 | }
71 | }
72 | .frame(height: sheetHeight(in: geometry) - min(self.draggedOffset*2, 0))
73 | .background(self.contentBackgroundColor)
74 | .cornerRadius(self.topBarCornerRadius, corners: [.topLeft, .topRight])
75 | .animation(animation)
76 | .offset(y: self.isPresented ? (geometry.size.height/2 - sheetHeight(in: geometry)/2 + geometry.safeAreaInsets.bottom + self.draggedOffset) : (geometry.size.height/2 + sheetHeight(in: geometry)/2 + geometry.safeAreaInsets.bottom))
77 | }
78 | } else {
79 | EmptyView()
80 | }
81 | }
82 | }
83 |
84 | fileprivate func sheetHeight(in geometry: GeometryProxy) -> CGFloat {
85 | return min(height, geometry.size.height)
86 | }
87 |
88 | fileprivate func fullScreenLightGrayOverlay() -> some View {
89 | Color
90 | .black
91 | .opacity(grayBackgroundOpacity)
92 | .edgesIgnoringSafeArea(.all)
93 | .animation(animation)
94 | .onTapGesture {
95 | self.isPresented = false
96 | onDismiss?()
97 | }
98 | }
99 |
100 | fileprivate func topBar(geometry: GeometryProxy) -> some View {
101 | ZStack {
102 | RoundedRectangle(cornerRadius: 6)
103 | .fill(Color.secondary)
104 | .frame(width: 40, height: 6)
105 | .opacity(showTopIndicator ? 1 : 0)
106 | }
107 | .frame(width: geometry.size.width, height: topBarHeight)
108 | .background(topBarBackgroundColor)
109 | .gesture(
110 | DragGesture()
111 | .onChanged({ (value) in
112 | // ignore gestures while the sheet is hidden. Otherwise it could collide with the iOS-global "go to home screen"-gesture
113 | guard isPresented else { return }
114 |
115 | let offsetY = value.translation.height
116 | self.draggedOffset = offsetY
117 |
118 | if let previousValue = self.previousDragValue {
119 | let previousOffsetY = previousValue.translation.height
120 | let timeDiff = Double(value.time.timeIntervalSince(previousValue.time))
121 | let heightDiff = Double(offsetY - previousOffsetY)
122 | let velocityY = heightDiff / timeDiff
123 | if velocityY > 1400 {
124 | self.isPresented = false
125 | onDismiss?()
126 | return
127 | }
128 | }
129 | self.previousDragValue = value
130 |
131 | })
132 | .onEnded({ (value) in
133 | let offsetY = value.translation.height
134 | if offsetY > self.dragToDismissThreshold {
135 | self.isPresented = false
136 | onDismiss?()
137 | }
138 | self.draggedOffset = 0
139 | })
140 | )
141 | }
142 | }
143 | #endif
144 |
--------------------------------------------------------------------------------
/iOS Example/iOS Example.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 52;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 8311EFAB25182FD500D0C52F /* MapSettingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8311EFAA25182FD500D0C52F /* MapSettingView.swift */; };
11 | 83B5CFEE245609BD00BF7435 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83B5CFED245609BD00BF7435 /* ContentView.swift */; };
12 | D9A12776235699C600D136A5 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9A12775235699C600D136A5 /* AppDelegate.swift */; };
13 | D9A12778235699C600D136A5 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9A12777235699C600D136A5 /* SceneDelegate.swift */; };
14 | D9A1277F235699C700D136A5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D9A1277E235699C700D136A5 /* Assets.xcassets */; };
15 | D9A12782235699C700D136A5 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D9A12780235699C700D136A5 /* LaunchScreen.storyboard */; };
16 | D9A1278B2356A25E00D136A5 /* BottomSheet in Frameworks */ = {isa = PBXBuildFile; productRef = D9A1278A2356A25E00D136A5 /* BottomSheet */; };
17 | /* End PBXBuildFile section */
18 |
19 | /* Begin PBXFileReference section */
20 | 8311EFAA25182FD500D0C52F /* MapSettingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapSettingView.swift; sourceTree = ""; };
21 | 83B5CFED245609BD00BF7435 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; };
22 | D9A12772235699C600D136A5 /* iOS Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "iOS Example.app"; sourceTree = BUILT_PRODUCTS_DIR; };
23 | D9A12775235699C600D136A5 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
24 | D9A12777235699C600D136A5 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; };
25 | D9A1277E235699C700D136A5 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
26 | D9A12781235699C700D136A5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
27 | D9A12783235699C700D136A5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
28 | /* End PBXFileReference section */
29 |
30 | /* Begin PBXFrameworksBuildPhase section */
31 | D9A1276F235699C600D136A5 /* Frameworks */ = {
32 | isa = PBXFrameworksBuildPhase;
33 | buildActionMask = 2147483647;
34 | files = (
35 | D9A1278B2356A25E00D136A5 /* BottomSheet in Frameworks */,
36 | );
37 | runOnlyForDeploymentPostprocessing = 0;
38 | };
39 | /* End PBXFrameworksBuildPhase section */
40 |
41 | /* Begin PBXGroup section */
42 | D9A12769235699C600D136A5 = {
43 | isa = PBXGroup;
44 | children = (
45 | D9A12774235699C600D136A5 /* Sources */,
46 | D9A12773235699C600D136A5 /* Products */,
47 | D9A127892356A25E00D136A5 /* Frameworks */,
48 | );
49 | sourceTree = "";
50 | };
51 | D9A12773235699C600D136A5 /* Products */ = {
52 | isa = PBXGroup;
53 | children = (
54 | D9A12772235699C600D136A5 /* iOS Example.app */,
55 | );
56 | name = Products;
57 | sourceTree = "";
58 | };
59 | D9A12774235699C600D136A5 /* Sources */ = {
60 | isa = PBXGroup;
61 | children = (
62 | D9A12775235699C600D136A5 /* AppDelegate.swift */,
63 | D9A12777235699C600D136A5 /* SceneDelegate.swift */,
64 | D9A1277E235699C700D136A5 /* Assets.xcassets */,
65 | D9A12780235699C700D136A5 /* LaunchScreen.storyboard */,
66 | D9A12783235699C700D136A5 /* Info.plist */,
67 | 83B5CFED245609BD00BF7435 /* ContentView.swift */,
68 | 8311EFAA25182FD500D0C52F /* MapSettingView.swift */,
69 | );
70 | path = Sources;
71 | sourceTree = "";
72 | };
73 | D9A127892356A25E00D136A5 /* Frameworks */ = {
74 | isa = PBXGroup;
75 | children = (
76 | );
77 | name = Frameworks;
78 | sourceTree = "";
79 | };
80 | /* End PBXGroup section */
81 |
82 | /* Begin PBXNativeTarget section */
83 | D9A12771235699C600D136A5 /* iOS Example */ = {
84 | isa = PBXNativeTarget;
85 | buildConfigurationList = D9A12786235699C700D136A5 /* Build configuration list for PBXNativeTarget "iOS Example" */;
86 | buildPhases = (
87 | D9A1276E235699C600D136A5 /* Sources */,
88 | D9A1276F235699C600D136A5 /* Frameworks */,
89 | D9A12770235699C600D136A5 /* Resources */,
90 | );
91 | buildRules = (
92 | );
93 | dependencies = (
94 | );
95 | name = "iOS Example";
96 | packageProductDependencies = (
97 | D9A1278A2356A25E00D136A5 /* BottomSheet */,
98 | );
99 | productName = "iOS Example";
100 | productReference = D9A12772235699C600D136A5 /* iOS Example.app */;
101 | productType = "com.apple.product-type.application";
102 | };
103 | /* End PBXNativeTarget section */
104 |
105 | /* Begin PBXProject section */
106 | D9A1276A235699C600D136A5 /* Project object */ = {
107 | isa = PBXProject;
108 | attributes = {
109 | LastSwiftUpdateCheck = 1110;
110 | LastUpgradeCheck = 1110;
111 | ORGANIZATIONNAME = "Tieda Wei";
112 | TargetAttributes = {
113 | D9A12771235699C600D136A5 = {
114 | CreatedOnToolsVersion = 11.1;
115 | };
116 | };
117 | };
118 | buildConfigurationList = D9A1276D235699C600D136A5 /* Build configuration list for PBXProject "iOS Example" */;
119 | compatibilityVersion = "Xcode 9.3";
120 | developmentRegion = en;
121 | hasScannedForEncodings = 0;
122 | knownRegions = (
123 | en,
124 | Base,
125 | );
126 | mainGroup = D9A12769235699C600D136A5;
127 | productRefGroup = D9A12773235699C600D136A5 /* Products */;
128 | projectDirPath = "";
129 | projectRoot = "";
130 | targets = (
131 | D9A12771235699C600D136A5 /* iOS Example */,
132 | );
133 | };
134 | /* End PBXProject section */
135 |
136 | /* Begin PBXResourcesBuildPhase section */
137 | D9A12770235699C600D136A5 /* Resources */ = {
138 | isa = PBXResourcesBuildPhase;
139 | buildActionMask = 2147483647;
140 | files = (
141 | D9A12782235699C700D136A5 /* LaunchScreen.storyboard in Resources */,
142 | D9A1277F235699C700D136A5 /* Assets.xcassets in Resources */,
143 | );
144 | runOnlyForDeploymentPostprocessing = 0;
145 | };
146 | /* End PBXResourcesBuildPhase section */
147 |
148 | /* Begin PBXSourcesBuildPhase section */
149 | D9A1276E235699C600D136A5 /* Sources */ = {
150 | isa = PBXSourcesBuildPhase;
151 | buildActionMask = 2147483647;
152 | files = (
153 | D9A12776235699C600D136A5 /* AppDelegate.swift in Sources */,
154 | 83B5CFEE245609BD00BF7435 /* ContentView.swift in Sources */,
155 | 8311EFAB25182FD500D0C52F /* MapSettingView.swift in Sources */,
156 | D9A12778235699C600D136A5 /* SceneDelegate.swift in Sources */,
157 | );
158 | runOnlyForDeploymentPostprocessing = 0;
159 | };
160 | /* End PBXSourcesBuildPhase section */
161 |
162 | /* Begin PBXVariantGroup section */
163 | D9A12780235699C700D136A5 /* LaunchScreen.storyboard */ = {
164 | isa = PBXVariantGroup;
165 | children = (
166 | D9A12781235699C700D136A5 /* Base */,
167 | );
168 | name = LaunchScreen.storyboard;
169 | sourceTree = "";
170 | };
171 | /* End PBXVariantGroup section */
172 |
173 | /* Begin XCBuildConfiguration section */
174 | D9A12784235699C700D136A5 /* Debug */ = {
175 | isa = XCBuildConfiguration;
176 | buildSettings = {
177 | ALWAYS_SEARCH_USER_PATHS = NO;
178 | CLANG_ANALYZER_NONNULL = YES;
179 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
180 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
181 | CLANG_CXX_LIBRARY = "libc++";
182 | CLANG_ENABLE_MODULES = YES;
183 | CLANG_ENABLE_OBJC_ARC = YES;
184 | CLANG_ENABLE_OBJC_WEAK = YES;
185 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
186 | CLANG_WARN_BOOL_CONVERSION = YES;
187 | CLANG_WARN_COMMA = YES;
188 | CLANG_WARN_CONSTANT_CONVERSION = YES;
189 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
190 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
191 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
192 | CLANG_WARN_EMPTY_BODY = YES;
193 | CLANG_WARN_ENUM_CONVERSION = YES;
194 | CLANG_WARN_INFINITE_RECURSION = YES;
195 | CLANG_WARN_INT_CONVERSION = YES;
196 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
197 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
198 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
199 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
200 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
201 | CLANG_WARN_STRICT_PROTOTYPES = YES;
202 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
203 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
204 | CLANG_WARN_UNREACHABLE_CODE = YES;
205 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
206 | COPY_PHASE_STRIP = NO;
207 | DEBUG_INFORMATION_FORMAT = dwarf;
208 | ENABLE_STRICT_OBJC_MSGSEND = YES;
209 | ENABLE_TESTABILITY = YES;
210 | GCC_C_LANGUAGE_STANDARD = gnu11;
211 | GCC_DYNAMIC_NO_PIC = NO;
212 | GCC_NO_COMMON_BLOCKS = YES;
213 | GCC_OPTIMIZATION_LEVEL = 0;
214 | GCC_PREPROCESSOR_DEFINITIONS = (
215 | "DEBUG=1",
216 | "$(inherited)",
217 | );
218 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
219 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
220 | GCC_WARN_UNDECLARED_SELECTOR = YES;
221 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
222 | GCC_WARN_UNUSED_FUNCTION = YES;
223 | GCC_WARN_UNUSED_VARIABLE = YES;
224 | IPHONEOS_DEPLOYMENT_TARGET = 13.4;
225 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
226 | MTL_FAST_MATH = YES;
227 | ONLY_ACTIVE_ARCH = YES;
228 | SDKROOT = iphoneos;
229 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
230 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
231 | SWIFT_VERSION = 5.0;
232 | };
233 | name = Debug;
234 | };
235 | D9A12785235699C700D136A5 /* Release */ = {
236 | isa = XCBuildConfiguration;
237 | buildSettings = {
238 | ALWAYS_SEARCH_USER_PATHS = NO;
239 | CLANG_ANALYZER_NONNULL = YES;
240 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
241 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
242 | CLANG_CXX_LIBRARY = "libc++";
243 | CLANG_ENABLE_MODULES = YES;
244 | CLANG_ENABLE_OBJC_ARC = YES;
245 | CLANG_ENABLE_OBJC_WEAK = YES;
246 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
247 | CLANG_WARN_BOOL_CONVERSION = YES;
248 | CLANG_WARN_COMMA = YES;
249 | CLANG_WARN_CONSTANT_CONVERSION = YES;
250 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
251 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
252 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
253 | CLANG_WARN_EMPTY_BODY = YES;
254 | CLANG_WARN_ENUM_CONVERSION = YES;
255 | CLANG_WARN_INFINITE_RECURSION = YES;
256 | CLANG_WARN_INT_CONVERSION = YES;
257 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
258 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
259 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
260 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
261 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
262 | CLANG_WARN_STRICT_PROTOTYPES = YES;
263 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
264 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
265 | CLANG_WARN_UNREACHABLE_CODE = YES;
266 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
267 | COPY_PHASE_STRIP = NO;
268 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
269 | ENABLE_NS_ASSERTIONS = NO;
270 | ENABLE_STRICT_OBJC_MSGSEND = YES;
271 | GCC_C_LANGUAGE_STANDARD = gnu11;
272 | GCC_NO_COMMON_BLOCKS = YES;
273 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
274 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
275 | GCC_WARN_UNDECLARED_SELECTOR = YES;
276 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
277 | GCC_WARN_UNUSED_FUNCTION = YES;
278 | GCC_WARN_UNUSED_VARIABLE = YES;
279 | IPHONEOS_DEPLOYMENT_TARGET = 13.4;
280 | MTL_ENABLE_DEBUG_INFO = NO;
281 | MTL_FAST_MATH = YES;
282 | SDKROOT = iphoneos;
283 | SWIFT_COMPILATION_MODE = wholemodule;
284 | SWIFT_OPTIMIZATION_LEVEL = "-O";
285 | SWIFT_VERSION = 5.0;
286 | VALIDATE_PRODUCT = YES;
287 | };
288 | name = Release;
289 | };
290 | D9A12787235699C700D136A5 /* Debug */ = {
291 | isa = XCBuildConfiguration;
292 | buildSettings = {
293 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
294 | CODE_SIGN_STYLE = Automatic;
295 | DEVELOPMENT_TEAM = T64RAU2S7P;
296 | INFOPLIST_FILE = Sources/Info.plist;
297 | IPHONEOS_DEPLOYMENT_TARGET = 13.4;
298 | LD_RUNPATH_SEARCH_PATHS = (
299 | "$(inherited)",
300 | "@executable_path/Frameworks",
301 | );
302 | PRODUCT_BUNDLE_IDENTIFIER = "com.tiedawei.iOS-Example";
303 | PRODUCT_NAME = "$(TARGET_NAME)";
304 | SWIFT_VERSION = 5.0;
305 | TARGETED_DEVICE_FAMILY = 1;
306 | };
307 | name = Debug;
308 | };
309 | D9A12788235699C700D136A5 /* Release */ = {
310 | isa = XCBuildConfiguration;
311 | buildSettings = {
312 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
313 | CODE_SIGN_STYLE = Automatic;
314 | DEVELOPMENT_TEAM = T64RAU2S7P;
315 | INFOPLIST_FILE = Sources/Info.plist;
316 | IPHONEOS_DEPLOYMENT_TARGET = 13.4;
317 | LD_RUNPATH_SEARCH_PATHS = (
318 | "$(inherited)",
319 | "@executable_path/Frameworks",
320 | );
321 | PRODUCT_BUNDLE_IDENTIFIER = "com.tiedawei.iOS-Example";
322 | PRODUCT_NAME = "$(TARGET_NAME)";
323 | SWIFT_VERSION = 5.0;
324 | TARGETED_DEVICE_FAMILY = 1;
325 | };
326 | name = Release;
327 | };
328 | /* End XCBuildConfiguration section */
329 |
330 | /* Begin XCConfigurationList section */
331 | D9A1276D235699C600D136A5 /* Build configuration list for PBXProject "iOS Example" */ = {
332 | isa = XCConfigurationList;
333 | buildConfigurations = (
334 | D9A12784235699C700D136A5 /* Debug */,
335 | D9A12785235699C700D136A5 /* Release */,
336 | );
337 | defaultConfigurationIsVisible = 0;
338 | defaultConfigurationName = Release;
339 | };
340 | D9A12786235699C700D136A5 /* Build configuration list for PBXNativeTarget "iOS Example" */ = {
341 | isa = XCConfigurationList;
342 | buildConfigurations = (
343 | D9A12787235699C700D136A5 /* Debug */,
344 | D9A12788235699C700D136A5 /* Release */,
345 | );
346 | defaultConfigurationIsVisible = 0;
347 | defaultConfigurationName = Release;
348 | };
349 | /* End XCConfigurationList section */
350 |
351 | /* Begin XCSwiftPackageProductDependency section */
352 | D9A1278A2356A25E00D136A5 /* BottomSheet */ = {
353 | isa = XCSwiftPackageProductDependency;
354 | productName = BottomSheet;
355 | };
356 | /* End XCSwiftPackageProductDependency section */
357 | };
358 | rootObject = D9A1276A235699C600D136A5 /* Project object */;
359 | }
360 |
--------------------------------------------------------------------------------