使用 HalfASheet ( https://github.com/franklynw/HalfASheet )。
我有一個名為 的視圖ProjectsView,并且在其中ZStack我ProjectsView有ProjectSorting和SortingView(都注入了EnvironmentObject)。我希望Text(??) inProjectSorting被更改,并且HStack(??) inSortingView有一個復選標記,這兩者都取決于sortingin 變數的值SortingValues。sorting用戶可以通過按Buttonin來更改 的值SortingView。
無論出于何種原因,Text(??) inProjectSorting根本沒有改變。而HStack(??) inSortingView只有當它ancestor stack有另一個Text(??) 包含時才會得到復選標記@State variable from the environment,我覺得這很奇怪。
我應該改變什么?有什么方法可以讓我使用它來完成這項作業@EnvironmentObject嗎?我是一個新手,不能真正理解其他包裝器,所以我想在@State, @Binding, @EnvirionmentObject. 提前致謝。
排序值.swift
import Combine
class SortingValues: ObservableObject {
@Published var sorting = "Top Rated"
}
ProjectsView.swift
struct ProjectsView: View {
@Binding var isPresented: Bool
@State var showSortingSheet = false
var body: some View {
ZStack {
NavigationView {
VStack(spacing: 0) {
ProjectsTopView(isPresented: $isPresented)
ProjectSorting(showSortingSheet: $showSortingSheet)
.environmentObject(SortingValues())
ProjectList()
}
.navigationBarHidden(true)
}
SortingView(showSortingSheet: $showSortingSheet)
.environmentObject(SortingValues())
}
}
}
專案排序.swift
import SwiftUI
struct ProjectSorting: View {
@EnvironmentObject var sortingValues: SortingValues
@Binding var showSortingSheet: Bool
@State var sortingValue = ""
var body: some View {
VStack {
HStack {
Text("Projects")
Spacer()
Button {
showSortingSheet.toggle()
} label: {
HStack(spacing: 3) {
Image("sortingArrows")
Text(sortingValue) // < ?? this is the Text I want to be changed
}
}
}
// Another HStack goes here
}
.onReceive(sortingValues.$sorting) { sorting in
print("This is ProjectSorting. sorting:", sorting) // < this does not print when I close the half sheet
sortingValue = sorting
}
}
}
排序視圖.swift
import SwiftUI
import HalfASheet
struct SortingView: View {
@EnvironmentObject var sortingValues: SortingValues
@Binding var showSortingSheet: Bool
@State var sortingValue = ""
var body: some View {
VStack {
HalfASheet(isPresented: $showSortingSheet) {
let sorting = ["Most Recent", "Most Reviewed", "Top Rated", "Lowest Price", "Highest Price"]
VStack(alignment: .leading) {
ForEach(sorting, id: \.self) { sorting in
VStack(alignment: .leading, spacing: 14) {
Button (action: {
sortingValues.sorting = sorting
}, label: {
HStack { // ??
Text(sorting)
Spacer()
if sorting == sortingValue { // < this is where I add the checkmark
Image(systemName: "checkmark")
}
}
.foregroundColor(.primary)
})
if sorting != "Highest Price" {
Divider()
}
}
}
}
}
.height(.fixed(325))
// Text("Inside VStack, outside HalfASheet") // adding this Text DOES NOT make the HStack have a checkmark
Text("Inside VStack, outside HalfASheet: \(sortingValue)") // ?? adding this Text DOES make the HStack have a checkmark
}
.onReceive(sortingValues.$sorting) { sorting in
// the two printing lines below print correctly every time I tap the Button
print("This is SortingView. sorting:", sorting)
print("sortingValues.sorting: \(sortingValues.sorting)")
sortingValue = sorting
}
}
}
uj5u.com熱心網友回復:
您SortingView和ProjectSorting兩者都訪問 type 的環境物件SortingValues,但您將新的、單獨的實體傳遞給每個物件。因此,您在一個地方所做的更改不會反映在另一個地方,因為每個視圖都在與兩個完全不同的相同型別物件之一進行通信。
如果您希望它們與同一個物件實體互動,您需要在物件層次結構中高于兩者的位置宣告它,并確保將單個實體傳遞給兩者。例如:
struct ProjectsView: View {
@Binding var isPresented: Bool
@State var showSortingSheet = false
@StateObject var sortingValues = SortingValues()
var body: some View {
ZStack {
NavigationView {
VStack(spacing: 0) {
ProjectsTopView(isPresented: $isPresented)
ProjectSorting(showSortingSheet: $showSortingSheet)
.environmentObject(sortingValue)
ProjectList()
}
.navigationBarHidden(true)
}
SortingView(showSortingSheet: $showSortingSheet)
.environmentObject(sortingValues)
}
}
}
但你可以更進一步。由于環境物件和值會自動沿視圖層次結構向下傳播,因此您可以將兩個單獨.environmentObject的呼叫替換為一個:
struct ProjectsView: View {
@Binding var isPresented: Bool
@State var showSortingSheet = false
@StateObject var sortingValues = SortingValues()
var body: some View {
ZStack {
NavigationView {
VStack(spacing: 0) {
ProjectsTopView(isPresented: $isPresented)
ProjectSorting(showSortingSheet: $showSortingSheet)
ProjectList()
}
.navigationBarHidden(true)
}
SortingView(showSortingSheet: $showSortingSheet)
}
.environmentObject(sortingValues)
}
}
可能有更好的方法來處理對觀察到的模型的變化做出反應,而不是在區域狀態變數中復制變數值——但確保所有視圖都使用相同的共享環境物件應該能讓你順利進行。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/489116.html
上一篇:意外輸出:我使用下面的代碼根據按下的按鈕列印出計時器,但計時器僅從20開始。怎么了?
下一篇:使用可選欄位解碼json
