SwiftUI에서 새로운 견해를 제시하십시오 방법 “을 이미

버튼을 클릭하고 present modallyUIKit 과 같은 새로운보기를 제시하고 싶습니다 .
여기에 이미지 설명을 입력하십시오

시트를 사용하여 새보기를 표시하는 방법 “을 이미 보았지만 기본보기에 모달 시트로 첨부하고 싶지 않습니다.

그리고 나는 NavigationLink새로운보기를 원하지 않고 오래된보기에는 탐색 관계가 있기 때문에을 사용 하고 싶지 않습니다.

당신의 도움을 주셔서 감사합니다…



답변

모달을 표시하려면 (iOS 13 스타일)

당신 sheet은 스스로를 기각하는 능력을 가진 간단한 것이 필요 합니다.

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

그리고 다음과 같이 제시하십시오.

struct ContentView: View {
    @State var presentingModal = false

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

참고 난을 통과 presentingModal하면 모달 자체를 해제 할 수 있지만, 당신이 그것을 제거 할 수 있도록 모달로.


그것을 fullscreen시각적으로 만 보여 주도록

에 액세스해야합니다 ViewController. 따라서 도우미 컨테이너와 환경 관련 요소가 필요합니다.

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

그런 다음이 확장을 구현해야합니다.

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

드디어

당신은 그것을 다음 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
            }
        }
    }
}

답변

간단한 일방 통행보기입니다. 매우 간단합니다.

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

답변

면책 조항 : 아래는 실제로 “네이티브 모달”과 같지 않으며, 행동하거나 룩앤필하지도 않지만, 누군가가 하나의 뷰를 다른 뷰보다 커스텀 전환하여 활성화하고 최상위 뷰 만 활성화 해야하는 경우 다음 접근법이 도움이 될 수 있습니다.

따라서 다음과 같은 것을 기대하면

다음은 접근법을 데모하기위한 간단한 코드입니다 (코즈 애니메이션 및 전환 매개 변수는 원하는대로 변경할 수 있음)

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