SwiftUI - есть ли аналог PopViewController в SwiftUI? - PullRequest
20 голосов
/ 07 июня 2019

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

Ответы [ 4 ]

5 голосов
/ 09 июня 2019

Кажется, что тонна базовых навигационных функций супер глючит, что вызывает разочарование и, возможно, на данный момент стоит отойти, чтобы сэкономить часы разочарования.Для меня PresentationButton - единственный, который работает.Вкладки TabbedView не работают должным образом, и NavigationButton не работает для меня вообще.Похоже, YMMV, если NavigationButton работает для вас.

Я надеюсь, что они исправят это одновременно с исправлением автозаполнения, что даст нам намного лучшее понимание того, что доступно для нас.В то же время я неохотно пишу код и веду записи, когда появятся исправления.Отстойно, когда приходится выяснять, делаем ли мы что-то неправильно или просто не работает, но для вас это бета!

2 голосов
/ 11 июля 2019

Я нашел решение для программного перетаскивания представлений в NavigationView, используя NavigationDestinationLink.

Вот простой пример:

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()
        }
    }
}

Я писал об этом в сообщении в блоге здесь .

0 голосов
/ 24 июля 2019

вместо кнопки навигации используйте Navigation DestinationLink

но вы должны импортировать Combine

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")
    }
}
}
0 голосов
/ 26 июня 2019

РЕДАКТИРОВАТЬ: Этот ответ здесь лучше, чем мой, но оба работают: SwiftUI отклонить модальный

То, что вы действительно хотите (или должны хотеть), - это модальная презентация, о которой несколько человек упомянули здесь. Если вы пойдете по этому пути, вам определенно потребуется возможность программно отклонить модал, и у Эрики Садун есть отличный пример того, как это сделать здесь: https://ericasadun.com/2019/06/16/swiftui-modal-presentation/

Учитывая разницу между декларативным кодированием и императивным кодированием, решение там может быть неочевидным (например, переключение bool в false для исключения модального режима), но имеет смысл, если ваше состояние модели является источником истины, а не состояние самого пользовательского интерфейса.

Вот мой быстрый пример Эрики, использующий привязку, переданную в TestModal, чтобы он мог отклонить себя, не будучи членом самого ContentView (как Эрика, для простоты).

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