elai950 / AlertToast

Create Apple-like alerts & toasts using SwiftUI
https://elai950.github.io/AlertToast/
MIT License
2.12k stars 191 forks source link

Wrong position of toast while displaying in sheet #5

Closed Rminsh closed 3 years ago

Rminsh commented 3 years ago

Describe the bug Toast will show in wrong position with hud display mode when using it in sheet. This bug appears only in iOS

To Reproduce Steps to reproduce the behavior:

  1. Define a view as sheet
  2. Add toast to it with hud display mode
  3. Call the toast to show

Expected behavior The Y Position of Toast should be much more below or even below the NavigationView (if is defined)

Screenshots IMG_0361

Smartphone:

Sample code:

import SwiftUI
import AlertToast

struct ContentView: View {

    @State private var showingDetail = false

    var body: some View {
        Button("Show Detail") {
            showingDetail.toggle()
        }
        .sheet(isPresented: $showingDetail) {
            NextView()
        }
    }
}

struct NextView: View {

    @State var showToast = false

    var body: some View {
        ScrollView {
            Button("Show Detail") {
                showToast.toggle()
            }
            .padding()
        }.toast(isPresenting: $showToast, duration: 3, tapToDismiss: true, alert: {
            AlertToast(
                displayMode: .hud,
                type: .systemImage("checkmark.circle.fill", .green),
                title: "Test",
                subTitle: "Some message")

        })
    }
}
elai950 commented 3 years ago

The .toast modifier should always be at the top of all view builders. Add a view builder (for example VStack) then implement the .toast on the vstack after the .sheet modifier. Try this:

var body: some View {
        VStack{
        Button("Show Detail") {
            showingDetail.toggle()
        }
        }
.sheet(isPresented: $showingDetail) {
            NextView()
        }
//Implement `.toast` here
    }
Rminsh commented 3 years ago

The .toast modifier should always be at the top of all view builders. Add a view builder (for example VStack) then implement the .toast on the vstack after the .sheet modifier. Try this:

var body: some View {
        VStack{
        Button("Show Detail") {
            showingDetail.toggle()
        }
        }
.sheet(isPresented: $showingDetail) {
            NextView()
        }
//Implement `.toast` here
    }

If I implement toast modifier in the Parent View, the toast will show up behind my sheet like this:

Screen Shot 2021-03-08 at 4 00 15 PM
import SwiftUI
import AlertToast

struct ContentView: View {

    @State var showToast = false
    @State private var showingDetail = false

    var body: some View {
        Button("Show Detail") {
            showingDetail.toggle()
        }
        .sheet(isPresented: $showingDetail) {
            childView
        }
        .toast(isPresenting: $showToast, duration: 3, tapToDismiss: true, alert: {
            AlertToast(
                displayMode: .hud,
                type: .systemImage("checkmark.circle.fill", .green),
                title: "Test",
                subTitle: "Some message")

        })
    }

    var childView: some View {
        ScrollView {
            Button("Show Detail") {
                showToast.toggle()
            }
            .padding()
        }
    }
}

So the correct way is to implement toast in the Child view and the Y Position should be based on the current view

elai950 commented 3 years ago

This is actually how AlertToast works. By receiving the Y position in the current view. Do not put '.toast' on Button, implement it on ViewBuilder, like Group.

'.sheet' can be on a button but it's not the same case for AlertToast.

0xifarouk commented 3 years ago

This is actually how AlertToast works. By receiving the Y position in the current view. Do not put '.toast' on Button, implement it on ViewBuilder, like Group.

'.sheet' can be on a button but it's not the same case for AlertToast.

This doesn't solve the problem, I have put the toast above the VStack in a Sheet, but the position still incorrect as @Rminsh showed.

iKK001 commented 3 years ago

...same here, this does not solve the problem (iOS 14.6)

It seems that .hud has a problem.

As Rminsh wrote "...to implement toast in the Child view..." works but unfortunately not for .hud.

What is the solution for .sheet and the need for a .hud type alert ??

elai950 commented 3 years ago

I've released a new version where you can manually offset the height until I'll find a better solution.

.toast(isPresenting: ...., offsetY: CGFloat)

Closing issue.