SwiftUI:使用 "if else" 更改视图
SwiftUI: changing view using "if else"
我正在尝试根据使用按钮所做的选择来更改视图。我正在使用 Combine 和 SwiftUI。
我用 @Published
var:
创建了一个视图路由器 class
import Foundation
import SwiftUI
import Combine
class ViewRouter: ObservableObject {
@Published var currentView = "folder"
}
我有我的按钮结构:
import SwiftUI
import Combine
struct MultiButton: View {
@ObservedObject var viewRouter = ViewRouter()
@State var showButton = false
var body: some View {
GeometryReader { geometry in
ZStack{
// open multi button
Button(action: {
withAnimation {
self.showButton.toggle()
}
}) {
Image(systemName: "gear")
.resizable()
.frame(width: 40, height: 40, alignment: .center)
}
if self.showButton {
Multi()
.offset(CGSize(width: -30, height: -100))
}
}
}
}
}
struct MultiButton_Previews: PreviewProvider {
static var previews: some View {
MultiButton()
}
}
struct Multi: View {
@ObservedObject var viewRouter = ViewRouter()
var body: some View {
HStack(spacing: 10) {
ZStack {
Button(action: {
self.viewRouter.currentView = "folder"
debugPrint("\(self.viewRouter.currentView)")
}) {
ZStack{
Circle()
.foregroundColor(Color.blue)
.frame(width: 70, height: 70)
Image(systemName: "folder")
.resizable()
.aspectRatio(contentMode: .fit)
.padding(20)
.frame(width: 70, height: 70)
.foregroundColor(.white)
}.shadow(radius: 10)
}
}
Button(action: {
self.viewRouter.currentView = "setting"
debugPrint("\(self.viewRouter.currentView)")
}, label: {
ZStack {
Circle()
.foregroundColor(Color.blue)
.frame(width: 70, height: 70)
Image(systemName: "gear")
.resizable()
.aspectRatio(contentMode: .fit)
.padding(20)
.frame(width: 70, height: 70)
.foregroundColor(.white)
}.shadow(radius: 10)
})
}
.transition(.scale)
}
}
和 contentView
:
import SwiftUI
import Combine
struct ContentView: View {
@ObservedObject var viewRouter = ViewRouter()
var body: some View {
VStack{
MultiButton()
if viewRouter.currentView == "folder" {
Text("folder")
} else if viewRouter.currentView == "setting"{
Text("setting")
}
}
}
}
为什么按下按钮时我的文本没有从文件夹更改为设置基础?
变量是@Published
;它应该发布更改并更新主视图。
我是不是漏掉了什么?
您有多个 ViewRouter
实例,每个视图都有自己的实例。如果您更改该实例,其他实例将不会更改。
要解决这个问题,您要么必须手动传递一个实例:
struct MultiButton {
@ObservedObject var viewRouter: ViewRouter
...
}
struct ContentView {
@ObservedObject var viewRouter = ViewRouter()
var body: some View {
VStack {
MultiButton(viewRouter: self.viewRouter)
...
}
}
}
或者您可以将其声明为环境对象:
struct MultiButton {
@EnvironmentObject var viewRouter: ViewRouter
...
}
然后在场景委托中创建视图层次结构时注入它:
let contentView = ContentView()
.environmentObject(ViewRouter())
请注意,在场景委托中注入环境对象时,它不会在使用 ViewRouter 的视图的每个预览中都可用,除非您也在那里手动注入它:
static var previews: some View {
ContentView()
.environmentObject(ViewRouter())
}
我正在尝试根据使用按钮所做的选择来更改视图。我正在使用 Combine 和 SwiftUI。
我用 @Published
var:
import Foundation
import SwiftUI
import Combine
class ViewRouter: ObservableObject {
@Published var currentView = "folder"
}
我有我的按钮结构:
import SwiftUI
import Combine
struct MultiButton: View {
@ObservedObject var viewRouter = ViewRouter()
@State var showButton = false
var body: some View {
GeometryReader { geometry in
ZStack{
// open multi button
Button(action: {
withAnimation {
self.showButton.toggle()
}
}) {
Image(systemName: "gear")
.resizable()
.frame(width: 40, height: 40, alignment: .center)
}
if self.showButton {
Multi()
.offset(CGSize(width: -30, height: -100))
}
}
}
}
}
struct MultiButton_Previews: PreviewProvider {
static var previews: some View {
MultiButton()
}
}
struct Multi: View {
@ObservedObject var viewRouter = ViewRouter()
var body: some View {
HStack(spacing: 10) {
ZStack {
Button(action: {
self.viewRouter.currentView = "folder"
debugPrint("\(self.viewRouter.currentView)")
}) {
ZStack{
Circle()
.foregroundColor(Color.blue)
.frame(width: 70, height: 70)
Image(systemName: "folder")
.resizable()
.aspectRatio(contentMode: .fit)
.padding(20)
.frame(width: 70, height: 70)
.foregroundColor(.white)
}.shadow(radius: 10)
}
}
Button(action: {
self.viewRouter.currentView = "setting"
debugPrint("\(self.viewRouter.currentView)")
}, label: {
ZStack {
Circle()
.foregroundColor(Color.blue)
.frame(width: 70, height: 70)
Image(systemName: "gear")
.resizable()
.aspectRatio(contentMode: .fit)
.padding(20)
.frame(width: 70, height: 70)
.foregroundColor(.white)
}.shadow(radius: 10)
})
}
.transition(.scale)
}
}
和 contentView
:
import SwiftUI
import Combine
struct ContentView: View {
@ObservedObject var viewRouter = ViewRouter()
var body: some View {
VStack{
MultiButton()
if viewRouter.currentView == "folder" {
Text("folder")
} else if viewRouter.currentView == "setting"{
Text("setting")
}
}
}
}
为什么按下按钮时我的文本没有从文件夹更改为设置基础?
变量是@Published
;它应该发布更改并更新主视图。
我是不是漏掉了什么?
您有多个 ViewRouter
实例,每个视图都有自己的实例。如果您更改该实例,其他实例将不会更改。
要解决这个问题,您要么必须手动传递一个实例:
struct MultiButton {
@ObservedObject var viewRouter: ViewRouter
...
}
struct ContentView {
@ObservedObject var viewRouter = ViewRouter()
var body: some View {
VStack {
MultiButton(viewRouter: self.viewRouter)
...
}
}
}
或者您可以将其声明为环境对象:
struct MultiButton {
@EnvironmentObject var viewRouter: ViewRouter
...
}
然后在场景委托中创建视图层次结构时注入它:
let contentView = ContentView()
.environmentObject(ViewRouter())
请注意,在场景委托中注入环境对象时,它不会在使用 ViewRouter 的视图的每个预览中都可用,除非您也在那里手动注入它:
static var previews: some View {
ContentView()
.environmentObject(ViewRouter())
}