SwiftUI IOS 14 이하 에서는 스크롤 뷰 Refresh Controll 지원이 안됨.
UIViewRepresentable 이용해서 UIScrollView와 UIRefreshControl 을 커스텀 해야됨.
import SwiftUI
struct RefreshableScrollView<Content: View>: UIViewRepresentable {
var content: Content
var onRefresh: (UIRefreshControl) -> ()
var refreshControl = UIRefreshControl()
init(@ViewBuilder content: @escaping () -> Content, onRefresh: @escaping (UIRefreshControl) -> ()) {
self.content = content()
self.onRefresh = onRefresh
}
func makeCoordinator() -> Coordinator {
return Coordinator(parent: self)
}
func makeUIView(context: Context) -> UIScrollView {
let uiScrollView = UIScrollView()
refreshControl.attributedTitle = NSAttributedString(string: "더 보기")
refreshControl.tintColor = .blue
refreshControl.addTarget(context.coordinator, action: #selector(context.coordinator.onRefresh), for: .valueChanged)
setUpView(uiScrollView: uiScrollView)
uiScrollView.refreshControl = refreshControl
return uiScrollView
}
func updateUIView(_ uiView: UIViewType, context: Context) {
setUpView(uiScrollView: uiView)
}
func setUpView(uiScrollView: UIScrollView) {
let hostingView = UIHostingController(rootView: content.frame(maxHeight: .infinity, alignment: .top))
hostingView.view.translatesAutoresizingMaskIntoConstraints = false
let constraints = [
hostingView.view.topAnchor.constraint(equalTo: uiScrollView.topAnchor),
hostingView.view.bottomAnchor.constraint(equalTo: uiScrollView.bottomAnchor),
hostingView.view.leadingAnchor.constraint(equalTo: uiScrollView.leadingAnchor),
hostingView.view.trailingAnchor.constraint(equalTo: uiScrollView.trailingAnchor),
hostingView.view.widthAnchor.constraint(equalTo: uiScrollView.widthAnchor),
hostingView.view.heightAnchor.constraint(greaterThanOrEqualTo: uiScrollView.heightAnchor, constant: 1),
]
uiScrollView.isScrollEnabled = true
uiScrollView.subviews.last?.removeFromSuperview()
uiScrollView.addSubview(hostingView.view)
uiScrollView.addConstraints(constraints)
}
class Coordinator {
var parent: RefreshableScrollView
init(parent: RefreshableScrollView) {
self.parent = parent
}
@objc func onRefresh() {
parent.onRefresh(parent.refreshControl)
}
}
}
[적용]
RefreshableScrollView(content: {
VStack {
ForEach(1...50, id: \.self) { index in
Color.blue
.frame(height: 200)
}
}
}, onRefresh: { contol in
// api request ...
// refresh contol end
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
control.endRefreshing()
}
})
'SwiftUI' 카테고리의 다른 글
[SwiftUI] 고정식 BottomSheet Custom (IOS 16 미만) (0) | 2024.05.21 |
---|---|
[SwiftUI] Refresh ScrollView(IOS15 미만) (0) | 2024.05.17 |
[SwiftUI] List Separator Line Hidden (IOS14 이하) (0) | 2024.05.02 |
[SwiftUI] View Full Modal Present (0) | 2024.05.02 |
[SwiftUI] onAppear / onDisappear 호출시점 (0) | 2024.04.23 |