SwiftUIのScrollViewにはPull to refreshのようなコンポーネントはUIScrollViewのようには付属されていないので自作した時のメモです。
IndicatorView
struct IndicatorView: View { var body: some View { VStack { Spacer() HStack(spacing: 0) { Spacer() LottieAnimationView(name: "loading") .frame(width: 100, height: 100, alignment: .center) Spacer() } Spacer() } .background(Color(.white)) .opacity(0.8) } }
※LottieAnimationViewはLottieのAnimationViewを実装したUIViewRepresentableです。
HiddenModifier
struct HiddenModifier: ViewModifier { let hidden: Bool func body(content: Content) -> some View { VStack { if !hidden { content } } } } extension View { func hidden(_ isHidden: Bool) -> some View { ModifiedContent(content: self, modifier: HiddenModifier(hidden: isHidden)) } }
ContentView
struct DiaryListView: View { @ObservedObject var viewModel: ViewModel var body: some View { ZStack { ScrollView { GeometryReader { proxy -> AnyView in let frame = proxy.frame(in: .global) if frame.origin.y > 180 && !viewModel.outputs.isLoading { viewModel.inputs.reload.send(true) } return AnyView(EmptyView()) } ForEach(viewModel.outputs.items, id: \.id) { item in Text(item.name) } .padding(.vertical, 8) .padding(.horizontal, 24) } IndicatorView() .frame(width: UIScreen.main.bounds.width, height: coordinator.hostingController?.view.frame.height ?? UIScreen.main.bounds.height) .hidden(!viewModel.outputs.isLoading) } } }
ViewModelのisLoadingが@Publishedになっているのでtrue/falseが切り替えられると.hidden()が切り替わります。
- 作者:金田 浩明
- 発売日: 2019/12/21
- メディア: 単行本