티스토리 뷰
화면 전환에서 현재 뷰를 dismiss 혹은 navigationViewController에서 pop 한 후 다른 뷰를 present 혹은 push 하는 부분에서
막혔던 과정을 포스팅해보겠습니다.
현재 뷰의 계층 상태는 rootView 와 각 각 다른 정보와 기능을 다루는 2개의 뷰로 이루어져 있습니다.
편의상 rootView, childView1, childView2 로 부르겠습니다.
rootView에서 childView1을 불러오고
childView1 에서의 작업을 끝내고 childView2로 넘어가려고 합니다.
childView1은 더 이상 남아있을 필요가 없기때문에 childView2로 가기전 childView1을 없애주고 넘어가려고 합니다.
떠오른 생각은 'childView1를 종료하고 completion을 이용해 childView2 를 불러오면 되겠구나' 였습니다.
그리고 작성한 코드는,
import UIKit
class ChildVC1: UIViewController {
func showChildVC2 {
self.dismiss(animated: false, completion: {
let childVC2 = self.storyboard?.instantiateViewController(identifier: "childVC2") as! ChildVC2
childVC2.modalPresentationStyle = .fullScreen
self.present(childVC2, animated: true, completion: nil)
})
}
}
하지만 이 방법은 작동하지 않았습니다.
그 이유는 마지막 줄의 self.present... 때문인데
childVC1을 dismiss 한 후에는 더이상 childVC1이 view 상에 존재하지 않기 때문에 self 는 없는 값을 불러오게 됩니다.
그리고 여러시도 끝에 찾아 낸 방법은,
import UIKit
class ChildVC1: UIViewController {
func showChildVC2 {
let rootView = presentingViewController
self.dismiss(animated: false, completion: {
let childVC2 = self.storyboard?.instantiateViewController(identifier: "childVC2") as! ChildVC2
childVC2.modalPresentationStyle = .fullScreen
rootView?.present(childVC2, animated: true, completion: nil)
})
}
}
presentingViewController 는 chilidView1 을 불러온 뷰 즉 rootView 를 가리킵니다.
rootView는 childVIew1 이 불러와지기 전부터 존재했고 childView1이 사라지더라도 뷰에서 제거하지 않는 이상 존재합니다.
이 방법을 통해 일반 뷰에서는 해결이 되었습니다.
하지만 제 프로젝트에서는 navigationViewContorller에서는 위 방법이 작동하지 않았고
다른 방법이 필요했습니다.
먼저 Swift 자체에는 navigationViewController push 와 pop 의 completion handler 기능이 없기 때문에 extension을 통해 이기능을 추가 해줍니다.
extension UINavigationController {
func popViewController(animated: Bool, completion:@escaping (()->())) -> UIViewController? {
CATransaction.setCompletionBlock(completion)
CATransaction.begin()
let poppedViewController = self.popViewController(animated: animated)
CATransaction.commit()
return poppedViewController
}
func pushViewController(_ viewController: UIViewController, animated: Bool, completion:@escaping (()->())) {
CATransaction.setCompletionBlock(completion)
CATransaction.begin()
self.pushViewController(viewController, animated: animated)
CATransaction.commit()
}
}
그리고 rootView에서 childView1으로 화면이 전환될 때 childView1에 rootView 자신의 객체를 저장해 줍니다.
사용한 코드로는,
import UIKit
class RootView: UIViewController {
func showChildVC1() {
let childVC1 = self.storyboard?.instantiateViewController(identifier: "childVC1") as! ChildVC1
childVC1.rootView = self
self.navigationController?.pushViewController(childVC1, animated: true)
}
}
class ChildVC1: UIViewController {
var rootView: RootView?
func showChildVC2 {
self.navigationController?.popViewController(animated: true, completion: {
let childVC2 = self.storyboard?.instantiateViewController(identifier: "childVC2") as! ChildVC2
self.rootView?.navigationController?.pushViewController(childVC2, animated: true)
})
}
}
입니다.
'Develop > iOS' 카테고리의 다른 글
[iOS]전화 바로 걸기: 전화 번호와 특수문자 (0) | 2021.08.02 |
---|---|
[Swift] textField를 통해 PickerView를 사용시 문제점 개선한 방법 (0) | 2020.11.04 |
[Swift] Alamofire And JSON (0) | 2020.11.01 |
[Swift]Naver Map API Location Button 오류 (0) | 2020.08.24 |
[API]Firebase setValue completion problem (0) | 2020.08.16 |
- Total
- Today
- Yesterday
- ios
- Push
- provisioning profile
- TextField
- 프로비저닝 프로파일
- 프로파일
- MVVM
- subject
- notification
- relay
- Clean Architecture
- RxSwift
- certificate
- Apple
- 코드사이닝
- rxcocoa
- 프로비저닝
- TabBar
- dip
- Crossing Boundaries
- CSR
- 동적계획법
- 아키텍처
- 클린아키텍처
- remote
- MVC
- Swift
- Rx
- APNS
- 코테
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |