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