View Present 하는 방식은 .fullScreenCover 또는 .sheet 사용하지만 커스텀 해서 UIKit에서 사용하는 방식으로

사용할 수 있어 기록해 놓습니다.

 

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: ViewControllerHolder {
        get { return self[ViewControllerKey.self] }
        set { self[ViewControllerKey.self] = newValue }
    }
}

extension UIViewController {
    func present<Content: View>(style: UIModalPresentationStyle =
        .automatic, @ViewBuilder builder: () -> Content) {
            // Must instantiate HostingController with some sort of view...
            let toPresent = UIHostingController(rootView:
                                                    AnyView(EmptyView()))
            toPresent.modalPresentationStyle = style
            // ... but then we can reset rootView to include the environment
            toPresent.rootView = AnyView(
                builder()
                    .environment(\.viewController, ViewControllerHolder(value:
                                                                            toPresent))
            )
            self.present(toPresent, animated: true, completion: nil)
        }
}

 

 

[사용방법]

struct ContentView: View {
	//Custom ViewController
    @Environment(\.viewController) private var viewControllerHolder: ViewControllerHolder
    private var viewController: UIViewController? {
        self.viewControllerHolder.value
    }
    
    var body: some View {
        VStack {
        	LazyVGrid(columns: type == .Grid ?
                  [GridItem(.adaptive(minimum: 160, maximum: 215), spacing: 10)] :
                    [GridItem(.adaptive(minimum: 320, maximum: 430), spacing: 10)], // column spacing
                  spacing: 10,  //row spacing
                  content: {
            	ForEach(myDataArray, id: \.self) { data in
            	    ZStack {
            	        Rectangle()
            	            .foregroundColor(.orange)
            	            .frame(height: cellHieght)
            	        Text(data)
            	    }
            	    .onTapGesture {
                    	// Present Sheet 방식
            	        self.viewController?.present(style: .formSheet, builder: {
            	            KStarSubView()
            	        })
                        
                        // Present fullScreen 방식
                        self.viewController?.present(style: .fullScreen, builder: {
                        	KStarSubView()
                    	})
            	    }
            	}
        	})
        }
    }
}

+ Recent posts