SwiftUI目前还在发展阶段,有些视图还未能提供。可是苹果给咱们提供复用机制,很容易将历史代码移植到SwiftUI世界中。下面咱们经过UIViewRepresentable将UIKit的UIActivityIndicator封装一下
首先,咱们将UIActivityIndicator包装到一个ActivityIndicator视图中,该视图可用做SwiftUI视图。其中 isAnimating做为动画的开关swift
struct ActivityIndicator: UIViewRepresentable { @Binding var isAnimating: Bool let style: UIActivityIndicatorView.Style func makeUIView(context: UIViewRepresentableContext<ActivityIndicator>) -> UIActivityIndicatorView { return UIActivityIndicatorView(style: style) } func updateUIView(_ uiView: UIActivityIndicatorView, context: UIViewRepresentableContext<ActivityIndicator>) { isAnimating ? uiView.startAnimating() : uiView.stopAnimating() } }
在实际开发中,咱们不多单独使用UIActivityIndicator,由于实在太单调了。我一般是添加UILabel来告知用户咱们正在处理的事项,例如:加载,计算,载入等,在SwiftUI世界里咱们用Text就能够很好的完成这个任务。ide
因为咱们如今将ActivityIndicator做为SwiftUI视图,所以咱们能够轻松地利用SwiftUI强大组合功能,联合其余View来建立功能强大的HUD(Head up Display))提示框。动画
另外,为此了示范loading页面的显示与隐藏,咱们还增长了隐藏和显示按钮。ui
显示按钮代码spa
Button(action:{ self.isShowing = !self.isShowing //self.isAnimating = false }){ Text(" Show loading ").foregroundColor(.white) }.background(Color.orange) .cornerRadius(2.0) .shadow(radius: 2)
隐藏按钮效果code
隐藏按钮代码blog
Button(action:{ self.isShowing = false //self.isAnimating = false }){ Text(" Hide ") }.background(Color.white) .cornerRadius(2.0) .shadow(radius: 2)
组装教程
struct LoadingView<Content>: View where Content: View { @Binding var isShowing: Bool @State var isAnimating: Bool = true var content: () -> Content var body: some View { GeometryReader { geometry in ZStack(alignment: .center) { self.content() .disabled(self.isShowing) .blur(radius: self.isShowing ? 3 : 0) VStack { Text("Loading...") ActivityIndicator(isAnimating: self.$isAnimating, style: .large) Button(action:{ self.isShowing = false //self.isAnimating = false }){ Text(" Hide ") }.background(Color.white) .cornerRadius(2.0) .shadow(radius: 2) } .frame(width: geometry.size.width / 2, height: geometry.size.height / 5) .background(Color.secondary.colorInvert()) .foregroundColor(Color.primary) .cornerRadius(20) .opacity(self.isShowing ? 1 : 0) } } } }
主页面ci
struct ContentView: View { @State var isShowing: Bool = true var body: some View { LoadingView(isShowing:self.$isShowing) { VStack{ Button(action:{ self.isShowing = !self.isShowing //self.isAnimating = false }){ Text(" Show loading ").foregroundColor(.white) }.background(Color.orange) .cornerRadius(2.0) .shadow(radius: 2) NavigationView { List(["1", "2", "3", "4", "5"], id: \.self) { row in Text(row) }.navigationBarTitle(Text("A List"), displayMode: .large) } } } } }
import SwiftUI struct ActivityIndicator: UIViewRepresentable { @Binding var isAnimating: Bool let style: UIActivityIndicatorView.Style func makeUIView(context: UIViewRepresentableContext<ActivityIndicator>) -> UIActivityIndicatorView { return UIActivityIndicatorView(style: style) } func updateUIView(_ uiView: UIActivityIndicatorView, context: UIViewRepresentableContext<ActivityIndicator>) { isAnimating ? uiView.startAnimating() : uiView.stopAnimating() } } struct LoadingView<Content>: View where Content: View { @Binding var isShowing: Bool @State var isAnimating: Bool = true var content: () -> Content var body: some View { GeometryReader { geometry in ZStack(alignment: .center) { self.content() .disabled(self.isShowing) .blur(radius: self.isShowing ? 3 : 0) VStack { Text("Loading...") ActivityIndicator(isAnimating: self.$isAnimating, style: .large) Button(action:{ self.isShowing = false //self.isAnimating = false }){ Text(" Hide ") }.background(Color.white) .cornerRadius(2.0) .shadow(radius: 2) } .frame(width: geometry.size.width / 2, height: geometry.size.height / 5) .background(Color.secondary.colorInvert()) .foregroundColor(Color.primary) .cornerRadius(20) .opacity(self.isShowing ? 1 : 0) } } } } struct ContentView: View { @State var isShowing: Bool = true var body: some View { LoadingView(isShowing:self.$isShowing) { VStack{ Button(action:{ self.isShowing = !self.isShowing //self.isAnimating = false }){ Text(" Show loading ").foregroundColor(.white) }.background(Color.orange) .cornerRadius(2.0) .shadow(radius: 2) NavigationView { List(["1", "2", "3", "4", "5"], id: \.self) { row in Text(row) }.navigationBarTitle(Text("A List"), displayMode: .large) } } } } }
https://peacemoon.de/blog/2019/06/10/activity-indicator-with-swiftui/开发
QQ:3365059189
SwiftUI技术交流QQ群:518696470