[UIKit-06] Onboarding 화면 추가하기
지난 포스팅까지는 Login 화면을 구축 하였었다. 이번 포스팅 부터 Onboarding 화면을 만들어 보겠다.
아래는 구현 할 화면이다. swaping을 통해 뷰가 전환 되는 형태이다.
Onboarding은 많은 어플리케이션에서 사용되고 있다. 주로 어플리케이션을 처음 설치한 유저들에게 어떠한 어플리케이션인지 간략하게 소개할 때 이용되는 것 같았다.
우선 전체 코드를 통해 차근차근 살펴보자.
Onboarding이라는 폴더를 하나 생성하였고, 하위에 OnboardingContainerViewController.swift 파일을 생성하였다.
그리고 시뮬레이터에서 확인을 위해 AppDelegate를 수정 해주겠다.
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
window?.backgroundColor = .systemBackground
// window?.rootViewController = LoginViewController()
window?.rootViewController = OnboardingContainerViewController()
return true
}
}
다음은 OnboardingContainerViewController이다. 전체 코드를 보면서 중요한 부분은 체크하면서 넘어가자.
OnboardingContainerViewController.swift
import UIKit
class OnboardingContainerViewController: UIViewController {
let pageViewController: UIPageViewController
var pages = [UIViewController]()
var currentVC: UIViewController {
didSet {
}
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
self.pageViewController = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
let page1 = ViewController1()
let page2 = ViewController2()
let page3 = ViewController3()
pages.append(page1)
pages.append(page2)
pages.append(page3)
currentVC = pages.first!
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemPurple
addChild(pageViewController)
view.addSubview(pageViewController.view)
pageViewController.didMove(toParent: self)
pageViewController.dataSource = self
pageViewController.view.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
view.topAnchor.constraint(equalTo: pageViewController.view.topAnchor),
view.leadingAnchor.constraint(equalTo: pageViewController.view.leadingAnchor),
view.trailingAnchor.constraint(equalTo: pageViewController.view.trailingAnchor),
view.bottomAnchor.constraint(equalTo: pageViewController.view.bottomAnchor),
])
pageViewController.setViewControllers([pages.first!], direction: .forward, animated: false, completion: nil)
currentVC = pages.first!
}
}
// MARK: - UIPageViewControllerDataSource
extension OnboardingContainerViewController: UIPageViewControllerDataSource {
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
return getPreviousViewController(from: viewController)
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
return getNextViewController(from: viewController)
}
private func getPreviousViewController(from viewController: UIViewController) -> UIViewController? {
guard let index = pages.firstIndex(of: viewController), index - 1 >= 0 else { return nil }
currentVC = pages[index - 1]
return pages[index - 1]
}
private func getNextViewController(from viewController: UIViewController) -> UIViewController? {
guard let index = pages.firstIndex(of: viewController), index + 1 < pages.count else { return nil }
currentVC = pages[index + 1]
return pages[index + 1]
}
func presentationCount(for pageViewController: UIPageViewController) -> Int {
return pages.count
}
func presentationIndex(for pageViewController: UIPageViewController) -> Int {
return pages.firstIndex(of: self.currentVC) ?? 0
}
}
// MARK: - ViewControllers
class ViewController1: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemRed
}
}
class ViewController2: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemGreen
}
}
class ViewController3: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBlue
}
}
우선 UIPageViewController를 통해 pageViewController를 선언하였고, pages를 배열을 통해 가져온돠.
그리고 page들을 ViewController로써 추가를 해주고, currentVC를 pages배열의 가장 첫 index로 지정을 해준다.
주목할 부분이 있다.
addChild(pageViewController)
view.addSubview(pageViewController.view)
pageViewController.didMove(toParent: self)
3 Step에 의해서 child view controller가 추가된다.
- 처음 addChild를 통해 child로 추가하고 싶은 ViewController를 파라미터로 넣게 된다.
- child를 넣은 다음, addSubview를 통해 view에 추가하게 된다.
- 마지막으로 didMove를 통하여 모든 UI ViewController 이벤트를 연결하게 된다. 이렇게 viewdidload, viewwillapper과 같은 일어나는 모든 life cycle를 포함하게 된다.
이 3가지 스텝은 Parent VC에 Child VC를 embed하고 싶을 때, 사용하게 되므로 꼭 기억하고 넘어가야겠다.
다음으로 pageViewController.dataSource = self 를 통해, 얼마나 많은 페이지가 있는지, 다음으로 보여져야할 페이지는 어떤 것인지 등을 넘겨주게 된다.
다른 것들은 기본적인 코드이므로, 읽어보면 바로 이해가 가능하여 설명은 생략하도록 하겠다.
댓글남기기