// 내용 추가중
어플리케이션에서 스크롤 뷰(scrollview)에 사진을 담은 후, 각각을 보기 편하게 하기 위해 페이지뷰를 이용한다.
이번에 만들 기능은 페이지 뷰(page view)에 인디케이터(indicator)를 넣고 애니메이션을 추가해 줬다.
단순한 애니메이션이 아니라, 페이지가 이동한 offset 만큼만 동적으로 변하게 하기 위해 UIViewRepresentable 프로토콜을 이용해 UIKit을 가져와 이용할 것이다.
2021.08.10 - [SwiftUI/기타] - SwiftUI에서 UIKit 이용하기: UIViewRepresentable
이번 글에서는 UIViewRepresentable을 이용하여 ScrollView에서 스크롤하며 스크롤 된 정도인 offset을 받아오는 기능적인 부분을 설명하고, 다음 글에서는 이를 실제 SwiftUI에서 불러와 보기 좋게 이런 저런 modifiers를 붙여볼 생각이다.
우선, PagingTabView.swift 로 이름 짓고 스크롤 뷰를 만들고 몇 가지 추가하자. 우리는 스크롤 뷰를 이용할 것이므로 UIScrollView를 적재 적소에 명시해준다.
// PagingTabView.swift
import SwiftUI
struct PagingTabView<Content: View>: UIViewRepresentable {
init() {
}
func makeUIView(context: Context) -> UIScrollView {
}
func updateUIView(_ uiView: UIScrollView, context: Context) {
}
}
기본적으로 살펴볼 문법
- Type Constraints in Generic Type
몇 가지 추가해주자
struct PagingTabView<Content: View>: UIViewRepresentable {
var content: Content
@Binding var offset: CGFloat
init(offset: Binding<CGFloat>, @ViewBuilder content: @escaping () -> Content) {
self.content = content()
self._offset = offset
}
func makeUIView(context: Context) -> UIScrollView {
let scrollView = UIScrollView()
// SwiftUI 뷰를 UIKit을 이용하기 위해
let hostview = UIHostingController(rootView: content)
// 뷰 고정
hostview.view.translatesAutoresizingMaskIntoConstraints = false
let constraints = [
hostview.view.topAnchor.constraint(equalTo: scrollView.topAnchor),
hostview.view.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
hostview.view.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
hostview.view.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor ),
hostview.view.heightAnchor.constraint(equalTo: scrollView.heightAnchor)
]
// UIView에 SwiftUI View 통합
scrollView.addSubview(hostview.view)
scrollView.addConstraints(constraints)
// 페이징 설정
scrollView.isPagingEnabled = true
scrollView.showsVerticalScrollIndicator = false
scrollView.showsHorizontalScrollIndicator = false
return scrollView
}
}
알아둘 개념
- @ViewBuilder
- @escaping
여기서 delegate와 coordinator 설정을 해주면 끝
import SwiftUI
struct PagingTabView<Content: View>: UIViewRepresentable {
...
func makeCoordinator() -> Coordinator {
return PagingTabView.Coordinator(parent: self)
}
init(offset: Binding<CGFloat>, @ViewBuilder content: @escaping () -> Content) {
...
}
func makeUIView(context: Context) -> UIScrollView {
...
scrollView.delegate = context.coordinator
return scrollView
}
func updateUIView(_ uiView: UIScrollView, context: Context) {
}
// offset 받기 위해 delegate 설정
class Coordinator: NSObject, UIScrollViewDelegate {
var parent: PagingTabView
init(parent: PagingTabView) {
self.parent = parent
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
// 오프셋 받는 부분
let offset = scrollView.contentOffset.x
parent.offset = offset
}
}
}
참고 자료
https://www.youtube.com/watch?v=cY-Feaqkbng
'SwiftUI > Project' 카테고리의 다른 글
4. SwiftUI Launching Page 만들기 (0) | 2021.08.15 |
---|---|
3. SwiftUI 페이지 뷰와 인디케이터 애니메이션(2) (0) | 2021.08.14 |
2. SwiftUI 탭 하여 화면 전환하기 (0) | 2021.08.10 |