SwiftUI 基礎之提示框Activity Indicator製做

SwiftUI目前還在發展階段,有些視圖還未能提供。可是蘋果給咱們提供複用機制,很容易將歷史代碼移植到SwiftUI世界中。下面咱們經過UIViewRepresentable將UIKit的UIActivityIndicator封裝一下

最終效果

SwiftUI 基礎之提示框Activity Indicator製做

實現步驟

首先,咱們將UIActivityIndi​​cator包裝到一個ActivityIndi​​cator視圖中,該視圖可用做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()
    }
}

在實際開發中,咱們不多單獨使用UIActivityIndi​​cator,由於實在太單調了。我一般是添加UILabel來告知用戶咱們正在處理的事項,例如:加載,計算,載入等,在SwiftUI世界裏咱們用Text就能夠很好的完成這個任務。ide

因爲咱們如今將ActivityIndi​​cator做爲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/開發

更多SwiftUI教程和代碼關注專欄

QQ:3365059189
SwiftUI技術交流QQ羣:518696470

https://www.jianshu.com/c/7b3...

相關文章
相關標籤/搜索