【问题标题】:SwiftUI Reload View after dismissing a sheet关闭工作表后 SwiftUI 重新加载视图
【发布时间】:2020-05-23 10:53:32
【问题描述】:

我在 UserDefaults 中有一个布尔值来检查用户是否登录。 在我的第一页中,我有一个标题,当用户单击个人资料图片时,它会显示一个模式(使用 .sheet),并且在其中我有一个供用户注销的按钮。

当用户按下注销按钮并关闭模式时,如何更改视图?

或者在用户单击 LogOut 按钮并关闭模式以检查新的 Bool 值后,我如何重新加载主页?

struct Home: View {

    var body: some View {
        ScrollView {
            VStack {   
                // MARK: Header
                Header(title: "Home")    
            }
            Spacer()
        }
        .padding(20)
    }
}

struct Header: View {

    public var title: String = ""
    @State private var showProfile = false

    var body: some View {
        HStack {
            // MARK: - User Profile
            Image("profile")
                .resizable()
                .clipShape(Circle())
                .frame(width: 50, height: 50)
                .onTapGesture {
                    print("⚠️ Profile has been tapped.")
                    self.showProfile.toggle()
            }
            .sheet(isPresented: $showProfile) {
                Account(showProfile: self.$showProfile)
            }

        }
    }
}

struct Account: View {

    @Binding var showProfile: Bool

    var body: some View {
        NavigationView {

            // MARK: - Account Sections
            List {

                // MARK: - Log Out -
                Section {
                    Button(action: {
                        print("❌ User has been logged out.")
                        self.showProfile.toggle()

                    }) {
                        Text("Log Out")
                            .bold()
                            .foregroundColor(.red)
                    }
                }
            }

                // MARK: - NavigationBar Settings
                .navigationBarTitle("Account", displayMode: .inline)
        }
    }
}

这是我的 UserDefault 类

class UsersSettings: ObservableObject {

    @Published var isLoggedIn: Bool = UserDefaults.standard.bool(forKey: "isLogged") {
        didSet {
            UserDefaults.standard.set(self.isLoggedIn, forKey: "isLogged")
            print(UserDefaults.standard.bool(forKey: "isLogged"))
        }
    }
}

【问题讨论】:

  • 您有没有为此找到解决方案?我有一个类似的问题,当查看工作表然后关闭列表中包含项目的列表视图时,现在是空白的。所以我需要知道当工作表被关闭时如何强制 ListView 刷新?
  • @Learn2Code in this video,我注意到这个人做了我正在寻找的事情,在检查之后我注意到这个人使用了一个叫做“NotificationCenter”的东西,我也做了同样的事情,现在它正在工作为了我。您可以在here了解更多关于通知中心的信息

标签: ios xcode swiftui


【解决方案1】:

很难说,你的目标是什么。也许这将满足您的要求 1)当用户点击图像时,工作表出现 2) 用户可以登录或退出,或者简单地用向下滑动手势关闭工作表 3) 用户图像反映登录/退出状态

import SwiftUI

class LoginModel: ObservableObject {
    @Published var loggedIn = false
}

let loginModel = LoginModel()

struct ContentView: View {
    @ObservedObject var model = loginModel
    var body: some View {
        ScrollView {
            VStack {
                // MARK: Header
                Header(title: "Home", loggedIn: model.loggedIn)
            }
            Spacer()
        }
        .padding(20)
    }
}

struct Header: View {

    public var title: String = ""
    var loggedIn: Bool
    @State private var showProfile = false
    var body: some View {
        HStack {
            // MARK: - User Profile
            Image(systemName: loggedIn ? "photo.fill.on.rectangle.fill" : "photo.on.rectangle")
                .resizable()
                .clipShape(Circle())
                .frame(width: 50, height: 50)
                .onTapGesture {
                    self.showProfile.toggle()
            }
            .sheet(isPresented: $showProfile) {
                Account(showProfile: self.$showProfile)
            }

        }
    }
}

struct Account: View {

    @Binding var showProfile: Bool
    @ObservedObject var model = loginModel

    var body: some View {
        NavigationView {
            List {
                Section {
                    Button(action: {
                        self.model.loggedIn.toggle()
                        self.showProfile.toggle()

                    }) {
                        Text(model.loggedIn ? "Log Out": "Log In")
                            .bold()
                            .foregroundColor(.red)
                    }
                }
            }
            .navigationBarTitle("Account", displayMode: .inline)
        }
    }
}

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

结果看起来像

【讨论】:

  • 当用户单击注销按钮时,我试图再次向用户显示登录页面(这将在第一次午餐时显示)。在你的代码中,我想检查 ContentView() 上的 UserDefault 值是否为 true 显示主视图,如果为 false 则显示登录视图,当用户单击注销时关闭工作表并显示登录视图
  • @user3441734 你有没有找到解决方案?我有一个类似的问题,当查看工作表然后关闭列表中包含项目的列表视图时,现在是空白的。所以我需要知道当工作表被关闭时如何强制 ListView 刷新?
  • @Learn2Code 解决方案是什么?我的答案中的代码按预期工作(如上所述)老实说,我不理解“arata”的通知......复制 - 粘贴 - 运行此代码,您会看到列表中的值根据需要更新。跨度>
  • @user3441734 你能去看看我的问题吗:stackoverflow.com/questions/60662263/…
【解决方案2】:

UserSettings 是事实的来源,必须在您的工作表模式视图中使用 (Account)。

在 Home 或 Header 视图中添加到此对象的绑定以观察更改并相应地更新您的界面。

你像这样声明一个对象绑定:

struct Home: View {
  @ObservedObject var userSettings: UserSettings
  // ...
}

然后你观察到这样的变化:

struct Home: View {
  // ...  
  var body: some View {
    if userSettings.isLoggedIn {
      Text("User is logged in")
    } else {
      Text("User is not logged in")
    }
  } 
}

为此,您必须在您的 Active 视图中注销用户。

【讨论】:

  • 它没有改变任何东西,我仍然需要关闭应用程序并重新打开它才能看到变化
【解决方案3】:

【讨论】:

  • 这被否决了,因为它是一个仅链接的答案,可能会过时,然后答案对任何人都没有帮助。
猜你喜欢
  • 2023-01-12
  • 2021-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-04
  • 1970-01-01
  • 2020-09-28
  • 2022-01-01
相关资源
最近更新 更多