如何关闭一个工作表并从 ContentView 启动另一个工作表?

问题描述 投票:0回答:2

对于我的应用程序,我有一个欢迎屏幕,介绍应用程序的功能并允许用户创建他们的第一个项目。当用户单击按钮时,我想关闭“welcomeScreen”工作表,然后启动“newRemindr”工作表。

我尝试通过创建一个可观察对象并将“addNewTrigger”布尔值设置为 false 来实现此目的。当我单击welcomeScreen 上的“添加新提醒”按钮时,该按钮的操作会导致welcomeScreen 关闭并将“addNewTrigger”布尔值切换为True。 (我已经验证这适用于打印报表)。然而,内容视图正在监听相同的观察对象来启动“newRemindr”表,但该操作似乎不起作用。

有人可以看一下代码,看看我哪里出错了吗?或者建议一个可以提供该类型功能的替代方案。

下面的代码...

欢迎屏幕:

import SwiftUI
import Combine

struct welcomeScreen: View {
    @Environment(\.presentationMode) var mode: Binding<PresentationMode>

    @ObservedObject var addNewReminder = showAddScreen()

    var body: some View {
        NavigationView {
            ZStack (alignment: .center) {

                LinearGradient(gradient: Gradient(colors: [Color.white, Color.white, Color.gray]), startPoint: .top, endPoint: .bottom)
                    .edgesIgnoringSafeArea(.all)

                Image("Ellipse2")
                    .offset(y: -475)

                VStack {
                    Spacer()
                    Text("Welcome to")
                        .foregroundColor(.white)
                        .fontWeight(.bold)
                    Image("RemindrLogoWhite")
                    Spacer()
                    Text("What is remindr?")
                        .font(.title)
                        .fontWeight(.bold)
                        .padding(.bottom, 25)
                    Text("Remindr is a simple app designed to help you schedule random reminders with the goal of clearing your mind.\n\nRemind yourself to check in with your body, set up positive affirmations, set your intentions; Whatever it is, the power is up to you.")
                        .padding(.horizontal, 25)
                        .padding(.bottom, 25)
                    Text("Click below to get started:")
                        .fontWeight(.bold)

                    // Add New Reminder Button
                    Button(action: {
                        self.mode.wrappedValue.dismiss()
                        print("Add Reminder Button from Welcome Screen is Tapped")
                        self.addNewReminder.addNewTrigger.toggle()
                        print("var addNewTrigger has been changed to \(self.addNewReminder.addNewTrigger)")
                    }) {
                        Image("addButton")
                            .renderingMode(.original)
                    }.padding(.bottom, 25)

                    Spacer()

                } .frame(maxWidth: UIScreen.main.bounds.width,
                         maxHeight: UIScreen.main.bounds.height)
            }
            .navigationBarTitle(Text(""), displayMode: .automatic)
            .navigationBarItems(trailing: Button(action: {
                self.mode.wrappedValue.dismiss()

            }, label: {
                Image(systemName: "xmark")
                    .foregroundColor(.white)
            }))
        }
    }
}

内容视图:

import SwiftUI
import CoreData

class showAddScreen: ObservableObject {
    @Published var addNewTrigger = false
}

struct ContentView: View {
    @Environment(\.managedObjectContext) var moc
    @FetchRequest(entity: ReminderEntity.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \ReminderEntity.dateCreated, ascending: false)])
    var reminder: FetchedResults<ReminderEntity>
    
    // Sheet Control
    @ObservedObject var addNewReminder = showAddScreen()
    //@State private var showingAddScreen = false
    @State var showWelcomeScreen = false
        
    let emojiList = EmojiList()

    //Toggle Control
    @State var notifyOn = true
    
    // Save Items Function
    func saveItems() {
        do {
            try moc.save()
        } catch {
            print(error)
        }
    }
    
    // Delete Item Function
    func deleteItem(indexSet: IndexSet) {
        let source = indexSet.first!
        let listItem = reminder[source]
        moc.delete(listItem)
    }
    
    // View Controller
    var body: some View {
        VStack {
            NavigationView {
                ZStack (alignment: .top) {
                    
                    // List View
                    List {
                        ForEach(reminder, id: \.self) { notification in
                            NavigationLink(destination: editRemindr(reminder: notification,
                                                                    notifyOn: notification.notifyOn,
                                                                    emojiChoice: Int(notification.emojiChoice),
                                                                    notification: notification.notification ?? "unknown",
                                                                    notes: notification.notes ?? "unknown")) {
                                // Text within List View
                                HStack {
                                    // MARK: TODO
                                    //Toggle("NotifyOn", isOn: self.$notifyOn)
                                    //    .labelsHidden() // Hides the label/title
                                    Text("\(self.emojiList.emojis[Int(notification.emojiChoice)]) \(notification.notification!)")
                                } 
                            }
                        } 
                        .onDelete(perform: deleteItem)
                        }.lineLimit(1)
                        
                        // Navigation Items
                        .navigationBarTitle("", displayMode: .inline)
                        .navigationBarItems(
                            leading:
                            HStack {
                                
                                Button(action: {
                                    self.showWelcomeScreen.toggle()
                                }) {
                                    Image(systemName: "info.circle.fill")
                                        .font(.system(size: 24, weight: .regular))
                                }.foregroundColor(.gray)
                                
                                // Positioning Remindr Logo on Navigation
                                Image("remindrLogoSmall")
                                    .resizable()
                                    .aspectRatio(contentMode: .fit)
                                    //.frame(width: 60, height: 60, alignment: .center)
                                    .padding(.leading, 83)
                                    .padding(.top, -10)
                            },
                            
                            // Global Settings Navigation Item
                            trailing: NavigationLink(destination: globalSettings()){
                                Image("settings")
                                    .font(Font.title.weight(.ultraLight))
                            }.foregroundColor(.gray)
                    )
                    
                    // Add New Reminder Button
                    VStack {
                        Spacer()
                        Button(action: { self.addNewReminder.addNewTrigger.toggle()
                        }) {
                            Image("addButton")
                                .renderingMode(.original)
                        }
                        .sheet(isPresented: $addNewReminder.addNewTrigger) {
                            
                            newRemindr().environment(\.managedObjectContext, self.moc)
                            
                        }
                    }
                }
            }  .sheet(isPresented: $showWelcomeScreen) {
                welcomeScreen()
            }
        }
    }
}
swift swiftui
2个回答
2
投票

首先我看到的是,您在两个视图中使用不同可观察对象,但应该使用相同的对象,因此在一个视图中所做的更改也可用于第二个视图。

这里有一个解决这个问题的方法

struct welcomeScreen: View {
@Environment(\.presentationMode) var mode: Binding<PresentationMode>

@ObservedObject var addNewReminder: showAddScreen // << declare to be injected

// ... other code

并在

ContentView

}  .sheet(isPresented: $showWelcomeScreen) {
    welcomeScreen(addNewReminder: self.addNewReminder)    // << inject !!
}

替代方案:您可以从

addNewReminder
中删除
welcomeScreen
,并仅在
ContentView
中使用它,方法是在欢迎表上激活关闭,例如

}  .sheet(isPresented: $showWelcomeScreen, onDismiss: {
              // it is better to show second sheet with delay to give chance
              // for first one to animate closing to the end
              DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                 self.addNewReminder.addNewTrigger.toggle()
              }
          }
   ) {
    welcomeScreen()
}

0
投票
不再需要

DispatchQueue.main.asyncAfter
来允许两个工作表屏幕之间的事务。

.sheet(isPresented: $showWelcomeScreen, onDismiss: {
      // change toggle to open another sheet screen        
      self.addNewReminder.addNewTrigger.toggle()
})

这样更干净。

© www.soinside.com 2019 - 2024. All rights reserved.