오늘의 목표. 많이들 쓰는 페이징 기능이 달린 배너 만들어보기.
어플리케이션을 만들다보면 한번쯤은 보게되는 페이징 배너.
여기에 한쪽방향으로 무한하게 움직이게 해달라거나, 양 옆에 이전, 다음 배너가 살짝(?) 걸치게 만들어달라는 등의 커스텀 요청을 많이 받곤 한다.
Swift UI 를 손대기 시작한지 얼마 되지 않았으니 아주 간단하게, 기본기능에 충실하게 만들어보는게 목표.
제일 처음 만들 방법을 생각해본건 ScrollView 를 이용한 제작방법이었다.
GeometryReader(세부사항은 다음 포스트에)
를 통해 상위 뷰의 크기를 잡고, 스크롤뷰를 깔고, 안에 대상이 되는 아이템들을 이미지로 넣어준다.
프리뷰에 보이진 않지만 좌우로 잘 움직인다. 이제 pagingEnable 을 설정해주면 되는데...
pagingEnable 은 없습니다.
또없다. 이게 또... 없다고 한다.(오토레이아웃이 없던것보다는 충격이 덜했지만)
해결방법은 UIScrollView에 접근해서 appearance 속성까지 타고들어가야 한다고 했다.
뷰의 라이프 사이클의 onAppear , onDisaooear 를 붙여서 이 뷰가 사용되는 동안만 UIScrollView.appearance 속성을 변경해보기로 했다.
struct ImageScrollBannerView: View {
var body: some View {
GeometryReader { geo in
let w = geo.size.width
let h = w
ScrollView(.horizontal, showsIndicators: true, content: {
LazyHStack(spacing: 0) {
ForEach(1..<5) { index in
Image("animal_0\(index)")
.resizable()
.frame(width: w, height: h)
.aspectRatio(contentMode: .fit)
}
}
})
.frame(width: w, height: h)
.onAppear {
UIScrollView.appearance().isPagingEnabled = true
}.onDisappear {
UIScrollView.appearance().isPagingEnabled = false
}
}
}
}
UIScrollview 의 appearance 를 건드리는게 상당히 찜찜했지만, 일단 여기까지 완성.
이제 UIPageController 를 ZStack 으로 위에 표기하면 될거같았는데...
PageController 도 없습니다.
pagingEnable 이 없을때 알아챘어야 했다. 활성화가 안되는데 컨트롤러가 있을리가 있나.
새삼 내가 UIKit 에 많은 도움을 받고있었음을 알수있었다.
결국 완성본처럼 만들려면 pageController 를 직접구현하거나, UIKit 의 컴포넌트를 랩핑하여 Swift UI 에서 사용해야 한다는 결론에 도달했다.
두가지 모두 하나의 포스트에 담기에는 내용이 방대해서 고민하고 있었는데, 역시나. 다른 방법으로 간단하게 구현하는것이 가능하다고 한다.
TabView 는 하단에 있는 셀렉트 박스와 함께 쓰는걸로 생각이 고정되어있었는데, Swift UI 에서는 TabView 의 스타일을 지정함으로서 Container View와 같은 개념으로도 사용이 가능한것 같았다.
코드는 스크롤뷰를 베이스로 직접 구현하는 방법보다 매우 심플하다.
struct ImageScrollBannerView: View {
var body: some View {
GeometryReader { geo in
let w = geo.size.width
let h = w
TabView {
ForEach(1..<5) { index in
Image("animal_0\(index)")
.resizable()
.frame(width: w, height: h)
.aspectRatio(contentMode: .fit)
}
}
.tabViewStyle(.page)
.frame(width: w, height: h)
}
}
}
아예 하단 Page Controller 까지 붙여서 나와주는 심플함.
TabView 를 쓰는것처럼 아이템을 쭉 추가하고 마지막에 .tabViewStyle(.page)
만 붙여주면 알아서, 편하게 만들어준다.
하지만 실제 디자이너의 요구를 받는다고 가정하면 TabView 를 쓰는 기본기능으로는 한계가 있을것이 분명했다. 기왕 공부를 시작한김에 스크롤뷰를 이용한 방법으로 완성시켜보려 한다.
그를 위해선 GeometryReader
와 PreferenceKey
에 대한 이해가 먼저 선결되어야 한다.
두가지 모두 다음 포스트에서.