SwiftUI'de yeni bir görünüm sunun


11

Bir düğmeyi tıklayıp present modallyUIKit'teki gibi yeni bir görünüm sunmak istiyorumresim açıklamasını buraya girin

Zaten " Sayfaları kullanarak yeni bir görünüm sunma " gördüm , ancak ana görünüme kalıcı bir sayfa olarak eklemek istemiyorum.

Kullanmak istemiyorum NavigationLink, çünkü yeni bir görünüm istemiyorum ve eski görünümde bir navigasyon ilişkisi var.

Yardımın için teşekkürler...


Neden ana görünüme kalıcı bir sayfa olarak eklemek istemiyorsunuz? Hatta standart bir yöntemdir UIKit. Özel bir sebebin var mı?
Mojtaba Hosseini

Düşüncelerimi açıklamaya çalışıyorum ... Yanlış bir şey olursa lütfen beni düzeltin.
CH Wing

Uygulamaların 3 görünümü vardır, 1: Giriş Sayfa 2: TableView Sayfa 3: TableDetail Sayfası, TableView sayfası ve TableDetail sayfası gezinme ilişkisidir. Giriş TableView sayfasına gösterildikten sonra, TableView sayfasının giriş yaptıktan sonra giriş sayfası ile bir ilişkisi yoktur
CH Wing

Yani fullscreendoğru olması mı gerekiyor ?
Mojtaba Hosseini

ys! ben istiyorumfullscreen
CH Kanat

Yanıtlar:


12

Bir model göstermek için (iOS 13 stili)

Sadece sheetkendini kovma yeteneğine sahip bir basitliğe ihtiyacınız var :

struct ModalView: View {
    @Binding var presentedAsModal: Bool
    var body: some View {
        Button("dismiss") { self.presentedAsModal = false }
    }
}

Ve şu şekilde sunun:

struct ContentView: View {
    @State var presentingModal = false

    var body: some View {
        Button("Present") { self.presentingModal = true }
        .sheet(isPresented: $presentingModal) { ModalView(presentedAsModal: self.$presentingModal) }
    }
}

Modalın kendisine geçtiğimi unutmayın,presentingModal böylece modalın kendisinden çıkarabilirsiniz, ancak ondan kurtulabilirsiniz.


GERÇEKTEN sunmak için fullscreen(Sadece görsel olarak değil)

Adresine erişmeniz gerekiyor ViewController. Yani bazı yardımcı konteynerlere ve çevre malzemelerine ihtiyacınız var:

struct ViewControllerHolder {
    weak var value: UIViewController?
}

struct ViewControllerKey: EnvironmentKey {
    static var defaultValue: ViewControllerHolder {
        return ViewControllerHolder(value: UIApplication.shared.windows.first?.rootViewController)

    }
}

extension EnvironmentValues {
    var viewController: UIViewController? {
        get { return self[ViewControllerKey.self].value }
        set { self[ViewControllerKey.self].value = newValue }
    }
}

O zaman bu uzantıyı uygulamak gerekir:

extension UIViewController {
    func present<Content: View>(style: UIModalPresentationStyle = .automatic, @ViewBuilder builder: () -> Content) {
        let toPresent = UIHostingController(rootView: AnyView(EmptyView()))
        toPresent.modalPresentationStyle = style
        toPresent.rootView = AnyView(
            builder()
                .environment(\.viewController, toPresent)
        )
        self.present(toPresent, animated: true, completion: nil)
    }
}

En sonunda

şöyle yapabilirsiniz fullscreen:

struct ContentView: View {
    @Environment(\.viewController) private var viewControllerHolder: UIViewController?

    var body: some View {
        Button("Login") {
            self.viewControllerHolder?.present(style: .fullScreen) {
                Text("Main") // Or any other view you like
            }
        }
    }
}

harika! çözümünüz için teşekkür ederiz
CH Wing

Ortam özelliği sarmalayıcısında bu hatayı alıyorum: 'Ortam <UIViewController?>'
Türünün

Varsayılan olarak ele alınmalıdır, ancak ?oradaki satırın sonuna eklemeyi deneyin . NoJJ
Mojtaba Hosseini

Ben konsolunda bu hatayı alıyorum: `` `Uyarı: Şu <_TtGC7SwiftUI19UIHostingControllerVS_7AnyView_: 0x7fafd2641d30> Girişimini <_TtGC7SwiftUI19UIHostingControllerVS_7AnyView_: 0x7fafd2611bd0> üzerinde kimin görünüm penceresi hiyerarşisinde değil` ``!
jsbeginnerNodeJS

nasıl reddedersin?
gabrielapittari

0

İşte basit tek yönlü ileri görünümler. Çok basit.

        struct ChildView: View{
           private  let colors: [Color] = [.red, .yellow,.green,.white]
           @Binding var index : Int
           var body: some View {
           let next = (self.index+1)  % MyContainer.totalChildren
             return   ZStack{
                    colors[self.index  % colors.count]
                     Button("myNextView \(next)   ", action: {
                    withAnimation{
                        self.index = next
                    }
                    }
                )}.transition(.asymmetric(insertion: .move(edge: .trailing)  , removal:  .move(edge: .leading)  ))
            }
        }

        struct MyContainer: View {
            static var totalChildren = 10
            @State private var value: Int = 0
            var body: some View {
                    HStack{
                        ForEach(0..<(Self.totalChildren) ) { index in
                            Group{
                            if    index == self.value {
                                ChildView(index:  self.$value)
                                }}
                            }
                }
                }
        }

-1

Feragatname: Aşağıda gerçekten bir "doğal mod" gibi değildir, ne davranır ne de bak ve hisset, ama eğer biri bir görüşün diğerine göre özel bir geçişe ihtiyaç duyacaksa, sadece birinciyi aktif hale getirecekse, aşağıdaki yaklaşım yardımcı olabilir.

Yani, aşağıdaki gibi bir şey bekliyorsanız

özel SwiftUI yöntemi

İşte demo için basit bir kod yaklaşımı (corse animasyonu ve geçiş parametreleri istek ile değiştirilebilir)

struct ModalView : View {
    @Binding var activeModal: Bool
    var body : some View {
        VStack {
            Button(action: {
                withAnimation(.easeInOut(duration: 0.3)) {
                    self.activeModal = false
                }
            }) {
                Text("Hide modal")
            }
            Text("Modal View")
        }
        .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .center)
        .background(Color.green)
    }
}

struct MainView : View {
    @Binding var activeModal: Bool
    var body : some View {
        VStack {
            Button(action: {
                withAnimation(.easeInOut(duration: 0.3)) {
                    self.activeModal = true
                }
            }) {
                Text("Show modal")
            }
            Text("Main View")
        }
        .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .center)
        .background(Color.yellow)
    }
}

struct ModalContainer: View {
    @State var showingModal = false
    var body: some View {
        ZStack {
            MainView(activeModal: $showingModal)
                .allowsHitTesting(!showingModal)
            if showingModal {
                ModalView(activeModal: $showingModal)
                    .transition(.move(edge: .bottom))
                    .zIndex(1)
            }
        }
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.