Skip to content

Commit

Permalink
New Year Update (#38)
Browse files Browse the repository at this point in the history
- Update Copyright
- Update swift-tools-version
- Update deprecated code (real fix for #19, replaces #20)
- Add `.absolutePositionValue` option (closes #37)
- Add `BottomSheetPositionAbsolute`
- Use explicit animations (fixes #31)
- Hide examples in ReadMe
- Implement and fix `.appleScrollBehavior` (closes #37)
  • Loading branch information
lucaszischka authored Dec 28, 2021
1 parent 737c239 commit 1702332
Show file tree
Hide file tree
Showing 14 changed files with 344 additions and 93 deletions.
2 changes: 1 addition & 1 deletion BottomSheetSwiftUI.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'BottomSheetSwiftUI'
s.version = '2.4.0'
s.version = '2.5.0'
s.summary = 'A sliding Sheet from the bottom of the Screen with 3 States build with SwiftUI.'

s.homepage = 'https://github.com/LucasMucGH/BottomSheet'
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
BottomSheet Changelog
==================

#### v2.5.0
- Update Copyright
- Update swift-tools-version
- Update deprecated code (real fix for #19, replaces #20)
- Add `.absolutePositionValue` option #37
- Add `BottomSheetPositionAbsolute`
- Use explicit animations #31
- Hide examples in ReadMe
- Update and fix `.appleScrollBehavior` #37
- Code clean up

#### v2.4.0
- Add option to enable shadow
- Add pod install
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version:5.3
// swift-tools-version:5.1
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription
Expand Down
55 changes: 41 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ struct ContentView: View {

### Options

`.absolutePositionValue` Allows absolute values in pixels to be used as BottomSheetPosition values.

`.allowContentDrag` Allows the BottomSheet to move when dragging the mainContent.

- Do not use if the mainContent is packed into a ScrollView.
Expand Down Expand Up @@ -173,15 +175,15 @@ struct ContentView: View {

## Custom States


You can create your own custom BottomSheetPosition enum:
- The enum must be conforming to `CGFloat` and `CaseIterable`
- The case and enum name doesnt matter
- The case/state with `rawValue == 0` is hiding the BottomSheet
- The value can be anythig between `0` and `1` (`x <= 1`, `x >= 0`)
- The value is the height of the BottomSheet propotional to the screen height (`1 == 100% == full screen`)
- The value can be anythig between `0` and `1` (`x <= 1`, `x >= 0`) or anything above `0` (`x >= 0`) when using the`.absolutePositionValue` option
- The value is the height of the BottomSheet propotional to the screen height (`1 == 100% == full screen`) or the height of the BottomSheet in pixel (`1 == 1px`) when using the`.absolutePositionValue` option
- The lowest value (greater than 0) automaticly gets the `.bottom` behavior. To prevent this please use the option `.noBottomPosition`

This BottomSheetPosition uses relative values.
```swift
import SwiftUI

Expand All @@ -190,6 +192,13 @@ enum CustomBottomSheetPosition: CGFloat, CaseIterable {
}
```

This BottomSheetPositionAbsolute uses absolute values and requires the the`.absolutePositionValue` option.
```swift
public enum BottomSheetPositionAbsolute: CGFloat, CaseIterable {
case top = 750, middle = 300, bottom = 100, hidden = 0
}
```

## Examples

**PLEASE NOTE:** When installed via Cocoapods, please keep in mind that the pod is called `BottomSheetSwiftUI` and not `BottomSheet`; so please use `import BottomSheetSwiftUI` instead.
Expand All @@ -198,22 +207,26 @@ enum CustomBottomSheetPosition: CGFloat, CaseIterable {

This BottomSheet shows additional information about a book.
You can close it by swiping it away, by tapping on the background or the close button.
It also uses a custom `enum` for the states, since only the states `.middle`, `.bottom` and `.hidden` should exist.
The drag indicator is hidden.
It uses a custom `enum` for the states with absolute values, since only the states `.middle`, `.bottom` and `.hidden` should exist with a predefined absolute height.

<img src="https://user-images.githubusercontent.com/63545066/132514316-c0d723c6-37fc-4104-b04c-6cf7bbcb0899.gif" height="600">

<details>
<summary>Source Code</summary>

```swift
import SwiftUI
import BottomSheet

//The custom BottomSheetPosition enum.
//The custom BottomSheetPosition enum with absolute values.
enum BookBottomSheetPosition: CGFloat, CaseIterable {
case middle = 0.4, bottom = 0.125, hidden = 0
case middle = 300, bottom = 100, hidden = 0
}

struct BookDetailView: View {

@State private var bottomSheetPosition: BookBottomSheetPosition = .middle
@State var bottomSheetPosition: BookBottomSheetPosition = .middle

let backgroundColors: [Color] = [Color(red: 0.2, green: 0.85, blue: 0.7), Color(red: 0.13, green: 0.55, blue: 0.45)]
let readMoreColors: [Color] = [Color(red: 0.70, green: 0.22, blue: 0.22), Color(red: 1, green: 0.32, blue: 0.32)]
Expand All @@ -224,7 +237,7 @@ struct BookDetailView: View {
LinearGradient(gradient: Gradient(colors: self.backgroundColors), startPoint: .topLeading, endPoint: .bottomTrailing)
.edgesIgnoringSafeArea(.all)

.bottomSheet(bottomSheetPosition: self.$bottomSheetPosition, options: [.allowContentDrag, .showCloseButton(), .swipeToDismiss, .tapToDissmiss], headerContent: {
.bottomSheet(bottomSheetPosition: self.$bottomSheetPosition, options: [.noDragIndicator, .allowContentDrag, .showCloseButton(), .swipeToDismiss, .tapToDissmiss, .absolutePositionValue], headerContent: {
//The name of the book as the heading and the author as the subtitle with a divider.
VStack(alignment: .leading) {
Text("Wuthering Heights")
Expand Down Expand Up @@ -279,27 +292,36 @@ struct BookButton: ButtonStyle {
}
}
```
</details>

### Word Search View

This BottomSheet shows nouns which can be filtered by searching.
It adopts the scrolling behavior of apple, so that you can only scroll the `ScrollView` in the `.top` position.
It adopts the scrolling behavior of apple, so that you can only scroll the `ScrollView` in the `.top` position.
The higher the BottomSheet is dragged, the more blurry the background becomes (with the BlurEffect .dark) to move the focus to the BottomSheet.

<img src="https://user-images.githubusercontent.com/63545066/132514347-57c5397b-ec03-4716-8e01-4e693082e844.gif" height="600">

<details>
<summary>Source Code</summary>

```swift
import SwiftUI
import BottomSheet

struct WordSearchView: View {

@State private var bottomSheetPosition: BottomSheetPosition = .middle
@State var bottomSheetPosition: BottomSheetPosition = .middle
@State var searchText: String = ""

@State private var searchText: String = ""
let backgroundColors: [Color] = [Color(red: 0.28, green: 0.28, blue: 0.53), Color(red: 1, green: 0.69, blue: 0.26)]
let words: [String] = ["birthday", "pancake", "expansion", "brick", "bushes", "coal", "calendar", "home", "pig", "bath", "reading", "cellar", "knot", "year", "ink"]

var filteredWords: [String] {
self.words.filter({ $0.contains(self.searchText.lowercased()) || self.searchText.isEmpty })
}


var body: some View {
//A green gradient as a background that ignores the safe area.
LinearGradient(gradient: Gradient(colors: self.backgroundColors), startPoint: .topLeading, endPoint: .bottomTrailing)
Expand All @@ -322,20 +344,21 @@ struct WordSearchView: View {
}
}) {
//The list of nouns that will be filtered by the searchText.
ForEach(self.words.filter({ $0.contains(self.searchText.lowercased()) || self.searchText.isEmpty}), id: \.self) { word in
ForEach(self.filteredWords, id: \.self) { word in
Text(word)
.font(.title)
.padding([.leading, .bottom])
.frame(maxWidth: .infinity, alignment: .leading)
}
.frame(maxWidth: .infinity, alignment: .leading)
.transition(.opacity)
.animation(.easeInOut)
.animation(.easeInOut, value: self.filteredWords)
.padding(.top)
}
}
}
```
</details>

### Artist Songs View

Expand All @@ -344,13 +367,16 @@ It has a custom animation and color for the drag indicator and the background, a

<img src="https://user-images.githubusercontent.com/63545066/132514283-b14b2977-c5d1-4b49-96b1-19995cd5a41f.gif" height="600">

<details>
<summary>Source Code</summary>

```swift
import SwiftUI
import BottomSheet

struct ArtistSongsView: View {

@State private var bottomSheetPosition: BottomSheetPosition = .middle
@State var bottomSheetPosition: BottomSheetPosition = .middle

let backgroundColors: [Color] = [Color(red: 0.17, green: 0.17, blue: 0.33), Color(red: 0.80, green: 0.38, blue: 0.2)]
let songs: [String] = ["One Dance (feat. Wizkid & Kyla)", "God's Plan", "SICKO MODE", "In My Feelings", "Work (feat. Drake)", "Nice For What", "Hotline Bling", "Too Good (feat. Rihanna)", "Life Is Good (feat. Drake)"]
Expand All @@ -374,6 +400,7 @@ struct ArtistSongsView: View {
}
}
```
</details>

## Contributing

Expand Down
6 changes: 5 additions & 1 deletion Sources/BottomSheet/BottomSheet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// BottomSheet.swift
//
// Created by Lucas Zischka.
// Copyright © 2021 Lucas Zischka. All rights reserved.
// Copyright © 2021-2022 Lucas Zischka. All rights reserved.
//

import SwiftUI
Expand All @@ -14,6 +14,8 @@ public struct BottomSheet {
return lhs.rawValue == rhs.rawValue
}

///Allows absolute values in pixels to be used as BottomSheetPosition values.
case absolutePositionValue
///Allows the BottomSheet to move when dragging the mainContent. Do not use if the mainContent is packed into a ScrollView.
case allowContentDrag
///Sets the animation for opening and closing the BottomSheet.
Expand Down Expand Up @@ -62,6 +64,8 @@ public struct BottomSheet {
*/
public var rawValue: String {
switch self {
case .absolutePositionValue:
return "absolutePositionValue"
case .allowContentDrag:
return "allowContentDrag"
case .animation:
Expand Down
6 changes: 5 additions & 1 deletion Sources/BottomSheet/BottomSheetArray.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@
// BottomSheetArray.swift
//
// Created by Lucas Zischka.
// Copyright © 2021 Lucas Zischka. All rights reserved.
// Copyright © 2021-2022 Lucas Zischka. All rights reserved.
//

import SwiftUI

internal extension Array where Element == BottomSheet.Options {
var absolutePositionValue: Bool {
return self.contains(BottomSheet.Options.absolutePositionValue)
}

var allowContentDrag: Bool {
return self.contains(BottomSheet.Options.allowContentDrag)
}
Expand Down
42 changes: 34 additions & 8 deletions Sources/BottomSheet/BottomSheetPosition.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,55 @@
// BottomSheetPosition.swift
//
// Created by Lucas Zischka.
// Copyright © 2021 Lucas Zischka. All rights reserved.
// Copyright © 2021-2022 Lucas Zischka. All rights reserved.
//

import SwiftUI

/**
The default BottomSheetPosition; it has the following cases and values: `top = 0.975`, `middle = 0.4`, `bottom = 0.125`, `hidden = 0`
The default BottomSheetPosition; it has the following cases and values: `top = 0.975`, `middle = 0.4`, `bottom = 0.125`, `hidden = 0`.
This BottomSheetPosition uses relative values. For absolute values in pixels, see BottomSheetPositionAbsolute.
You can create your own custom BottomSheetPosition enum:
- The enum must be conforming to `CGFloat` and `CaseIterable`
- The case and enum name doesnt matter
- The case/state with `rawValue == 0` is hiding the BottomSheet
- The value can be anythig between `0` and `1` (`x <= 1`, `x >= 0`)
- The value is the height of the BottomSheet propotional to the screen height (`1 == 100% == full screen`)
- The value can be anythig between `0` and `1` (`x <= 1`, `x >= 0`) or anything above `0` (`x >= 0`) when using the`.absolutePositionValue` option
- The value is the height of the BottomSheet propotional to the screen height (`1 == 100% == full screen`) or the height of the BottomSheet in pixel (`1 == 1px`) when using the`.absolutePositionValue` option
- The lowest value (greater than 0) automaticly gets the `.bottom` behavior. To prevent this please use the option `.noBottomPosition`
*/
public enum BottomSheetPosition: CGFloat, CaseIterable {
//The state where the height of the BottomSheet is 97.5%
///The state where the height of the BottomSheet is 97.5%
case top = 0.975
//The state where the height of the BottomSheet is 40%
///The state where the height of the BottomSheet is 40%
case middle = 0.4
//The state where the height of the BottomSheet is 12.5% and the `mainContent` is hidden
///The state where the height of the BottomSheet is 12.5% and the `mainContent` is hidden
case bottom = 0.125
//The state where the BottomSheet is hidden
///The state where the BottomSheet is hidden
case hidden = 0
}

/**
The default BottomSheetPositionAbsolute; it has the following cases and values: `top = 750`, `middle = 300`, `bottom = 100`, `hidden = 0`.
This BottomSheetPositionAbsolute uses absolute values and requires the the`.absolutePositionValue` option. For relative values in pixels, see BottomSheetPosition.
You can create your own custom BottomSheetPosition enum:
- The enum must be conforming to `CGFloat` and `CaseIterable`
- The case and enum name doesnt matter
- The case/state with `rawValue == 0` is hiding the BottomSheet
- The value can be anythig between `0` and `1` (`x <= 1`, `x >= 0`) or anything above `0` (`x >= 0`) when using the`.absolutePositionValue` option
- The value is the height of the BottomSheet propotional to the screen height (`1 == 100% == full screen`) or the height of the BottomSheet in pixel (`1 == 1px`) when using the`.absolutePositionValue` option
- The lowest value (greater than 0) automaticly gets the `.bottom` behavior. To prevent this please use the option `.noBottomPosition`
*/
public enum BottomSheetPositionAbsolute: CGFloat, CaseIterable {
///The state where the height of the BottomSheet is 750px
case top = 750
///The state where the height of the BottomSheet is 300px
case middle = 300
///The state where the height of the BottomSheet is 100px and the `mainContent` is hidden
case bottom = 100
///The state where the BottomSheet is hidden
case hidden = 0
}
Loading

0 comments on commit 1702332

Please sign in to comment.