Search

[정리] SOPT 29기 2주차 과제 정리

contents

RootViewController

이번 과제에서는 RootViewController(LoginVC)로의 화면 전환이 있었습니다.

Presented to Presenting

로그인, 회원가입 후에 나오는 화면에서 진행되는 화면전환은 Presented된 화면에서 Presenting해준 화면으로의 dismiss였습니다.
만약, 로그인 화면에서 present했다면
간단하게 dismiss해주면 됩니다.
만약, 회원가입 화면에서 present했다면
로그인 화면으로 돌아가야하기에 dismiss로는 충분하지 않습니다. 회원가입 화면까지 pop해줄 필요가 있어요.
guard let presentingVC = presentingViewController as? UINavigationController else { return } dismiss(animated: true) { presentingVC.popToRootViewController(animated: false) }
Swift
복사
presentingViewController: 현재 VC를 Present시켜준 VC를 말합니다. 유튜브 프로젝트로 치면 로그인VC, 회원가입VC가 그 일을 하겠죠?
as? UINavigationController: 우리를 띄워준 로그인, 회원가입 뷰의 RootVC가 NavigationController이기 때문에 NaviController가 맞는지 확인하는 부분입니다. Presenting해준 Controller가 우리가 원하는 VC가 아니라면 return해줘야겠죠?
completion: completion이 있어야 하는 부분에 argument가 없고, 뒤에 closure가 있는게 보일겁니다. 맨 뒤에 있는 매개변수가 closure라면 저런식으로 밖에다가 코드를 쓸 수 있습니다.
popToRootViewController: RootViewController로 자동적으로 이동시켜주는 메소드입니다. 해당 메소드는 로그인, 회원가입뷰 어디서나 RootVC(로그인뷰)로 이동시켜주기 때문에 편리합니다.

SubView To RootView

이번 과제에서 로그인 상태라면 바로 메인으로 가는 코드를 구현했습니다.
따라서 우리는 탭바뷰에서 로그아웃하는 방식도 알아야 합니다.
따로, LoginManager를 생성해두고 Logout하는 코드를 짰습니다.
func setLoginOut() { let navi = UINavigationController.init(rootViewController: LoginVC()) UIApplication.shared.keyWindow?.replaceRootViewController(navi, animated: true, completion: nil) }
Swift
복사
로그아웃 버튼을 누르면 navi(완전한 Root)로 이동할겁니다.
replaceRootViewController는 제가 UIWindow에 Extension으로 넣어둔 코드입니다.
extension UIWindow { func replaceRootViewController(_ replacementController: UIViewController, animated: Bool, completion: (() -> Void)?) { let snapshotImageView = UIImageView(image: self.snapshot()) self.addSubview(snapshotImageView) let dismissCompletion = { () -> Void in // dismiss all modal view controllers self.rootViewController = replacementController self.bringSubviewToFront(snapshotImageView) if animated { UIView.animate(withDuration: 0.4, animations: { () -> Void in snapshotImageView.alpha = 0 }, completion: { (success) -> Void in snapshotImageView.removeFromSuperview() completion?() }) } else { snapshotImageView.removeFromSuperview() completion?() } } if self.rootViewController!.presentedViewController != nil { self.rootViewController!.dismiss(animated: false, completion: dismissCompletion) } else { dismissCompletion() } } func snapshot() -> UIImage { UIGraphicsBeginImageContextWithOptions(bounds.size, false, UIScreen.main.scale) drawHierarchy(in: bounds, afterScreenUpdates: true) guard let result = UIGraphicsGetImageFromCurrentImageContext() else { return UIImage.init() } UIGraphicsEndImageContext() return result } }
Swift
복사
replaceRootViewController: 이동할 rootViewController를 받아서 해당 VC로 이동시켜줍니다. 이동은 우리가 rootViewController이길 원하는 뷰 위에 다른 뷰가 없을 때까지 dismiss를 반복하는 방식으로 RootVC 이동을 구현했습니다.