私は最近 SwiftUI を使用しており、アプリ内の他の「ページ」または「画面」に変更するための 2 つのボタンを含む、rootView として ContentView.swift を書き込むことができました。現在、コード内の 2 つのビュー間を移動できます。各「画面」Swiftファイルで ObservableObjects(viewRouter : ViewRouter) を使用しました。ユーザーが表示できるようにポップアップする 3 番目の画面を作成することにしました。同じ構造とそのビューを表示する方法を含めた後: 3 番目のビューのボタンのアクションは実行されていません。コンパイルにエラーはなく、アプリがビルドされます! ただし、FirstScreen 内のボタンをクリックすると、ThirdScreen は表示されません。
メイン ビュー ContentView は次のとおりです。
import SwiftUI
struct ContentView: View {
@State var screen: String = "FirstScreen" //Declares the first state
@EnvironmentObject var viewRouter : ViewRouter //References our other swift file.
var body : some View {
VStack {
if viewRouter.currentScreen == "FirstScreen" {
FirstScreen()
} else if viewRouter.currentScreen == "SecondScreen" {
SecondScreen()
.transition(.slide)
} else if viewRouter.currentScreen == "ThirdScreen" {
ThirdScreen()
.transition(.opacity)
}
struct ContentView_Previews: PreviewProvider { //Looks fine, its the previews
static var previews: some View {
ContentView().environmentObject(ViewRouter())}}
これは、以下の構造を持つ FirstScreen ファイルです。
import Foundation
import UIKit
import SwiftUI
struct FirstScreen : View {
@EnvironmentObject var viewRouter : ViewRouter
var body : some View {
VStack {
Button(action: {
print("The info button has been clicked.")
self.viewRouter.currentScreen = "SecondScreen" //Heres an action
}) {
Image(systemName: "info")
.padding()
.background(Color.green)
.font(.largeTitle)
.foregroundColor(Color.orange)
.frame(width: 300, height: 600)
}
Button(action: {
print("You have erased it.")
self.viewRouter.currentScreen = "ThirdScreen" //This action does not happen.
}) {
Image(systemName: "trash")
.padding()
.background(Color.red)
.font(.largeTitle)
.foregroundColor(Color.white)
.frame(width: 426, height: 620)
}}}}
struct FirstScreen_previews : PreviewProvider {
static var previews: some View {
FirstScreen().environmentObject(ViewRouter())
}
}
これは、ViewRouter からロードする必要がある私の ThirdScreen のコードと、FirstScreen の Swift ファイルからボタンをクリックすることによる変更です。
import Foundation
import UIKit
import SwiftUI
struct ThirdScreen : View {
@EnvironmentObject var viewRouter : ViewRouter
var body : some View {
VStack {
Text("You step a bit off balance")
.font(.largeTitle)
.foregroundColor(Color.red)
Text("You stand up, shaking, under a pass")
.font(.callout)
Text("It looks to be a wrong step. Maybe you head back?")
.font(.caption)
.foregroundColor(Color.gray)
Button(action :{self.viewRouter.currentScreen = "FirstScreen"}){
Image(systemName: "capslock" )
.frame(width: 209, height: 308)
.foregroundColor(Color.green)
}}}}
struct Third_preview : PreviewProvider {
static var previews: some View {
ThirdScreen().environmentObject(ViewRouter())
}
}
これは、画面を管理するために正常に動作する ViewRouter.swift です。
import Foundation
import Combine
import SwiftUI
class ViewRouter: ObservableObject {
let objectWillChange = PassthroughSubject<ViewRouter, Never>()
var currentScreen : String = "FirstScreen" {
didSet {
withAnimation(){
objectWillChange.send(self)
}
}
}
}
最後に、正しく動作している SecondScreen.swift. このファイルはおそらく冗長ですが、このファイル内で何か良いことが機能している可能性を考えて含めました。ボタンは内部で機能し、ビューを変更します。
import Foundation
import UIKit
import SwiftUI
struct SecondScreen : View {
@EnvironmentObject var viewRouter : ViewRouter
var body : some View {
VStack {
Button(action: {self.viewRouter.currentScreen = "FirstScreen"}) {
Image(systemName: "arrowshape.turn.up.left" )
.padding()
.cornerRadius(18)
.frame(width: 180, height: 400)
}}}}
struct SecondScreen_previews : PreviewProvider{
static var previews : some View {
SecondScreen().environmentObject(ViewRouter())
}
}
ここで私を助けてくれて本当にありがとう。以下のように、引き続き Screen ファイルを作成したいと思っています。この問題のトラブルシューティングを続けているため、迅速に対応いたします。ありがとうございました!