1. UIApplication의 KeyWindow 대체
import UIKit
extension UIApplication {
var keyWindow: UIWindow? {
connectedScenes
.compactMap { $0 as? UIWindowScene }
.flatMap { $0.windows }
.first { $0.isKeyWindow }
}
}
‘keyWindow’ was deprecated in iOS 13.0: Should not be used for applications that support multiple scenes as it returns a key window across all connected scenes 에러를 방지하기 위함입니다.
2. 뷰 컨트롤러에서 최상위 뷰 컨트롤러를 반환하는 함수 작성
import UIKit
extension UIViewController {
/// 현재 표시된 최상위 뷰 컨트롤러 반환
func getTopMostViewController() -> UIViewController {
if let presentedViewController = self.presentedViewController {
return presentedViewController.getTopMostViewController()
} else if let navigationController = self as? UINavigationController {
return navigationController.visibleViewController?.getTopMostViewController() ?? navigationController
} else if let tabBarController = self as? UITabBarController {
return tabBarController.selectedViewController?.getTopMostViewController() ?? tabBarController
} else {
return self
}
}
}
3. 뷰 컨트롤러 오브젝트에서 다음과 같이 .getTopMostViewController() 사용
if let topViewController = UIApplication.shared.keyWindow?.rootViewController?.getTopMostViewController() {
// ...
}
현재 키 윈도우에 있는 rootViewController의 최상위 뷰 컨트롤러를 반환합니다.
예제: SwiftUI에서 빠른 Alert 띄우기
import UIKit
struct QuickAlert {
static func show(
_ title: String,
message: String? = nil,
preferredStyle: UIAlertController.Style = .alert,
completionHandler: ((UIAlertAction) -> Void)? = nil
) {
let alert = UIAlertController(
title: title,
message: message,
preferredStyle: .alert
)
let alertAction = UIAlertAction(
title: "확인",
style: .default,
handler: completionHandler
)
alert.addAction(alertAction)
DispatchQueue.main.async {
if let topViewController = UIApplication.shared.keyWindow?.rootViewController?.getTopMostViewController() {
topViewController.present(alert, animated: true, completion: nil)
}
}
}
}
최상위 뷰 컨트롤러를 찾아서 UIKit의 UIAlert을 띄웁니다.
UIKit에서도 사용할 수 있고, 아래 코드처럼 SwiftUI에서도 원하는 곳에서 바로 사용할 수 있습니다.
.onChange(of: isReminderOn) { newValue in
QuickAlert.show(
"no_alert_permission_title",
message: "no_alert_permission_detail"
) { _ in
// 컴플리션 핸들러 작업
}
}





0개의 댓글