Skip to content

Commit

Permalink
Add ability to set a custom popup bar view
Browse files Browse the repository at this point in the history
  • Loading branch information
LeoNatan committed Sep 3, 2020
1 parent 94e5a1f commit 97d2650
Show file tree
Hide file tree
Showing 12 changed files with 321 additions and 36 deletions.
16 changes: 12 additions & 4 deletions LNPopupUIExample/LNPopupUIExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@
/* Begin PBXBuildFile section */
395781D524DC5D2700A604D1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 395781D424DC5D2700A604D1 /* AppDelegate.swift */; };
395781D724DC5D2700A604D1 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 395781D624DC5D2700A604D1 /* SceneDelegate.swift */; };
395781D924DC5D2700A604D1 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 395781D824DC5D2700A604D1 /* ContentView.swift */; };
395781D924DC5D2700A604D1 /* MusicView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 395781D824DC5D2700A604D1 /* MusicView.swift */; };
395781DB24DC5D2800A604D1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 395781DA24DC5D2800A604D1 /* Assets.xcassets */; };
395781DE24DC5D2800A604D1 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 395781DD24DC5D2800A604D1 /* Preview Assets.xcassets */; };
395781E124DC5D2800A604D1 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 395781DF24DC5D2800A604D1 /* LaunchScreen.storyboard */; };
395781F324DC692300A604D1 /* PlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 395781F224DC692300A604D1 /* PlayerView.swift */; };
396B439624DC8EF100D84FC7 /* LoremIpsum in Frameworks */ = {isa = PBXBuildFile; productRef = 396B439524DC8EF100D84FC7 /* LoremIpsum */; };
398404EA25003925006C9011 /* SceneSelection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398404E925003925006C9011 /* SceneSelection.swift */; };
398404EE2500451E006C9011 /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398404ED2500451E006C9011 /* MapView.swift */; };
39E18E3B24F059F50096391B /* LNPopupUI in Frameworks */ = {isa = PBXBuildFile; productRef = 39E18E3A24F059F50096391B /* LNPopupUI */; };
39E18E3C24F059F50096391B /* LNPopupUI in Embed Frameworks */ = {isa = PBXBuildFile; productRef = 39E18E3A24F059F50096391B /* LNPopupUI */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
/* End PBXBuildFile section */
Expand All @@ -37,13 +39,15 @@
395781D124DC5D2700A604D1 /* LNPopupUIExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LNPopupUIExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
395781D424DC5D2700A604D1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
395781D624DC5D2700A604D1 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
395781D824DC5D2700A604D1 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
395781D824DC5D2700A604D1 /* MusicView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MusicView.swift; sourceTree = "<group>"; };
395781DA24DC5D2800A604D1 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
395781DD24DC5D2800A604D1 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
395781E024DC5D2800A604D1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
395781E224DC5D2800A604D1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
395781EA24DC5DE800A604D1 /* LNPopupUI */ = {isa = PBXFileReference; lastKnownFileType = folder; name = LNPopupUI; path = ..; sourceTree = "<group>"; };
395781F224DC692300A604D1 /* PlayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerView.swift; sourceTree = "<group>"; };
398404E925003925006C9011 /* SceneSelection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneSelection.swift; sourceTree = "<group>"; };
398404ED2500451E006C9011 /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -83,7 +87,9 @@
395781D424DC5D2700A604D1 /* AppDelegate.swift */,
395781D624DC5D2700A604D1 /* SceneDelegate.swift */,
395781F224DC692300A604D1 /* PlayerView.swift */,
395781D824DC5D2700A604D1 /* ContentView.swift */,
395781D824DC5D2700A604D1 /* MusicView.swift */,
398404ED2500451E006C9011 /* MapView.swift */,
398404E925003925006C9011 /* SceneSelection.swift */,
395781DA24DC5D2800A604D1 /* Assets.xcassets */,
395781DF24DC5D2800A604D1 /* LaunchScreen.storyboard */,
395781E224DC5D2800A604D1 /* Info.plist */,
Expand Down Expand Up @@ -186,8 +192,10 @@
buildActionMask = 2147483647;
files = (
395781D524DC5D2700A604D1 /* AppDelegate.swift in Sources */,
398404EE2500451E006C9011 /* MapView.swift in Sources */,
395781D724DC5D2700A604D1 /* SceneDelegate.swift in Sources */,
395781D924DC5D2700A604D1 /* ContentView.swift in Sources */,
395781D924DC5D2700A604D1 /* MusicView.swift in Sources */,
398404EA25003925006C9011 /* SceneSelection.swift in Sources */,
395781F324DC692300A604D1 /* PlayerView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
103 changes: 103 additions & 0 deletions LNPopupUIExample/LNPopupUIExample/MapView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
//
// MapView.swift
// LNPopupUIExample
//
// Created by Leo Natan (Wix) on 9/3/20.
//

import SwiftUI
import MapKit

struct EnlargingButton: View {
let label: String
let action: (Bool) -> Void
@State var pressed: Bool = false

init(label: String, perform action: @escaping (Bool) -> Void) {
self.label = label
self.action = action
}

var body: some View {
return Text(label)
.font(.title)
.foregroundColor(.white)
.padding(10)
.background(RoundedRectangle(cornerRadius: 10).foregroundColor(.blue))
.scaleEffect(self.pressed ? 1.2 : 1.0)
.onLongPressGesture(minimumDuration: .infinity, maximumDistance: .infinity, pressing: { pressing in
withAnimation(.easeInOut) {
self.pressed = pressing
self.action(pressing)
}
}, perform: { })
}
}

struct CustomBarMapView: View {
static private let center = CLLocationCoordinate2D(latitude: 40.6892, longitude: -74.0445)
static private let defaultRegion = MKCoordinateRegion(center: CustomBarMapView.center, span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5))

static private let zoomedRegion = MKCoordinateRegion(center: CustomBarMapView.center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))

@State private var region = CustomBarMapView.defaultRegion

private let onDismiss: () -> Void

init(onDismiss: @escaping () -> Void) {
self.onDismiss = onDismiss
}

@State var input: String = ""
@State var isPopupOpen: Bool = false

var body: some View {
ZStack(alignment: Alignment(horizontal: .leading, vertical: .top)) {
Map(coordinateRegion: $region)
.ignoresSafeArea()
.animation(.easeInOut)
Button(action: {
onDismiss()
}, label: {
Image(systemName: "chevron.left.circle.fill")
.resizable()
.renderingMode(.template)
.frame(width: 30, height: 30, alignment: .center)
})
.background(Color(.systemBackground).cornerRadius(15))
.padding(10)
}
.popup(isBarPresented: Binding.constant(true), isPopupOpen: $isPopupOpen) {
Color.red
.ignoresSafeArea()
}
.popupBarCustomView(wantsDefaultTapGesture: false, wantsDefaultPanGesture: false, wantsDefaultHighlightGesture: false) {
ZStack(alignment: .trailing) {
HStack {
Spacer()
EnlargingButton(label: "Zoom") { pressing in
self.region = pressing ? CustomBarMapView.zoomedRegion : CustomBarMapView.defaultRegion
}.padding()
Spacer()

}
Button(action: {
isPopupOpen.toggle()
}, label: {
Image(systemName: "chevron.up.square.fill")
.resizable()
.renderingMode(.template)
.frame(width: 30, height: 30, alignment: .center)
})
.background(Color(.systemBackground).cornerRadius(15))
.padding(10)
}
}
}
}

struct MapView_Previews: PreviewProvider {
static var previews: some View {
CustomBarMapView(onDismiss: {})
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// ContentView.swift
// MusicView.swift
// LNPopupUIExample
//
// Created by Leo Natan on 8/6/20.
Expand Down Expand Up @@ -27,14 +27,17 @@ fileprivate var songs: [RandomTitleSong] = {
}()

struct RandomTitlesListView : View {
@Environment(\.presentationMode) var presentationMode
private let title: String

@Binding var isPopupPresented: Bool
private let onSongSelect: (RandomTitleSong) -> Void
private let onDismiss: () -> Void

init(_ title: String, _ isPopupPresented: Binding<Bool>, onSongSelect: @escaping (RandomTitleSong) -> Void) {
init(_ title: String, _ isPopupPresented: Binding<Bool>, onDismiss: @escaping () -> Void, onSongSelect: @escaping (RandomTitleSong) -> Void) {
self.title = title
self._isPopupPresented = isPopupPresented
self.onDismiss = onDismiss
self.onSongSelect = onSongSelect
}

Expand Down Expand Up @@ -66,13 +69,15 @@ struct RandomTitlesListView : View {
.listStyle(PlainListStyle())
.navigationBarTitle(title)
.navigationBarTitleDisplayMode(.inline)
.navigationBarItems(trailing: Image(systemName: isPopupPresented ? "rectangle.bottomthird.inset.fill" : "rectangle"))
.navigationBarItems(leading: Image(systemName: isPopupPresented ? "rectangle.bottomthird.inset.fill" : "rectangle"), trailing: Button("Gallery") {
onDismiss()
})
}
.navigationViewStyle(StackNavigationViewStyle())
}
}

struct ContentView: View {
struct MusicView: View {
@State var isPopupPresented: Bool = false
@State var isPopupOpen: Bool = false

Expand All @@ -84,51 +89,57 @@ struct ContentView: View {
}
}

var body: some View {
private let onDismiss: () -> Void

init(onDismiss: @escaping () -> Void) {
self.onDismiss = onDismiss
}

var body: some View {
TabView {
RandomTitlesListView("Music", $isPopupPresented, onSongSelect: { song in
RandomTitlesListView("Music", $isPopupPresented, onDismiss:onDismiss, onSongSelect: { song in
currentSong = song
})
.tabItem {
Text("Music")
Image(systemName: "play.circle.fill")
}
RandomTitlesListView("Artists", $isPopupPresented, onSongSelect: { song in
.tabItem {
Text("Music")
Image(systemName: "play.circle.fill")
}
RandomTitlesListView("Artists", $isPopupPresented, onDismiss:onDismiss, onSongSelect: { song in
currentSong = song
})
.tabItem {
Text("Artists")
Image(systemName: "music.mic")
}
RandomTitlesListView("Composers", $isPopupPresented, onSongSelect: { song in
.tabItem {
Text("Artists")
Image(systemName: "music.mic")
}
RandomTitlesListView("Composers", $isPopupPresented, onDismiss:onDismiss, onSongSelect: { song in
currentSong = song
})
.tabItem {
Text("Composers")
Image(systemName: "music.quarternote.3")
}
RandomTitlesListView("Recents", $isPopupPresented, onSongSelect: { song in
.tabItem {
Text("Composers")
Image(systemName: "music.quarternote.3")
}
RandomTitlesListView("Recents", $isPopupPresented, onDismiss:onDismiss, onSongSelect: { song in
currentSong = song
})
.tabItem {
Text("Recents")
Image(systemName: "clock.fill")
}
.tabItem {
Text("Recents")
Image(systemName: "clock.fill")
}
}
.popup(isBarPresented: $isPopupPresented, isPopupOpen: $isPopupOpen) {
if let currentSong = currentSong {
PlayerView(song: currentSong)
}
}
// .popupInteractionStyle(.drag)
// .popupInteractionStyle(.drag)
.popupBarStyle(.prominent)
.popupBarProgressViewStyle(.top)
.popupBarMarqueeScrollEnabled(true)
}
}

struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
static var previews: some View {
MusicView(onDismiss: {})
}
}
2 changes: 1 addition & 1 deletion LNPopupUIExample/LNPopupUIExample/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).

// Create the SwiftUI view that provides the window contents.
let contentView = ContentView()
let contentView = SceneSelection()

// Use a UIHostingController as window root view controller.
if let windowScene = scene as? UIWindowScene {
Expand Down
54 changes: 54 additions & 0 deletions LNPopupUIExample/LNPopupUIExample/SceneSelection.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//
// SceneSelection.swift
// LNPopupUIExample
//
// Created by Leo Natan (Wix) on 9/2/20.
//

import SwiftUI

struct SceneSelection: View {
@State var musicSheetPresented: Bool = false
@State var mapSheetPresented: Bool = false

var body: some View {
NavigationView {
List {
Section(header: Text("Demo App").frame(height: 48, alignment: .bottom)) {
Button("Apple Music") {
musicSheetPresented.toggle()
}
.foregroundColor(Color(.label))
.fullScreenCover(isPresented: $musicSheetPresented, content: {
MusicView {
musicSheetPresented.toggle()
}
})
}
Section(header: Text("Custom Popup Bar")) {
Button("Custom Popup Bar with SwiftUI") {
mapSheetPresented.toggle()
}
.foregroundColor(Color(.label))
.fullScreenCover(isPresented: $mapSheetPresented, content: {
CustomBarMapView {
mapSheetPresented.toggle()
}
})
}
}
.listStyle(GroupedListStyle())
.navigationBarTitle("LNPopupUI")
.navigationBarTitleDisplayMode(.inline)
}
.navigationViewStyle(StackNavigationViewStyle())
.ignoresSafeArea()
}
}

struct SceneSelection_Previews: PreviewProvider {
static var previews: some View {
SceneSelection()

}
}
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ let package = Package(
],
dependencies: [
// .package(path: "../LNPopupController")
.package(url: "https://github.com/LeoNatan/LNPopupController.git", from: Version(stringLiteral: "2.10.4"))
.package(url: "https://github.com/LeoNatan/LNPopupController.git", from: Version(stringLiteral: "2.10.8"))
],
targets: [
.target(
Expand Down
18 changes: 18 additions & 0 deletions Sources/LNPopupUI/LNPopupUI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ public extension View {

/// Sets the popup bar style.
///
/// Setting a custom popup bar view will methis this modifier have no effect.
///
/// - Parameter style: The popup bar style.
func popupBarStyle(_ style: LNPopupBarStyle) -> some View {
return environment(\.popupBarStyle, style)
Expand All @@ -56,6 +58,22 @@ public extension View {
func popupBarMarqueeScrollEnabled(_ enabled: Bool) -> some View {
return environment(\.popupBarMarqueeScrollEnabled, enabled)
}

/// Sets a custom popup bar view, instead of the default system-provided bars.
///
/// If a custom bar view is provided, setting the popup bar style has no effect.
///
/// - Parameters:
/// - wantsDefaultTapGesture: Indicates whether the default tap gesture recognizer should be added to the popup bar.
/// - wantsDefaultPanGesture: Indicates whether the default pan gesture recognizer should be added to the popup bar.
/// - wantsDefaultHighlightGesture: Indicates whether the default highlight gesture recognizer should be added to the popup bar.
/// - popupBarContent: A closure returning the content of the popup bar custom view
func popupBarCustomView<PopupBarContent>(wantsDefaultTapGesture: Bool = true,
wantsDefaultPanGesture: Bool = true,
wantsDefaultHighlightGesture: Bool = true,
@ViewBuilder popupBarContent: @escaping () -> PopupBarContent) -> some View where PopupBarContent : View {
return environment(\.popupBarCustomBarView, LNPopupBarCustomView(wantsDefaultTapGesture: wantsDefaultTapGesture, wantsDefaultPanGesture: wantsDefaultPanGesture, wantsDefaultHighlightGesture: wantsDefaultHighlightGesture, popupBarCustomBarView: AnyView(popupBarContent())))
}
}

public extension View {
Expand Down

0 comments on commit 97d2650

Please sign in to comment.