Giter Site home page Giter Site logo

leonatan / lnpopupui Goto Github PK

View Code? Open in Web Editor NEW
293.0 293.0 29.0 158.35 MB

A SwiftUI library for presenting views as popups, much like the Apple Music and Podcasts apps.

License: MIT License

Swift 98.41% Objective-C 0.21% Shell 1.38%
lnpopupcontroller lnpopupcontroller-framework popup spm swiftui swiftui-library

lnpopupui's Introduction

Hi there! 👋 My name is Léo and I am a software engineer from Ramat Gan, Israel

LeoNatan's github stats

lnpopupui's People

Contributors

aidewoode avatar hvrbyte avatar leonatan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lnpopupui's Issues

Gesture Conflict

Describe the Bug
When using other components (compactslider, https://github.com/buh/CompactSlider) with multiple gesture effects within popupContent, I've noticed conflicts between the events of LNPopupUI and those of the other components. While using .popupInteractionStyle(.none) can resolve the issue, it disables the ability to close the view by dragging. I'm quite puzzled. Do you have any valuable suggestions? Thank you very much for your time.

To Reproduce
Steps to reproduce the behavior:
I have submitted a case swiftUI repo that you can run if you have time. This repo can reproduce my problem.
👉 https://github.com/jiangdi0924/LNPopupUIGestureConflic

Expected Behavior
resolve gesture conflict

Screenshots
none

Additional Context
none

popupBarCustomView produces too much padding

Discussed in #39

Originally posted by dsk1306 April 12, 2024
I've been playing around with the library and noticed some strange behavior.

I've added a simple view with some content

var body: some View {
    Color.red
        .ignoresSafeArea(edges: [.top, .bottom])
        .popupCloseButtonStyle(.none)
        .popupInteractionStyle(.customizedSnap(percent: 0.5))
        .popup(
            isBarPresented: $coordinator.isBarPresented,
            isPopupOpen: $coordinator.isPopupOpen,
            onClose: { coordinator.onPopupClose?() },
            popupContent: { Text("test") }
        )
        .popupBarCustomView(wantsDefaultHighlightGesture: false) {
            VStack {
                Text("line 1")
                Text("line 2")
                Text("line 3")
            }
        }
}

and for some reason the hosting view adds quite a lot of vertical space around my content view.

Screenshot 2024-04-12 at 13 49 13
Screenshot 2024-04-12 at 13 49 22

I've tried to ignore safe area in custom view

.popupBarCustomView(wantsDefaultHighlightGesture: false) {
    VStack(spacing: .zero) {
        Text("line 1")
        Text("line 2")
        Text("line 3")
    }
    .ignoresSafeArea()
}

but it seems that the hosting view size stays the same

Screenshot 2024-04-12 at 13 58 28

Do you think it's possible to remove these paddings without breaking the layout logic?

LNPopupController: The popup controller is already in transition. Will ignore this transition request.

Nice repo very useful to me, much appreciated, i found a issue this is very confusing.
Describe the Bug
When audio is playing popup content view always change isPopupOpen status and open and close over and over again; the terminal show "LNPopupController: The popup controller is already in transition. Will ignore this transition request."

To Reproduce
Steps to reproduce the behavior:

  1. play audio file
  2. click popup bar
  3. drag down popup content view then the bug show

(i use this repo playing remote audio https://github.com/tanhakabir/SwiftAudioPlayer)

Simulator.Screen.Recording.-.iPhone.13.-.2021-12-24.at.22.34.48.mp4

iOS 15.2 has broken safe area insets under some conditions

See https://twitter.com/LeoNatan/status/1458388991666016257
This is an Apple bug, and FB9750551 has been opened:

iOS 15.2: SwiftUI.PlatformViewHost incorrectly calculates safe area insets for itself and its view hierarchy

Please provide a descriptive title for your feedback:
iOS 15.2: SwiftUI.PlatformViewHost incorrectly calculates safe area insets for itself and its view hierarchy
Which area are you seeing an issue with?
SwiftUI Framework
What type of feedback are you reporting?
Incorrect/Unexpected Behavior
Please describe the issue and what steps we can take to reproduce it:
On iOS 15.2, SwiftUI.PlatformViewHost incorrectly calculates safe area insets for itself and its view hierarchy.

I have attached an example project which reproduces the issue. In the example project, I add a UIHostingController, which has additionalSafeAreaInsets set to non-zero value. Further down the hierarchy, I have a UIViewRepresentable, which gets wrapped in a PlatformViewHost. The result is that the view in UIViewRepresentable gets an incorrect safeAreaInsets value.

This is a regression in iOS 15.2.

See screenshots from iOS 15.0 and iOS 15.2, where the issue is clear.

Possible regression between 1.4.0 and 1.4.1 in popupBarItems

Describe the Bug

When updating LNPopupView from 1.4.0 to 1.4.1, then the frame of popupBarItems' Button moves around.

To Reproduce

Change SPM from exact version 1.4.0 to exact version 1.4.1, then the behaviour manifests itself.

Expected Behavior

I guess I would expect the LoadingSpinnerView which is the button's content not to shift around like it does - while there is a rotation modifier on a view within that view, it does not contain anything that changes position or frame size. My workaround for now will be to stay on 1.4.0 but this isn't viable for when I ship, as LNPopupUI is maintained and will change and fix and improve over time leaving me behind.

Screenshots

Behaviour on 1.4.0:

Before.mov

Behaviour on 1.4.1:

After.mov

Additional Context

I am changing the button's content when the play state changes as follows:

.popupBarItems({
    Button(action: {
        playerViewModel.togglePlaying()
    }) {
         if playerViewModel.playerState == .loading {
            LoadingSpinnerView()
                 .frame(width: 35, height: 35)
                 .accentColor(.primary)
                 .padding(2)
                 .border(.pink)
        } else if playerViewModel.playbackState == .stopped || playerViewModel.playbackState == .paused {
            Image(systemName: "play.fill")
                .renderingMode(.template)
                .foregroundColor(.primary)
                .font(.title2)
                .padding(10)
        } else if playerViewModel.playbackState == .playing {
            Image(systemName: "pause.fill")
                .renderingMode(.template)
                .foregroundColor(.primary)
                .font(.title2)
                .padding(10)
        }
    }
})

Limiting dragging area

I'd like to be able to limit the draggable area when the popup is open. For instance, a small strip at the top of the popup will respond to dragging, but the rest of the view will not. Right now, with .popupInteractionStyle(.drag), the entire popup view is draggable.

Is there a way to limit the draggable area, either on the library side or the app side?

Can't build test target while using LNPopupUI

Describe the Bug
I'm using LNPopupUI as a SPM dependency in my project, added through Xcode. I have my target set up so that it adds LNPopupUI-Static (not sure if this is the intended way). When I try to build tests for my target, I get a failure
<unknown>:0: error: missing required module 'LNPopupController_ObjC'

To Reproduce
Steps to reproduce the behavior:

  1. add LNPopupUI to your target
  2. import LNPopupUI and attach popup to ContentView content
  3. build and run tests
  4. See error

Expected Behavior
Test bundle should build and run tests

Additional Context
I've uploaded an example that reproduces the issue here

State management breaks on quick opening/closing of the popup

Describe the Bug:

When interacting with the LNPopupUI in my SwiftUI application, specifically when the audio is playing and I either drag down the popup or click the close button on the popup, the tab view and popup view turn black. The audio continues to play as expected, but the visual elements of the popup and tab view do not render correctly.

To Reproduce:

Steps to reproduce the behavior:

  1. Start audio playback in the app using LNPopupUI.
  2. Interact with the popup by either dragging it down or clicking the close button.
  3. Observe that the tab view and popup view turn black while the audio continues to play.

Expected Behavior:

The popup and tab view should maintain their proper visual appearance when interacted with, without turning black, while allowing the audio to continue playing.

Screenshots:

RPReplay_Final1702224398.MP4

Additional Context:

  • The issue occurs in a SwiftUI application.
  • Using LNPopupUI for popup management.
  • The problem seems related to view rendering and state management in conjunction with LNPopupUI.
  • The issue is consistently reproducible under the described conditions.

Environment:

  • SwiftUI version: 5
  • LNPopupUI version: 1.7.0
  • iOS version: 17.1.2
  • Xcode version: 15.0.1 (15A507)
  • Device/Emulator type and iOS version: iPhone 11

Unable to change text attributes in .popupBarCustomizer

Describe the Bug

The documentation states that we can use the .popupBarCustomizer modifier to change the appearance of the title and subtitle, but that does not seem to actually work since the Swift compiler throws an error stating that we can not assign a value of type [AnyHashable: NSObject] to type AttributeContainer.

I am specifically trying to change the color
To Reproduce
Steps to reproduce the behavior:

  1. Modify PlayerView in the MusicScene and add the following (from the README)
     .popupBarCustomizer { popupBar in
      let paragraphStyle = NSMutableParagraphStyle()
      paragraphStyle.alignment = .right
      paragraphStyle.lineBreakMode = .byTruncatingTail

      popupBar.standardAppearance.backgroundEffect = UIBlurEffect(style: .dark)
      popupBar.standardAppearance.titleTextAttributes = [ .paragraphStyle: paragraphStyle, .font: UIFont(name: "Chalkduster", size: 14)!, .foregroundColor: UIColor.yellow ]
      popupBar.standardAppearance.subtitleTextAttributes = [ .paragraphStyle: paragraphStyle, .font: UIFont(name: "Chalkduster", size: 12)!, .foregroundColor: UIColor.green ]

      popupBar.tintColor = .yellow
    }

  1. Build the project.
  2. We get the error: "Cannot assign value of type '[AnyHashable : NSObject]' to type 'AttributeContainer'"

Expected Behavior
To be able to set the titleTextAttributes and subTitleTextAttributes

Screenshots

These are the errors above and where I put the customizer
Screenshot 2024-07-02 at 21 54 48

Additional Context

I also tried to use a typed dictionary, but it leads to the same error

Screenshot 2024-07-02 at 22 03 23

Since it clearly does not accept a dictionary I also tried using an AttributeContainer, but then I get "Undefined symbol: (extension in LNPopupController):__C.LNPopupBarAppearance.titleTextAttributes.setter : Foundation.AttributeContainer?
"

Screenshot 2024-07-02 at 22 05 49

As a final attempt, I also tried using the .popupBarTitleTextAttributes modifier, but although that does build and run it does not actually change the font or text color

Screenshot 2024-07-02 at 22 11 23

Please let me know if I am doing something incorrect here.

Adding title / subtitle to the popup.

I am trying to add title and subtitle but it doesn't work .


   .popup(isBarPresented: $isBarPresented, isPopupOpen: $isPopupOpen) {
         
            
        }
        
        .popupImage(Image(systemName: "person"))
        .popupTitle("1356")
        .popupCloseButtonStyle(.chevron)
        .popupInteractionStyle(.drag)

PlayerView question

Hi @LeoNatan ,

I am trying to replace this:

     .popupImage(Image(song.imageName).resizable())

by:

     let image = Image(song.imageName).resizable()
     .popupImage(image)

to use the same image reference elsewhere.

I get the following error:

Variable used within its own initial value

What am i doing wrong, please?

Thanks,

Updating popup content while popup is closing causes popup to get stuck in a loop of closing and opening endlessly.

Describe the Bug
If while the popup is animating to close, the popup's internal content changes, it will get stuck in an endless loop of closing and opening again.

To Reproduce
I have created another extremely basic SwiftUI app to show this bug, https://pastie.io/lgfkwf.swift xD

  1. Swipe to open popup
  2. Swipe to close popup and while its closing, click the "Update Popup Content" button

Expected Behavior
Popup would not open when content changes while closing the popup

Screenshots
Demo App Bug:
https://github.com/LeoNatan/LNPopupUI/assets/40129637/cc17f6d8-7b4d-48d5-8c1e-1e4b4e898af4

popup bar and popup content can get stuck in wrong position when dismissing a modal sheet with the keyboard in a transitory state

This probably needs to be done on LNPopupController, but I'm posting it here for now since I'm using LNPopupUI.

If the keyboard comes out, the position of the popup bar will move to be on top of the keyboard. Is there a way to prevent this behavior so the popup bar stays fixed behind the keyboard. It seems the moving can cause certain bugs where the bar gets stuck in the wrong position as in the attached video. It can get stuck in even worse positions where opening the popup will not fix it.

Even if you need to keep this behavior, maybe there is some easy way to prevent it from within LNPopupController, so that I can make the change just for my case?

keyboard.mp4

Change color of now playing bar background

Hey. Thanks for the great swift UI package! Ive been trying to update the background color of the now playing bar, it seems to only show gray behind a custom not playing bar. I've used
.popupBarBackgroundEffect(nil) .popupBarBackgroundStyle(nil)

But neither have changed the background color (Ideally to clear)

Thanks!

Inconsistent Scrolling in PopupView

Hi,
Quick question regarding some inconsistent scrolling I'm running into using the LNPopUp UI.

Goal: Add a horizontally paging view in the popup view
What I've Tried: I've made the following changes to the demo project to accomplish this:


//SafeAreaDemoView(colorSeed: "Popup", offset: true, isPopupOpen: isPopupOpen)
      ScrollView {
      TabView {
        SafeAreaDemoView(colorSeed:  "tab_0" )
        SafeAreaDemoView(colorSeed:  "tab_1" )
        SafeAreaDemoView(colorSeed:  "tab_2" )
        SafeAreaDemoView(colorSeed:  "tab_3" )
      }
      .frame(
          width: UIScreen.main.bounds.width ,
          height: UIScreen.main.bounds.height
      )
      .tabViewStyle(PageTabViewStyle(indexDisplayMode: .always))
      .indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .always))
      }.edgesIgnoringSafeArea(.all)
        .popupTitle(demoContent.title, subtitle: demoContent.subtitle)
        .popupImage(Image("genre\(demoContent.imageNumber)"))

What I expect to happen:

  • Be able to swipe up to reveal popup view
  • Be able to swipe left/right within the popup view

What happens: Swiping horizonatally works occasionally, however about 30% of touches get lost. Also, the PopUpUI sporadically closes following some of the swipes. It seems like the gesture recognizer might be a bit too sensitive in the vertical direction. Horizontal swiping works most consistently when you swipe diagonally up+left or up+right

Visual of changes:
Screen Shot 2021-05-01 at 7 47 24 PM

Popover's background Scale Effect

In standard modalViews of SwiftUI like .sheet & .popover, You'll notice that when the modal view is presented the view behind kind of scales down & moves outwards ...
It's just a nice pre-canned touch only for .sheet & .popover provided by apple with probably their own private APIs.

I wanted to know if it is deployable to the project to add to it's sweetness?

RPReplay_Final1704230334

I think apple had used a simple .fullScreenCover for the popup action ... but they also have included this touch to it which isn't seen in a standard fullScreenCover in SwiftUI

Using a custom view for the popup bar breaks presentation/dismiss animations

Describe the Bug
When using a custom view for the popup bar, the presentation and dismiss animations do not appear correctly.
This is happening on the iOS 15.4 simulator and device using the latest version of Xcode (13.3.1).

To Reproduce

  1. In the example project, modify the MusicScene to use a custom popup bar (see code block below for the one I used).
  2. Present the popup bar by clicking on a track.
  3. Notice the presentation animation starts higher than where it finishes and slides down to attach itself to the bottom safe area guide.
  4. This happens with and without using a TabView.

Expected Behavior
The animation should behave the same as when using the built-in popup bars.

Screenshots
LNPopupUI-CustomView

Additional Context
Thanks for the amazing library! This is the modified custom popup bar from the MapScene that I used:

    .popupBarCustomView(wantsDefaultTapGesture: false, wantsDefaultPanGesture: false, wantsDefaultHighlightGesture: false) {
      ZStack(alignment: .trailing) {
        HStack {
          Button("Dismiss Bar") { isPopupBarPresented = false }
          Spacer()
          Button(action: {
            isPopupOpen.toggle()
          }, label: {
            Image(systemName: "chevron.up")
              .renderingMode(.template)
          })
        }
        .padding()
      }
    }

Can't make custom popup close button.

import SwiftUI
import LNPopupUI

struct AppetizerTabView: View {
    
    @State var isPopupOpen: Bool = false 
    
    var body: some View {
        TabView{
            AppetizerListView()
                .tabItem {
                    Image(systemName: "house")
                    Text("Home")
                }
            AccountView()
                .tabItem {
                    Image(systemName: "person")
                    Text("Account")
                }
            
            OrderView()
                .tabItem {
                    Image(systemName: "bag")
                    Text("Home")
                }
        }
        
        .popup(isBarPresented: .constant(true) , isPopupOpen: $isPopupOpen , popupContent: {
            Button(action: {
                self.isPopupOpen.toggle()
            }, label: {
                Image(systemName: "info.circle")
                    .resizable()
                    .frame(width: 30, height: 30)
                    .foregroundColor(Color(.lightGray))
            })
        })
        
        .popupInteractionStyle(.drag)
        .popupBarCustomView(wantsDefaultTapGesture: false, wantsDefaultPanGesture: true, wantsDefaultHighlightGesture: false) {
            HStack(spacing: 24){
                Text("Choose any user to\ndisplay coding activity")
                    .font(.system(size: 16, weight: .light))
                    .foregroundColor(.black)
                    .frame(height: 40)
                    .lineLimit(nil)
                    .multilineTextAlignment(.center)
                    .padding(10)
                    .padding(.leading)
                Button(action: {
                    self.isPopupOpen.toggle()
                }, label: {
                    Image(systemName: "info.circle")
                        .resizable()
                        .frame(width: 30, height: 30)
                        .foregroundColor(Color(.black))
                })
            }
        }
    }
}

After adding .popupBarStyle(.prominent) or .popupBarProgressViewStyle(.top) or .popupBarMarqueeScrollEnabled(true) to the View hierarchy, iOS keyboard will resign after single keypress

Describe the Bug
using any or all of these modifiers will interfere with the first responder:

        .popupBarStyle(.prominent)
        .popupBarProgressViewStyle(.top)
        .popupBarMarqueeScrollEnabled(true)

NOTE
.popup() alone does NOT interfere with first responder.

when entering text in another TabView's TextField, the keyboard will resign after every key press.

To Reproduce
Steps to reproduce the behavior:

  1. add any or all of:
    .popupBarStyle(.prominent)
    .popupBarProgressViewStyle(.top)
    .popupBarMarqueeScrollEnabled(true)
  2. enter text in a TextField
  3. Observe the keyboard resigning after first keypress

Expected Behavior
Keyboard/first responder does not resign

Screenshots
Made a video.

Additional Context
none

RPReplay_Final1661400494.MP4

Minimal Example Crashes on Load

A minimal example is crashing on load

Xcode 11.6
LNPopupUI 1.0.2
LNPopupController 2.10.1
iOS Deployment Target 13.5
Swift version 5.2.4 (swiftlang-1103.0.32.9 clang-1103.0.32.53)
Target: x86_64-apple-darwin19.4.0

Here's the reproducible case:

ContentView.swift

import SwiftUI
import LNPopupUI


struct BasicView: View {
    
    var body: some View {
        VStack {
            Text("Hello, world!")
        }
        .popupTitle("Hi")
        .popupImage("heart")
        .popupProgress(0.5)
        .popupBarItems(leading: {
            HStack(spacing: 20) {
                Button(action: {}) {
                    Image(systemName: "pause.fill")
                }
            }
        }, trailing: {
            HStack(spacing: 20) {
                Button(action: {
                    print("Next")
                }) {
                    Image(systemName: "forward.fill")
                }
            }
        })
    }
}

struct ContentView: View {
    @State var selectedTabIndex: Int = 2
    
    @State var isPopupPresented: Bool = true
    @State var isPopupOpen: Bool = false
    
    
    var body: some View {
        TabView(selection: self.$selectedTabIndex) {
            
            Text("First View").tabItem {
                VStack {
                    Text("Tab 1")
                    Image(systemName: "list.bullet")
                }
                
            }.tag(1)
            Text("Second View").tabItem {
                VStack {
                    Text("Tab 2")
                    Image(systemName: "rectangle.stack")
                }
            }.tag(2)
        }        .popup(isBarPresented: $isPopupPresented, isPopupOpen: $isPopupOpen) {
                    BasicView()
                }
                .popupBarStyle(.prominent)
                .popupBarProgressViewStyle(.top)
                .popupBarMarqueeScrollEnabled(true)
        
    }
    
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Crashes with:
crash

Am I missing a required component, or is this a bug?

Making isBarPresented = true, while its animating closed when set to false causes the popup to become bugged until open/closed again

Describe the Bug
When hiding the popup if the popup is unhidden during the hide animation, it will become bugged and will not show again until it is first shown then closed again, then shown again

To Reproduce
I have created a extremely basic SwiftUI app to show this bug, https://pastie.io/ukxbjx.swift

  1. Open the popup by clicking on it, or by scrolling up on it
  2. Click the button in the popup to close it
  3. While its animating closed click the button on the main screen to show it again

Expected Behavior
When clicking the button

while its animating closed, the animation would be stopped, and it would re-open

Screenshots
Demo App Bug:
https://github.com/LeoNatan/LNPopupUI/assets/40129637/03099756-1656-4b0f-a759-913bdeb9a6e8
Prod App Bug:
https://github.com/LeoNatan/LNPopupUI/assets/40129637/0b23cd29-c8c4-4048-85b4-219a95f67e0d

Extra Bug: I have not been able to replicate it, or understand what causes it however, so I do not have a demo app version.
Sometimes when closing it can get stuck in a loop of infinitely closing and opening the popup.

Prod App Extra Bug:
https://github.com/LeoNatan/LNPopupUI/assets/40129637/9a8edf3b-ce99-4aac-8375-e618051e9832

Run the example project

Hello,

After downloading and trying to run I have the error:

Swift package target 'LNPopupUI' is linked as a static library by 'LNPopupUIExample' and 'LNPopupUI', but cannot be built dynamically because there is a package product with the same name.

Thanks for help!

popupImage(image: from Image

There are 2 call signatures for .popupImage

popupImage(systemName: String) -> some View

and

func popupImage(_ name: String, bundle: Bundle? = nil) -> some View

Which work great when the image is loaded from the file system.

Could another signature be added that directly accepts an Image to more easily support e.g. images loaded from URLs?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.