rootViewController를 애니메이션과 스왑하시겠습니까?
앱 대리인을 통해 탭 모음이 있는 다른 루트 뷰 컨트롤러로 스왑하려고 하는데 전환 애니메이션을 추가하려고 합니다.기본적으로 애니메이션 없이 보기만 표시됩니다.
let tabBar = self.instantiateViewController(storyBoard: "Main", viewControllerID: "MainTabbar")
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.window = UIWindow(frame: UIScreen.main.bounds)
appDelegate.window?.rootViewController = tabBar
appDelegate.window?.makeKeyAndVisible()
그렇게 해서 다른 루트뷰 컨트롤러로 스왑했습니다.
사용할 수 있습니다.UIView.transition(with: view)
대체하기 위해rootViewController
상당한UIWindow
:
guard let window = UIApplication.shared.keyWindow else {
return
}
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "MainTabbar")
// Set the new rootViewController of the window.
// Calling "UIView.transition" below will animate the swap.
window.rootViewController = vc
// A mask of options indicating how you want to perform the animations.
let options: UIView.AnimationOptions = .transitionCrossDissolve
// The duration of the transition animation, measured in seconds.
let duration: TimeInterval = 0.3
// Creates a transition animation.
// Though `animations` is optional, the documentation tells us that it must not be nil. ¯\_(ツ)_/¯
UIView.transition(with: window, duration: duration, options: options, animations: {}, completion:
{ completed in
// maybe do something on completion here
})
스위프트 4
다음에 함수 붙여넣기AppDelegate
:
func setRootViewController(_ vc: UIViewController, animated: Bool = true) {
guard animated, let window = self.window else {
self.window?.rootViewController = vc
self.window?.makeKeyAndVisible()
return
}
window.rootViewController = vc
window.makeKeyAndVisible()
UIView.transition(with: window,
duration: 0.3,
options: .transitionCrossDissolve,
animations: nil,
completion: nil)
}
다른 루트 뷰 컨트롤러로 스왑하려고 하는데... 전환 애니메이션을 추가하려고 합니다.
저는 이것을 하는 앱을 가지고 있습니다: 그것은 애니메이션으로 루트 뷰 컨트롤러를 변경합니다(알부멘이라고 함).
하지만 제 앱은 루트 뷰 컨트롤러를 실제로 변경하지는 않습니다.루트 보기 컨트롤러는 변경되지 않는 사용자 지정 컨테이너 보기 컨트롤러입니다.보기가 표시되지 않으며 기능도 없습니다.이것의 유일한 일은 변화가 일어나는 장소입니다. 즉, 한 하위 보기 컨트롤러를 다른 하위 보기 컨트롤러로 교체하여 전환 애니메이션이 작동합니다.
즉, 계층 맨 위에 있는 보기 컨트롤러 계층에 하나의 보기 컨트롤러를 추가하면 전체 문제가 깔끔하고 올바르게 해결됩니다.
대안 솔루션:
let stb = UIStoryboard(name: "YOUR_STORYBOARD_NAME", bundle: nil)
let rootVC = stb.instantiateViewController(withIdentifier: "YOUR_TABBAR_VIEWCONTROLLER_NAME")
let snapshot = (UIApplication.shared.keyWindow?.snapshotView(afterScreenUpdates: true))!
rootVC.view.addSubview(snapshot)
UIApplication.shared.keyWindow?.rootViewController = rootVC
UIView.transition(with: snapshot,
duration: 0.4,
options: .transitionCrossDissolve,
animations: {
snapshot.layer.opacity = 0
},
completion: { status in
snapshot.removeFromSuperview()
})
사용해 보십시오.
UIView.transition(from: appdelegate.window.rootViewController!.view, to: tabbar.view, duration: 0.6, options: [.transitionCrossDissolve], completion: {
_ in
appdelegate.window.rootViewController = tabbar
})
업데이트된 Swift 5.3 버전:
let foregroundedScenes = UIApplication.shared.connectedScenes.filter { $0.activationState == .foregroundActive }
let window = foregroundedScenes.map { $0 as? UIWindowScene }.compactMap { $0 }.first?.windows.filter { $0.isKeyWindow }.first
guard let uWindow = window else { return }
uWindow.rootViewController = customTabBarController
UIView.transition(with: uWindow, duration: 0.3, options: [.transitionCrossDissolve], animations: {}, completion: nil)
}
다음은 예입니다.transitionCrossDissolve
와 함께transform translation Y
snapshotView의 경우 일반 전환 애니메이션보다 더 좋아 보입니다.
테스트 대상Swift 4~5, iOS 11 ~ 15.7
if let window = UIApplication.shared.keyWindow {
var snapShot = UIView()
let destinationVC = UIViewController()
if let realSnapShot = window.snapshotView(afterScreenUpdates: true) {
snapShot = realSnapShot
}
destinationVC.view.addSubview(snapShot)
window.rootViewController = destinationVC
window.makeKeyAndVisible()
UIView.transition(
with: window,
duration: 0.5,
options: .transitionCrossDissolve,
animations: {
snapShot.transform = CGAffineTransform(translationX: 0, y: snapShot.frame.height)
},
completion: { status in
snapShot.removeFromSuperview()
}
)
}
d.felber의 답변을 바탕으로 이에 대한 도우미 클래스를 만들었습니다.
import UIKit
class ViewPresenter {
public static func replaceRootView(for viewController: UIViewController,
duration: TimeInterval = 0.3,
options: UIView.AnimationOptions = .transitionCrossDissolve,
completion: ((Bool) -> Void)? = nil) {
guard let window = UIApplication.shared.keyWindow else {
return
}
guard let rootViewController = window.rootViewController else {
return
}
viewController.view.frame = rootViewController.view.frame
viewController.view.layoutIfNeeded()
UIView.transition(with: window, duration: duration, options: options, animations: {
window.rootViewController = viewController
}, completion: completion)
}
}
다음과 같이 사용할 수 있습니다.
let loginVC = SignInViewController(nibName: "SignInViewController", bundle: nil)
ViewPresenter.replaceRootView(for: loginVC)
또는
ViewPresenter.replaceRootView(for: loginVC, duration: 0.3, options: .transitionCrossDissolve) {
(bool) in
// do something
}
언급URL : https://stackoverflow.com/questions/41144523/swap-rootviewcontroller-with-animation
'programing' 카테고리의 다른 글
FontAwesome 아이콘의 아이콘 색상, 크기 및 그림자 스타일 설정 방법 (0) | 2023.08.13 |
---|---|
자바.java.javaNoClassDefFoundError:Log/apache/http/ProtocolVersion 확인 실패 (0) | 2023.08.13 |
기록 없이 새 분기를 푸시하는 방법 (0) | 2023.08.13 |
UI 웹 보기에서 사용자 에이전트 변경 (0) | 2023.08.13 |
증분이 5인 UI 슬라이더 (0) | 2023.08.13 |