[英]Navigation Bar Items with @EnvironmentObject
I would like to create a Settings
view using SwiftUI.我想使用 SwiftUI 创建一个Settings
视图。 I mainly took the official example from Apple about SwiftUI to realize my code.我主要是拿苹果官方关于SwiftUI的例子来实现我的代码。 The settings view should have a toggle to whether display or not my favorites items.设置视图应该可以切换是否显示我的收藏夹项目。
For now I have a landmarks list and a settings view.现在我有一个地标列表和一个设置视图。
struct Landmark: Hashable, Codable, Identifiable {
var id: Int
var imageName: String
var title: String
var isFavorite: Bool
var description: String
enum CodingKeys: String, CodingKey {
case id, imageName, title, description
}
}
final class UserData: ObservableObject {
@Published var showFavoriteOnly: Bool = false
@Published var items: [Landmark] = landmarkData
@Published var showProfile: Bool = false
}
struct ItemList: View {
@EnvironmentObject var userData: UserData
@State var trailing: Bool = false
init() {
UITableView.appearance().separatorStyle = .none
}
var body: some View {
NavigationView {
List {
VStack {
CircleBadgeView(text: String(landmarkData.count), thickness: 2)
Text("Tutorials available")
}.frame(minWidth:0, maxWidth: .infinity)
ForEach(userData.items) { landmark in
if !self.userData.showFavoriteOnly || landmark.isFavorite {
ZStack {
Image(landmark.imageName)
.resizable()
.frame(minWidth: 0, maxWidth: .infinity)
.cornerRadius(10)
.overlay(ImageOverlay(text: landmark.title), alignment: .bottomTrailing)
Text(String(landmark.isFavorite))
NavigationLink(destination: TutorialDetailView(landmark: landmark)) {
EmptyView()
}.buttonStyle(PlainButtonStyle())
}
}
}
}.navigationBarTitle("Tutorials")
.navigationBarItems(trailing: trailingItem())
}
}
}
extension ItemList {
func trailingItem () -> some View {
return HStack {
if userData.showProfile {
NavigationLink(destination: ProfileView()) {
Image(systemName: "person.circle")
.imageScale(.large)
.accessibility(label: Text("Profile"))
}
}
NavigationLink(destination: SettingsView().environmentObject(userData)) {
Image(systemName: "gear")
.imageScale(.large)
.accessibility(label: Text("Settings"))
}
}
}
}
As you can see my SettingsView
is accessible from navigationBarItems
of my NavigationView.如您所见,可以从我的 NavigationView 的navigationBarItems
访问我的SettingsView
。 I don't know if it's the problem or not but when I put the Toggle inside the ListView
it works as expected.我不知道这是否是问题所在,但是当我将 Toggle 放入ListView
它会按预期工作。 But now when I trigger the toggle to enable only favorite my application crash instantly.但是现在当我触发切换以仅启用最喜欢的应用程序时,我的应用程序会立即崩溃。
I've tried to trigger the Show profile
toggle from SettingsView
and it works.我试图从SettingsView
触发Show profile
切换并且它有效。
struct SettingsView: View {
@EnvironmentObject var userData: UserData
var body: some View {
Form {
Section(header: Text("General")) {
Toggle(isOn: $userData.showProfile) {
Text("Show profile")
}
Toggle(isOn: $userData.showFavoriteOnly) {
Text("Favorites only")
}
}
Section(header: Text("UI")) {
Toggle(isOn: .constant(false)) {
Text("Dark mode")
}
NavigationLink(destination: Text("third")) {
Text("Third navigation")
}
}
}.navigationBarTitle(Text("Settings"), displayMode: .inline)
}
}
In brief, the crash appears in my SettingsView
when I trigger the Show only favorite
Toggle and then I try to go back to the previous view which is ItemListView
简而言之,当我触发Show only favorite
Toggle 时,崩溃出现在我的SettingsView
,然后我尝试返回上一个视图,即ItemListView
The only information I can get about the error is Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
我能得到的关于错误的唯一信息是Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
You can find the whole project on my GitHub : https://github.com/Hurobaki/swiftui-tutorial你可以在我的 GitHub 上找到整个项目: https : //github.com/Hurobaki/swiftui-tutorial
Some help would be really appreciated :)一些帮助将不胜感激:)
Here is a minimal version of your example code, that works:这是您的示例代码的最小版本,它有效:
struct Landmark: Hashable, Codable, Identifiable {
var id: Int
var imageName: String
var title: String
var isFavorite: Bool
var description: String
}
final class UserData: ObservableObject {
@Published var showFavoriteOnly: Bool = false
@Published var items: [Landmark] = [
Landmark(id: 1, imageName: "a", title: "a", isFavorite: true, description: "A"),
Landmark(id: 2, imageName: "b", title: "b", isFavorite: false, description: "B")
]
}
struct ContentView: View {
@EnvironmentObject var userData: UserData
var body: some View {
NavigationView {
List(userData.items.filter { !userData.showFavoriteOnly || $0.isFavorite }) { landmark in
Text(String(landmark.isFavorite))
}
.navigationBarTitle("Tutorials")
.navigationBarItems(trailing: trailingItem())
}
}
func trailingItem () -> some View {
return HStack {
NavigationLink(destination: SettingsView()) {
Text("Settings")
}
}
}
}
struct SettingsView: View {
@EnvironmentObject var userData: UserData
var body: some View {
Form {
Section(header: Text("General")) {
Toggle(isOn: $userData.showFavoriteOnly) {
Text("Favorites only")
}
}
}.navigationBarTitle(Text("Settings"), displayMode: .inline)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.