Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use multiple fullScreenCover in IOS14

Tags:

swiftui

ios14

I want to present the two destinations view in full screen mode from a single view. Below is a sample of my code. Seem that the function only works for single presentation, if I have a second fullScreenCover defined, the first fullScreenCover didn't work properly.Is that any workaround at this moment?

import SwiftUI

struct TesFullScreen: View {
    

    
    init(game : Int){
        print(game)
    }

    
    var body: some View {
        Text("Full Screen")
    }
}

ContentView

 import SwiftUI
    struct ContentView: View {
        
        @State var showFullScreen1 : Bool = false
        @State var showFullScreen2 : Bool = false
        
        var body: some View {
            NavigationView {
                VStack {
                    Spacer()
                    Button(action: { self.showFullScreen1 = true }) {
                        Text("Show Full Screen 1")
                    }
                    Button(action: { self.showFullScreen2 = true }) {
                        Text("Show Full Screen 2")
                    }
                    Spacer()
                }
                .navigationBarTitle("TextBugs", displayMode: .inline)
            }
            .fullScreenCover(isPresented: self.$showFullScreen1){
                TesFullScreen(game: 1)
            }
            .fullScreenCover(isPresented: self.$showFullScreen2){
                TesFullScreen(game: 2)
            }
        }
    }
like image 241
BellRinging Avatar asked Sep 25 '20 02:09

BellRinging


3 Answers

Not always the accepted answer works (for example if you have a ScrollView with subviews (cells in former days) which holds the buttons, that set the navigational flags).

But I found out, that you also can add the fullScreen-modifier onto an EmptyView. This code worked for me:

   // IMPORTANT: Has to be within a container (e.g. VStack, HStack, ZStack, ...)

   if myNavigation.flag1 || myNavigation.flag2 {

      EmptyView().fullScreenCover(isPresented: $myNavigation.flag1)
      { MailComposer() }

      EmptyView().fullScreenCover(isPresented: $myNavigation.flag2)
      { RatingStore() }
    }
like image 99
LukeSideWalker Avatar answered Nov 20 '22 14:11

LukeSideWalker


Usually some same modifier added one after another is ignored. So the simplest fix is to attach them to different views, like

struct FullSContentView: View {

    @State var showFullScreen1 : Bool = false
    @State var showFullScreen2 : Bool = false

    var body: some View {
        NavigationView {
            VStack {
                Spacer()
                Button(action: { self.showFullScreen1 = true }) {
                    Text("Show Full Screen 1")
                }
                .fullScreenCover(isPresented: self.$showFullScreen1){
                    Text("TesFullScreen(game: 1)")
                }

                Button(action: { self.showFullScreen2 = true }) {
                    Text("Show Full Screen 2")
                }
                .fullScreenCover(isPresented: self.$showFullScreen2){
                    Text("TesFullScreen(game: 2)")
                }
                Spacer()
            }
            .navigationBarTitle("TextBugs", displayMode: .inline)
        }
    }
}

Alternate is to have one .fullScreenCover(item:... modifier and show inside different views depending on input item.

like image 5
Asperi Avatar answered Nov 20 '22 15:11

Asperi


The only thing that worked for me was the answer in this link:

https://forums.swift.org/t/multiple-sheet-view-modifiers-on-the-same-view/35267

Using the EmptyView method or other solutions always broke a transition animation on one of the two presentations. Either transitioning to or from that view and depending on what order I chose them.

Using the approach by Lantua in the link which is using the item argument instead of isPresented worked in all cases:

enum SheetChoice: Hashable, Identifiable {
  case a, b

  var id: SheetChoice { self }
}

struct ContentView: View {
  @State var sheetState: SheetChoice?

  var body: some View {
    VStack {
      ...
    }
    .sheet(item: $sheetState) { item in
      if item == .a {
        Text("A")
      } else {
        Text("B")
      }
    }
  }
}

The sheetState needs to be optional for it to work.

like image 2
alionthego Avatar answered Nov 20 '22 14:11

alionthego