Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

책 보기 Layout 구현 #87

Merged
merged 4 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import UIKit

final class BookViewController: UIViewController {
// MARK: - UI Components
private let pageViewController = UIPageViewController(
Comment on lines +3 to +5
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

영현님의 리뷰노트 메세지를 읽었을 때
저는 BookVC가 UIPageViewController를 상속 받았을 거라고 예상했는데요,
혹시 UIVC 안에 UIPageVC를 들고 있는 이유가 있나요 ??

UIPageVC가 뷰컨의 배열을 관리하는데, 그걸 또 뷰컨으로 감싸는 게 몬가가 몬가해서 여쭤봅니다 !

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

직접해본건 아니지만 PageViewController 관련 예제 코드들을 봤을때 모두 ViewController 내부에 PageViewController를 포함하는 방식으로 구현해주셨더라구요 ! 예상이지만 UIPageViewController 자체가 UINavigationController처럼 Container View Controller라서이지 않을까.. 라는 생각을 했었습니다 !

UIPageViewController를 바로 띄우는게 가능한지는 한 번 테스트해보도록 하겠습니다 !

transitionStyle: .pageCurl,
navigationOrientation: .horizontal
)

// MARK: - Property
private let viewModel: BookViewModel

// MARK: - Initialize
init(bookTitle: String, viewModel: BookViewModel) {
self.viewModel = viewModel
super.init(nibName: nil, bundle: nil)

title = bookTitle
}

required init?(coder: NSCoder) {
self.viewModel = BookViewModel()
super.init(nibName: nil, bundle: nil)

title = "책 이름"
}

// MARK: - View Life Cycle
override func viewDidLoad() {
super.viewDidLoad()

setup()
configureNavigationBar()
configureConstraints()
configurePageViewController()
}

// MARK: - Setup & Configure
private func setup() {
view.backgroundColor = .baseBackground
addChild(pageViewController)
pageViewController.delegate = self
pageViewController.dataSource = self
}

private func configureNavigationBar() {
navigationController?.navigationBar.isHidden = false
navigationController?.navigationBar.titleTextAttributes = [
.font: UIFont.ownglyphBerry(size: 17),
.foregroundColor: UIColor.mhTitle
]

// 공통 스타일 정의
let normalAttributes: [NSAttributedString.Key: Any] = [
.font: UIFont.ownglyphBerry(size: 17),
.foregroundColor: UIColor.mhTitle
]
let selectedAttributes: [NSAttributedString.Key: Any] = [
.font: UIFont.ownglyphBerry(size: 17),
.foregroundColor: UIColor.mhTitle
]

// 왼쪽 닫기 버튼
navigationItem.leftBarButtonItem = UIBarButtonItem(
title: "닫기",
normal: normalAttributes,
selected: selectedAttributes
) { [weak self] in
self?.navigationController?.popViewController(animated: true)
}

// 오른쪽 책 속지 수정 버튼
navigationItem.rightBarButtonItem = UIBarButtonItem(
title: "수정",
normal: normalAttributes,
selected: selectedAttributes
) { [weak self] in
// TODO: - 추후 책 속지 수정 페이지로 넘어가는 로직 필요
}
}

private func configureConstraints() {
view.addSubview(pageViewController.view)
pageViewController.view.fillSuperview()
}

// MARK: - Set PageviewController
private func configurePageViewController() {
guard let startViewController = makeNewPageViewController(index: 0) else { return }
let viewControllers = [startViewController]
pageViewController.setViewControllers(viewControllers, direction: .forward, animated: true, completion: nil)
}

private func makeNewPageViewController(index: Int) -> ReadPageViewController? {
// TODO: - 로직 수정 필요
return ReadPageViewController(viewModel: ReadPageViewModel(index: index))
}
}

// MARK: - UIPageViewControllerDelegate
extension BookViewController: UIPageViewControllerDelegate {
// TODO: - Page transition 감지
}

// MARK: - UIPageViewControllerDataSource
extension BookViewController: UIPageViewControllerDataSource {
func pageViewController(
_ pageViewController: UIPageViewController,
viewControllerBefore viewController: UIViewController
) -> UIViewController? {
guard let targetViewController = viewController as? ReadPageViewController else { return nil }
let pageIndex = targetViewController.getPageIndex()

return pageIndex == 0
? nil
: makeNewPageViewController(index: pageIndex - 1)
}

func pageViewController(
_ pageViewController: UIPageViewController,
viewControllerAfter viewController: UIViewController
) -> UIViewController? {
guard let targetViewController = viewController as? ReadPageViewController else { return nil }
let pageIndex = targetViewController.getPageIndex()

return pageIndex == viewModel.pageList.count - 1
? nil
: makeNewPageViewController(index: pageIndex + 1)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Foundation
import Combine

final class BookViewModel: ViewModelType {
enum Input {

}

enum Output {

}

private let output = PassthroughSubject<Output, Never>()
private var cancellables = Set<AnyCancellable>()
private(set) var pageList = ["one", "two", "three"]

func transform(input: AnyPublisher<Input, Never>) -> AnyPublisher<Output, Never> {
input.sink { event in
switch event {

}
}
.store(in: &cancellables)

return output.eraseToAnyPublisher()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import UIKit

final class ReadPageViewController: UIViewController {
// MARK: - UI Components
private let textView: UITextView = {
let textView = UITextView()
textView.font = .ownglyphBerry(size: 20)
textView.textColor = .mhTitle
textView.backgroundColor = .clear
textView.textContainerInset = UIEdgeInsets(top: 20, left: 32, bottom: 20, right: 32)
textView.layer.borderWidth = 3
textView.layer.borderColor = UIColor.mhTitle.cgColor
textView.isScrollEnabled = false
textView.isEditable = false

return textView
}()
private var textLayoutManager: NSTextLayoutManager?
private var textStorage: NSTextStorage?
private var textContainer: NSTextContainer?

// MARK: - Property
private let viewModel: ReadPageViewModel

// MARK: - Initialize
init(viewModel: ReadPageViewModel) {
self.viewModel = viewModel

super.init(nibName: nil, bundle: nil)
}

required init?(coder: NSCoder) {
self.viewModel = ReadPageViewModel(index: 0)

super.init(nibName: nil, bundle: nil)
}

// MARK: - View Life Cycle
override func viewDidLoad() {
super.viewDidLoad()

setup()
configureConstraints()
}

// MARK: - Setup & Configure
private func setup() {
view.backgroundColor = .baseBackground
textView.text = String(viewModel.index)
}

private func configureConstraints() {
view.addSubview(textView)
textView.setAnchor(
top: view.topAnchor, constantTop: 10,
leading: view.leadingAnchor, constantLeading: 10,
bottom: view.bottomAnchor, constantBottom: 10,
trailing: view.trailingAnchor, constantTrailing: 10
)
}

func getPageIndex() -> Int {
return viewModel.index
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import Foundation
import Combine

final class ReadPageViewModel: ViewModelType {
enum Input {

}

enum Output {

}

private let output = PassthroughSubject<Output, Never>()
private var cancellables = Set<AnyCancellable>()
let index: Int

init(index: Int) {
self.index = index
}

func transform(input: AnyPublisher<Input, Never>) -> AnyPublisher<Output, Never> {
input.sink { event in
switch event {

}
}
.store(in: &cancellables)

return output.eraseToAnyPublisher()
}
}
Loading