SwiftUI: изменение представления с помощью «если еще» - PullRequest
1 голос
/ 30 мая 2020

Я пытаюсь изменить вид на основе выбора, сделанного с помощью кнопки. Я использую 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")
            }
        }
    }
}

Почему мой текст не меняется из папки для установки базы при нажатии кнопки Ed?

var is @Published; он должен опубликовать sh изменение и обновить главное окно.

Я что-то пропустил?

1 Ответ

2 голосов
/ 30 мая 2020

У вас есть несколько экземпляров 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())
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...