programing

Swift UI - Swift에 해당하는 popViewController가 있습니까?UI?

yellowcard 2023. 8. 8. 21:27
반응형

Swift UI - Swift에 해당하는 popViewController가 있습니까?UI?

요 ㅠㅠㅠㅠㅠㅠㅠㅠㅠ 때 수 , 를 사용하는 것과 로 UI 및 버 튼 을 누 를 때 는 사 하 용 과 것 가 우 같 습 니 다 리 는 이 는 데 하 원 를 로 있 돌 기 기 아 갈 전 수 보 이 ▁ui ▁when 다 니 ▁want , ▁a 습 ▁tapping 같 ▁ui ▁to ▁and ▁the 및 ▁we ▁button ▁view 과 ▁to ▁back ▁be popViewController富士山의 UINavigationController지금까지 제공된 방법이 있습니까?

저는 또한 사용하려고 노력했습니다.NavigationDestinationLink성공하지 못하고 그렇게 하는 것.

struct AView: View {
    var body: some View {
        NavigationView {
            NavigationButton(destination: BView()) {
                Text("Go to B")
            }
        }
    }
}

struct BView: View {
    var body: some View {
        Button(action: {
            // Trying to go back to the previous view
            // previously: navigationController.popViewController(animated: true)
        }) {
            Text("Come back to A")
        }
    }
}

를 합니다.BView구조는 다음과 같습니다.버튼은 다음과 같이 작동합니다.popViewControllerUIKit에서 했습니다.

struct BView: View {
    @Environment(\.presentationMode) var presentationMode
    
    var body: some View {
        Button("Come back to A") {
            presentationMode.wrappedValue.dismiss()
        }
    }
}

사용하다@Environment(\.presentationMode) var presentationMode이전 보기로 돌아갑니다.자세한 내용은 아래 코드를 확인하십시오.

import SwiftUI

struct ContentView: View {


    var body: some View {

        NavigationView {
            ZStack {
                Color.gray.opacity(0.2)

                NavigationLink(destination: NextView(), label: {Text("Go to Next View").font(.largeTitle)})
            }.navigationBarTitle(Text("This is Navigation"), displayMode: .large)
                .edgesIgnoringSafeArea(.bottom)
        }
    }
}

struct NextView: View {
    @Environment(\.presentationMode) var presentationMode
    var body: some View {
        ZStack {
            Color.gray.opacity(0.2)
        }.navigationBarBackButtonHidden(true)
            .navigationBarItems(leading: Button(action: {
                self.presentationMode.wrappedValue.dismiss()
            }, label: { Image(systemName: "arrow.left") }))
            .navigationBarTitle("", displayMode: .inline)
    }
}


struct NameRow: View {
    var name: String
    var body: some View {
        HStack {
            Image(systemName: "circle.fill").foregroundColor(Color.green)
            Text(name)
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

상태 변수 포함.한번 해보세요.

struct ContentViewRoot: View {
    @State var pushed: Bool = false
    var body: some View {
        NavigationView{
            VStack{
                NavigationLink(destination:ContentViewFirst(pushed: self.$pushed), isActive: self.$pushed) { EmptyView() }
                    .navigationBarTitle("Root")
                Button("push"){
                    self.pushed = true
                }
            }
        }
        .navigationViewStyle(StackNavigationViewStyle())
    }
}


struct ContentViewFirst: View {
    @Binding var pushed: Bool
    @State var secondPushed: Bool = false
    var body: some View {
        VStack{
            NavigationLink(destination: ContentViewSecond(pushed: self.$pushed, secondPushed: self.$secondPushed), isActive: self.$secondPushed) { EmptyView() }
                .navigationBarTitle("1st")
            Button("push"){
                self.secondPushed = true;
            }
        }
    }
}



struct ContentViewSecond: View {
    @Binding var pushed: Bool
    @Binding var secondPushed: Bool

    var body: some View {
        VStack{
            Spacer()
            Button("PopToRoot"){
                self.pushed = false
            } .navigationBarTitle("2st")

            Spacer()
            Button("Pop"){
                         self.secondPushed = false
                     } .navigationBarTitle("1st")
            Spacer()
        }
    }
}

enter image description here

이것은 watch OS(iOS를 사용해 본 적이 없음)에서 작동하는 것 같습니다.

@Environment(\.presentationMode) var presentationMode

그리고 나서 네가 터져야 할 때.

self.presentationMode.wrappedValue.dismiss()

이제 원하는 경우 탐색 보기에서 프로그래밍 방식으로 팝업을 표시할 수 있습니다.이것은 베타 5에 있습니다.

뒤로 단추가 필요하지 않습니다.원하는 방식으로 DetailView에서 showSelf 속성을 프로그래밍 방식으로 트리거할 수 있습니다.마스터에 "Push" 텍스트를 표시할 필요가 없습니다.빈 보기()일 수 있으므로 보이지 않는 세그를 만들 수 있습니다.

(새로운 NavigationLink 기능이 더 이상 사용되지 않는 NavigationDestinationLink를 대체합니다.)

import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationView {
            MasterView()
        }
    }
}

struct MasterView: View {
    @State var showDetail = false

    var body: some View {
        VStack {
            NavigationLink(destination: DetailView(showSelf: $showDetail), isActive: $showDetail) {
                Text("Push")
            }
        }
    }
}

struct DetailView: View {
    @Binding var showSelf: Bool

    var body: some View {
        Button(action: {
            self.showSelf = false
        }) {
            Text("Pop")
        }
    }
}

#if DEBUG
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
#endif

기본적인 내비게이션 기능의 상당 부분이 슈퍼 버그인 것처럼 보이는데, 이는 실망스럽고 몇 시간 동안의 좌절감을 줄이기 위해 지금은 물러설 가치가 있을 수도 있습니다.저는 PresentationButton이 유일하게 작동합니다.탭으로 된 보기 탭이 제대로 작동하지 않고 탐색 단추가 전혀 작동하지 않습니다.내비게이션 버튼이 작동하면 YMMV처럼 들립니다.

저는 그들이 자동 완성을 고치는 동시에 그것을 고치기를 바랍니다. 그러면 우리가 무엇을 이용할 수 있는지에 대한 훨씬 더 나은 통찰력을 얻을 수 있을 것입니다.그 동안 저는 마지못해 코드를 작성하고 수정 사항이 언제 나올지 기록하고 있습니다.우리가 무엇을 잘못하고 있는지 또는 단지 그것이 작동하지 않는지 알아내야 하는 것은 최악이지만, 그것은 당신을 위한 베타입니다!

업데이트: 이 솔루션의 NavigationDestinationLink API는 iOS 13 베타 5에서 더 이상 사용되지 않습니다.이제 NavigationLink를 isActive 바인딩과 함께 사용하는 것이 좋습니다.

NavigationDestinationLink를 사용하여 NavigationView에서 보기를 프로그래밍 방식으로 푸시/팝업하는 솔루션을 찾았습니다.

다음은 간단한 예입니다.

import Combine
import SwiftUI

struct DetailView: View {
    var onDismiss: () -> Void

    var body: some View {
        Button(
            "Here are details. Tap to go back.",
            action: self.onDismiss
        )
    }
}

struct MainView: View {
    var link: NavigationDestinationLink<DetailView>
    var publisher: AnyPublisher<Void, Never>

    init() {
        let publisher = PassthroughSubject<Void, Never>()
        self.link = NavigationDestinationLink(
            DetailView(onDismiss: { publisher.send() }),
            isDetail: false
        )
        self.publisher = publisher.eraseToAnyPublisher()
    }

    var body: some View {
        VStack {
            Button("I am root. Tap for more details.", action: {
                self.link.presented?.value = true
            })
        }
            .onReceive(publisher, perform: { _ in
                self.link.presented?.value = false
            })
    }
}

struct RootView: View {
    var body: some View {
        NavigationView {
            MainView()
        }
    }
}

저는 여기 블로그에 이것에 대해 썼습니다.

또한 이 기능을 사용할 수 있습니다..sheet

.navigationBarItems(trailing: Button(action: {
            self.presentingEditView.toggle()
        }) {
            Image(systemName: "square.and.pencil")
        }.sheet(isPresented: $presentingEditView) {
            EditItemView()
        })

제 경우 오른쪽 탐색 모음 항목에서 사용하면 보기를 생성해야 합니다(EditItemView()(내 경우) 해당 모달 뷰에 표시합니다.

https://developer.apple.com/documentation/swiftui/view/sheet(ispresented:ondismiss:content:)

편집: 여기 있는 답변이 제 답변보다 낫지만, 두 가지 모두 효과가 있습니다. Swift UI 해제 모달

여러분이 정말로 원하는 것은 여러 사람들이 여기서 언급한 모달 프레젠테이션입니다.만약 당신이 그 길을 간다면, 당신은 분명히 모달을 프로그램적으로 제거할 수 있어야 할 것입니다. 그리고 에리카 사둔은 여기에 그것을 하는 방법에 대한 훌륭한 예를 가지고 있습니다: https://ericasadun.com/2019/06/16/swiftui-modal-presentation/ .

선언형 코딩과 명령형 코딩의 차이를 고려할 때 해결책이 분명하지 않을 수도 있습니다(예: 모달을 제거하기 위해 부울을 거짓으로 전환하는 것). 그러나 모델 상태가 UI 자체의 상태가 아니라 진실의 소스인지 여부는 타당합니다.

다음은 TestModal에 전달된 바인딩을 사용하여 ContentView 자체의 멤버가 되지 않고도 자신을 제거할 수 있도록 Erica의 예를 간단히 보여드리겠습니다.

struct TestModal: View {
    @State var isPresented: Binding<Bool>

    var body: some View {
        Button(action: { self.isPresented.value = false }, label: { Text("Done") })
    }
}

struct ContentView : View {
    @State var modalPresented = false

    var body: some View {
        NavigationView {
            Text("Hello World")
            .navigationBarTitle(Text("View"))
            .navigationBarItems(trailing:
                Button(action: { self.modalPresented = true }) { Text("Show Modal") })
        }
        .presentation(self.modalPresented ? Modal(TestModal(isPresented: $modalPresented)) {
            self.modalPresented.toggle()
        } : nil)
    }
}

아래는 XCode11 GM에서 작동합니다.

self.myPresentationMode.wrappedValue.dismiss()

NavigationButton 대신 NavigationDestinationLink 사용

하지만 당신은 콤바인을 수입해야 합니다.

struct AView: View {
 var link: NavigationDestinationLink<BView>
var publisher: AnyPublisher<Void, Never>

init() {
    let publisher = PassthroughSubject<Void, Never>()
    self.link = NavigationDestinationLink(
        BView(onDismiss: { publisher.send() }),
        isDetail: false
    )
    self.publisher = publisher.eraseToAnyPublisher()
}

var body: some View {
    NavigationView {
        Button(action:{
        self.link.presented?.value = true


 }) {
            Text("Go to B")
        }.onReceive(publisher, perform: { _ in
            self.link.presented?.value = false
        })
    }
}
}

struct BView: View {
var onDismiss: () -> Void
var body: some View {
    Button(action: self.onDismiss) {
        Text("Come back to A")
    }
}
}

대상에서 리디렉션할 보기를 통과하고, 내부 블록에서는 다른 보기로 전달할 데이터를 통과합니다.

NavigationLink(destination: "Pass the particuter View") {
    Text("Push")
}

언급URL : https://stackoverflow.com/questions/56492965/swiftui-is-there-a-popviewcontroller-equivalent-in-swiftui

반응형