우리는 주작톡의 런치 이미지가 너무 빨리 없어져버리는 것에 대해 딜레이를 주기로 했다.
위 코드는 튜터님의 도움을 받아 완성된 딜레이코드이다. 실행되면 딜레이가 잘 들어가는 걸 확인할 수 있었다.
그런데 만약 내가 마음이 바뀌어서 런치스크린에 페이드인/아웃 애니메이션을 넣는다던지 특정 작업을 수행하고 싶을 수도 있지 않을까 해서 코드를 재구성 해보고 싶었다.
한번 해보자~
일단 잘 이해가 가지 않는 부분 부터 차근차근 알아보면서 해석해보려고 한다.
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
이 메서드는 앱이 처음 실행될 때 호출되는데,
guard let windowScene = (scene as? UIWindowScene)
scene
이 UIWindowScene
타입인지 확인하고, 맞다면 windowScene
에 할당한다라는 말이다. guard let
을 사용한 이유는 만약 scene
이 UIWindowScene
이 아니면 앱을 더 이상 진행하지 않기 위해서이다.
만약 캐스팅에 실패하면 else
로 넘어가서 return
문을 실행. 그리고 이 함수 실행이 중단된다.
window = UIWindow(windowScene: windowScene)
새로운 UIWindow
객체를 만들고 windowScene
을 기반으로 설정한다는 것인데 이건 앱의 기본 창을 설정하는 과정이다.
여기서 잠깐 위에 나온 return
에 대해 정리하자면, return은 함수나 메서드의 실행을 종료하고 호출한 위치로 돌아가는 역할을 하는 친구다. 현재 함수가 더이상 실행되지 않도록 하고 호출한 곳으로 반환을 해주는 느낌으로 되돌아가다의 return 인 것이다.
함수 종료
: return
문이 실행되면 해당 함수의 실행이 즉시 종료된다. 이는 함수의 마지막에 도달할 때까지 코드를 계속 실행하지 않겠다는 의미이다.
값 반환
: return
문은 함수가 어떤 값을 반환해야 할 경우 그 값을 지정할 수 있다. 예를 들어 func add(a: Int, b: Int) -> Int { return a + b }
와 같은 경우, 두 수의 합을 반환한다.
제어 반환
: 함수가 종료되면, 제어는 그 함수를 호출한 코드로 돌아간다. 예를 들어 let result = add(a: 5, b: 3)
에서 add
함수가 종료되면 제어가 이 호출 문으로 돌아가고, 결과값이 result
에 저장된다.
return
문을 사용하면 함수의 흐름을 잘 파악할 수 있고 언제 함수가 종료되고 제어가 어디로 돌아가는지 쉽게 이해도 가능하다.
결론적으로 함수의 실행을 관리하는 중요한 도구라고 생각하면 된다.
window?.rootViewController = UIStoryboard(name: "LaunchScreen", bundle: nil).instantiateInitialViewController()
window?.makeKeyAndVisible()
UIStoryboard(name: "LaunchScreen", bundle: nil).instantiateInitialViewController()
"LaunchScreen"이라는 이름의 스토리보드를 불러와서 해당 스토리보드의 첫 화면 (초기 뷰 컨트롤러) 을 rootViewController
로 설정.
window?.makeKeyAndVisible()
현재 window를 주 창(key window)으로 만들고, 화면에 표시되도록 설정하는 것
animateFadeOutAndSwitchToMain()
애니메이션을 시작하는 메서드를 호출한다. 여기서는 바로 페이드 아웃 애니메이션을 시작하여 런치 화면을 부드럽게 사라지게 해준다.
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1.5) {
animateFadeOutAndSwitchToMain()
}
DispatchQueue.main.asyncAfter
코드는 1.5초 후에 특정 작업을 예약하여 실행할 수 있도록 한다.
DispatchTime.now() + 1.5
현재 시간에서 1.5초를 더한 시점이다. 즉, 이 코드는 1.5초 후에 animateFadeOutAndSwitchToMain()
함수가 실행되도록 예약해주는 것이다.
func animateFadeOutAndSwitchToMain() {
guard let window = window else { return }
UIView.animate(withDuration: 1.0, animations: {
window.alpha = 0
}) { _ in
animateFadeOutAndSwitchToMain()
페이드 아웃 애니메이션 후 메인 화면으로 전환하는 함수.
guard let window = window else { return }
window가 있는지 확인하고, 없으면 메서드를 종료.
UIView.animate(withDuration: animations: completion:)
1초 동안 창의 투명도(alpha) 를 0으로 줄이는 페이드 아웃 애니메이션을 실행한다. alpha
는 0
이 완전히 투명하다는 의미이다.
이 메서드는 페이드 아웃 애니메이션을 수행하고, 애니메이션이 완료된 후 메인 화면으로 전환하는 역할을 한다.
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
if let mainVC = mainStoryboard.instantiateInitialViewController() {
window.rootViewController = mainVC
window.makeKeyAndVisible()
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
Main.storyboard 파일을 사용하여 메인 화면을 불러오고,
instantiateInitialViewController()
메인 스토리보드에서 설정된 초기 화면을 인스턴스화 해준다는 것이다.
window.rootViewController = mainVC
현재 창의 rootViewController
를 런치 화면에서 메인 화면으로 교체한다는 의미.
UIView.animate(withDuration: 1.0, animations: {
window.alpha = 1
UIView.animate
iOS에서 뷰에 대한 애니메이션을 설정할 때 사용하는 메서드인데, 애니메이션의 지속 시간과 실행할 애니메이션 효과를 지정할 수 있다.
withDuration: 1.0
애니메이션의 지속 시간을 초 단위로 설정할 수 있는데, 여기서는 1.0초 동안 애니메이션이 실행된다. 1초 동안 페이드 인 효과가 진행된다는 의미.
animations:
이 클로저 안에 애니메이션으로 실행할 코드를 작성한다. 해당 코드의 내용이 지정된 시간 동안(여기서는 1초) 부드럽게 변화하게 된다.
window.alpha = 1
alpha: 뷰의 투명도를 나타내는 속성인데, 값의 범위는 0에서 1까지이며, 0은 완전히 투명함을, 1은 완전히 불투명함을 의미한다.
전체 코드를 보면 0에서 1로 가는 부분을 확인하기가 더 쉽다.
오늘 런치스크린 이미지의 노출시간을 설정하는 것과 더불어 페이드인/아웃 애니메이션을 구현하는 과정을 배우게 됐다.
처음에는 런치스크린을 일정시간 보여주기 위해 애증의 디스패치큐를 이용하여 지연시간을 주었다. 그래도 타이머 만들 때 몇 번 쓰고 공부했다고 좀 알고 있는게 신기하다.
그렇게 1.5초 정도 보여주고 메인화면으로 자연스럽게 전환하는 흐름을 만들 수 있었는데 저번에 공부했던 비동기 처리에 대해 다시 한번 좀 공부를 하게 되었고, 앱 전환에서 지연이 필요한 상황에 적절히 사용할 수 있는 기법이라고 생각했다.
페이드인/아웃 애니메이션은 사실 앱을 다 만들고 나서 디테일 요소를 추가하고 싶은 마음에 구글링으로 알아보았다. 이런 사소한 애니메이션이 사용자 경험을 향상 시키는 요소가 될 수 있으니 말이다.
애니메이션 과정에서 알게 된 점은 UIView.animate 메서드를 이용하면 복잡한 코드를 작성하지 않고도 더 직관적인 애니메이션 효과를 구현할 수 있다는 걸 알게 됐다. 또한 뷰의 투명도를 활용하여 자연스러운 페이드아웃을 했는데, 앱의 전환이나 정보표시에도 유용하게 쓰일 수 있을 것 같다고 느꼈다.
좀 더 다양한 애니메이션 효과를 적용해보고 싶은 욕심이 생긴 듯 하다.
자자잔