손쉬운 업데이트를 위해 대부분의 회사에서 하이브리드 앱으로 개발을 합니다.
이 과정에 특정 서비스의 경우 웹뷰를 따로 구성해야하는 상황이 발생합니다.
예를들어, AViewController, BViewController와 같이 UIViewController를 상속받는 ViewController를 따로 생성하여 웹뷰를 구성하게 됩니다. 이러한 구성에 따로 생성된 뷰컨트럴러간 스위칭이 필요한 경우가 발생합니다.
+ UINavigationController
- AViewController
- BViewController
- CViewController
위와 같은 경우 마지막에 추가된 CViewController가 화면에 출력됩니다.
UINavigationController의 뷰컨트럴러 배열의 순서를 변경하면 원하는 뷰컨트럴러를 최상단으로 올릴 수 있습니다.
다음은 해당 기능을 구현한 클래스입니다.
extension UINavigationController {
// 주어진 UIViewController를 제거합니다.
func removeVC(_ kindClass: AnyClass) {
self.viewControllers = self.viewControllers.filter {!$0.isKind(of:kindClass)}
}
// 주어진 UIViewController가 존재하는지 체크
func containsVC(_ kindClass: AnyClass) -> Bool {
return self.viewControllers.contains(where: {$0.isKind(of:kindClass)})
}
// 주어진 UIViewController를 최상위에 출력되도록 합니다.
func setTopVC(_ kindClass: AnyClass) -> UIViewController? {
var stack: [UIViewController] = self.viewControllers
var index: Int = 0
for vc in stack {
if vc.isKind(of: kindClass) {
stack.remove(at: index)
stack.append(vc)
self.viewControllers = stack
return vc
}
index += 1
}
return nil
}
// 주어진 UIViewController를 존재하는 경우 최상위에 출력되도록 합니다.
func activateVC(_ kindClass: AnyClass) {
if containsVC(kindClass) {
_ = setTopVC(kindClass)
}
}
}
extension UIViewController {
// 옵져버 추가
func addObserver(_ aSelector: Selector) {
NotificationCenter.default.addObserver(self,
selector: aSelector,
name: NSNotification.Name(self.theClassName),
object: nil)
}
// 옵져버 삭제
func removeObserver() {
NotificationCenter.default.removeObserver(self)
}
// 타깃 뷰컨트럴러로 데이터 전달
func post(_ targetClassName: String, _ userInfo: [AnyHashable : Any], _ delay: Double = 0.0) {
let delayTime: Double = (delay < 0) ? 1.0 : delay
Timer.scheduledTimer(withTimeInterval: delayTime, repeats: false, block: {_ in
NotificationCenter.default.post(name: NSNotification.Name(targetClassName),
object: nil,
userInfo: userInfo)
})
}
}
//
// BViewController
//
override func viewDidLoad() {
super.viewDidLoad()
addObserver(#selector(onCommand))
... 중간 생략 ...
}
deinit {
removeObserver()
}
... 중간 생략 ...
@objc func onCommand(notification: Notification) {
guard notification.name.rawValue == self.theClassName else { return }
guard let userInfo = notification.userInfo else { return }
let name = userInfo["name"] as? String ?? ""
if name == "이벤트이름" {
let paramString = userInfo["data"] as! String
self.sendScript(name: "이벤트이름", result: paramString)
}
else {
//self.userMethod = name
//self.userInfo = userInfo["data"] as! Dictionary <String, Any>
}
}
//
// 사용 방법
// : 아래 내용은 CViewController에서 BViewController로 이벤트 데이터를 전달 및 화면 스위칭한다.
//
// BViewController에 이벤트 데이터 정보 전달
post("BViewController", ["name" : "이벤트이름", "data" : "전달할 데이터 정보"])
// 0.5초 딜레이 주어 웹뷰 로딩 시간을 주었다.
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.navigationController?.activateVC(BViewController.self)
}
2020/12/11 - [iOS/Swift] - UIViewController 스위칭
2020/12/11 - [개발노트] - PlantUML 설치 (Mac OS X)
2020/12/11 - [분류 전체보기] - Tones And I - Dance Monkey
2020/12/11 - [lyrics] - Beyonce - Halo
2020/12/10 - [iOS/Objective-C] - 웹뷰에서 javascript 함수 동기식 호출
2020/12/10 - [iOS/Tips] - Fat Static Library 빌드 (2/2)
2020/12/10 - [iOS/Tips] - Fat Static Library 빌드 (1/2)
2020/12/10 - [iOS/Tips] - Custom UserAgent 설정
2020/12/10 - [iOS/Tips] - CocoaPods 설치 및 제거
2020/12/10 - [iOS/Tips] - Clang diagnostic 경고 무시하기
2020/12/10 - [개발노트] - Bluetooth UUID
2020/12/08 - [개발노트] - 모바일 앱 메모리덤프 이슈 해결방법
2020/12/08 - [프로그래밍/Java Script] - Android, iOS 앱 설치여부 체크 및 스토어 이동
'개발 > iOS' 카테고리의 다른 글
디버깅 차단 처리 (Anti Debug) (0) | 2020.12.15 |
---|---|
bundle id 알아내기 (0) | 2020.12.14 |
웹뷰에서 javascript 함수 동기식 호출 (0) | 2020.12.10 |
Fat Static Library 빌드 (2/2) (0) | 2020.12.10 |
Fat Static Library 빌드 (1/2) (1) | 2020.12.10 |