에자일에서 user story는 다음과 같이 나누어서 관리한다.
팀마다 column의 이름이나 개수는 다를 수 있다. 중요한 점은
라는 것이다.
storyboard를 관리하는 툴에는 Trello, JIRA 등이 있다. 실제 프로젝트에서는 JIRA가 많이 사용된다.
onboarding 화면은 UIPageViewController
를 이용해서 구현한다.
addChild(pageViewController)
view.addSubview(pageViewController.view)
pageViewController.didMove(toParent: self)
자식 뷰 컨트롤러를 추가하는 과정은 세 단계로 나뉜다.
자식 뷰 컨트롤러를 컨테이너에 추가한다.
→ 자식 뷰 컨트롤러로 설정
자식 뷰 컨트롤러의 뷰를 subview로 추가한다.
→ 자식 뷰 컨트롤러의 view를 가장 위에 보여주도록 하기 위함
자식 뷰 컨트롤러에게 부모 뷰 컨트롤러에 추가되는 정확한 시점을 알려주기 위해 didMove 메소드를 호출한다.
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]
}
맨 처음과 마지막 화면에서는 더이상 넘어가지 않도록 처리를 해주었다. 첫 화면→마지막 화면 또는 마지막 화면→첫 화면으로도 움직일 수 있도록 하도록 코드를 조금 수정하면 잘 동작하는 것 같다.
벡터 pdf를 asset catalog로 불러오면 retina image로 불러와진다. 벡터 그래픽으로 설정하려면 asset catalog에서 원하는 asset을 선택하고 Resizing의 Preserve Vector Data
를 체크한 후 Scales를 Single Scale
로 설정한다.
우리는 이미지와 label 내용만 다른 세 개의 화면이 필요하기 때문에 OngoingViewController를 초기화 할 때 이미지 이름과 텍스트 내용을 전달하는 방식으로 코드를 수정해서 뷰 컨트롤러를 재사용 할 수 있다.
let heroImageName: String
let titleText: String
init(heroImageName: String, titleText: String) {
self.heroImageName = heroImageName
self.titleText = titleText
super.init(nibName: nil, bundle: nil)
}
*참고: 클래스의 이니셜라이저에서는 상수 프로퍼티에 값 할당이 가능하다.
위의 코드만 추가하면 'required' initializer 'init(coder:)' must be provided by subclass of 'UIViewController'
라는 에러가 발생한다.
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
이는 위와 같은 코드를 추가해주면 해결이 되는데, 이는 UIViewController에서 상속받은 생성자인데, 스토리보드로 작업을 할 때 필요한 생성자이다. 그런데 required
로 설정되어 있기 때문에 반드시 추가해주어야 하는 것이다.