[UIKit-07] Image 추가하여 Onboarding 화면 구성
이번 포스팅에서는 Onboarding 화면 구성을 마치도록 하겠다. 이미지를 추가하고, 텍스트를 넣어 화면이 변화하는 것에 따라 다르게 표현을 해보도록 하자.
우선 이미지 3개를 다운로드 받고, Assets에 추가해준다. 그런 다음 아래의 사진과 같이 셋팅을 해줬는데, Resizing을 Preserve Vector Data로 체크하였고 Scales를 Single Scale로 하였다. (Vector Data이기에 Scale이 의미가 없다.)
우선 OnboardingViewController.swift 파일 코드를 작성하도록 하자.
OnboardingViewController.swift
import UIKit
class OnboardingViewController: UIViewController {
let stackView = UIStackView()
let imageView = UIImageView()
let label = UILabel()
let heroImageName: String
let titleText: String
override func viewDidLoad() {
super.viewDidLoad()
style()
layout()
}
init(heroImageName: String, titleText: String) {
self.heroImageName = heroImageName
self.titleText = titleText
super.init(nibName: nil, bundle: nil)
}
// required constructor
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension OnboardingViewController {
func style() {
view.backgroundColor = .systemBackground
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.spacing = 20
//Image
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = .scaleAspectFit
imageView.image = UIImage(named: heroImageName)
// Label
label.translatesAutoresizingMaskIntoConstraints = false
label.textAlignment = .center
label.font = UIFont.preferredFont(forTextStyle: .title3)
label.adjustsFontForContentSizeCategory = true
label.numberOfLines = 0
label.text = titleText
}
func layout() {
stackView.addArrangedSubview(imageView)
stackView.addArrangedSubview(label)
view.addSubview(stackView)
NSLayoutConstraint.activate([
stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
stackView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
stackView.leadingAnchor.constraint(equalToSystemSpacingAfter: view.leadingAnchor, multiplier: 1),
stackView.trailingAnchor.constraint(equalToSystemSpacingAfter: stackView.trailingAnchor, multiplier: 1)
])
}
}
하드코딩 방식이 아닌, heroImageName에서 이미지명을 입력받고 titleText에서 description에 해당하는 Text를 입력받고자 한다.
그런 다음, layout들을 잡아준다.
이제 상위 파일인 OnboardingContainerViewController에서 이를 불러와서 적용시켜보자.
OnboardingContainerViewController
import UIKit
class OnboardingContainerViewController: UIViewController {
let pageViewController: UIPageViewController
var pages = [UIViewController]()
var currentVC: UIViewController
let closeButton = UIButton(type: .system)
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
self.pageViewController = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
let page1 = OnboardingViewController(heroImageName: "delorean", titleText: "Bankey is faster, easier to use, and has a brand new look and feel that will make you feel like you are back in 1989.")
let page2 = OnboardingViewController(heroImageName: "world", titleText: "Move your money around the world quickly and securely")
let page3 = OnboardingViewController(heroImageName: "thumbs", titleText: "Learn more at www.bankey.com")
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()
setup()
style()
layout()
}
private func setup() {
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!
}
private func style() {
closeButton.translatesAutoresizingMaskIntoConstraints = false
closeButton.setTitle("Close", for: [])
closeButton.addTarget(self, action: #selector(closeTapped), for: .primaryActionTriggered)
view.addSubview(closeButton)
}
private func layout() {
NSLayoutConstraint.activate([
closeButton.leadingAnchor.constraint(equalToSystemSpacingAfter: view.leadingAnchor, multiplier: 2),
closeButton.topAnchor.constraint(equalToSystemSpacingBelow: view.safeAreaLayoutGuide.topAnchor, multiplier: 2)
])
}
}
// 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: - Actions
extension OnboardingContainerViewController {
@objc func closeTapped(_ sender: UIButton) {
// TODO
}
}
page1, 2, 3을 각각 다르게 선언을 해주었다. 그리고 마지막 부분에 button을 추가해주었다.
코드 자체는 저번에 대부분 구현하였고 설명을 적었던 것이기에 설명을 생략하도록 하겠다.
이제 마지막으로 AppDelegate에서 해당 파일을 root로 설정하여 한번 띄워보자.
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 = OnboardingContainerViewController()
return true
}
}
댓글남기기