1. 程式人生 > >SwiftUI - 一步一步教你使用UIViewRepresentable封裝網路載入檢視(UIActivityIndicatorView)

SwiftUI - 一步一步教你使用UIViewRepresentable封裝網路載入檢視(UIActivityIndicatorView)

概述

網路載入檢視,在一個聯網的APP上可以講得上是必須要的元件,在SwiftUI中它並沒有提供如 UIKit 中的UIActivityIndicatorView直接提供給我們呼叫,但是我們可以通過 SwiftUI 中的UIViewRepresentable協議封裝UIActivityIndicatorView來使用它。

介紹 UIViewRepresentable

那麼UIViewRepresentable到底有著什麼樣的作用呢?

它可以將 UIKit 封裝成 SwiftUI View,這意味著我們可以通過它來搭建橋樑,可以很方便地複用以往在 UIKit 所有的元件,這很強大。

接下來介紹它的兩個必須實現的協議。

/// 建立一個 UIView 的檢視元件用於展示
func makeUIView(context: Self.Context) -> Self.UIViewType

/// 更新檢視元件到最新的內容
func updateUIView(_ uiView: Self.UIViewType, context: Self.Context)

封裝網路載入檢視(UIActivityIndicatorView)

我們開始封裝網路載入檢視(UIActivityIndicatorView),建立一個實現了 UIViewRepresentable 協議的結構體。

struct GCIndicatorView: UIViewRepresentable {}

接下來的步驟均按照Xcode的提示進行,不做任何的簡化操作,如果你們想要知道如何簡化,可以評論或私信告訴我,我下期補這個內容。

Xcode 提示缺少內容,點選紅色小框後點擊 Fix 按鈕,將會補全缺失程式碼。

struct GCIndicatorView: UIViewRepresentable {
    typealias UIViewType = UIActivityIndicatorView
}

將檢視型別改成我們所需要的 UIActivityIndicatorView ,這裡定義好之後,makeUIView 和 updateUIView 方法定義都會返回此處定義的檢視型別。接下來 Xcode 還會提示缺失程式碼,我們繼續重複上一步。

在 makeUIView 方法體內建立 UIActivityIndicatorView 檢視,它接受一個引數 UIActivityIndicatorView.Style,因此我們使用 let 定義一個 type 型別為 UIActivityIndicatorView.Style 的屬性。

let style: UIActivityIndicatorView.Style
    
func makeUIView(context: UIViewRepresentableContext<GCIndicatorView>) -> UIActivityIndicatorView {
    return UIActivityIndicatorView(style: style)
}

因為 Style 型別是定義在 UIActivityIndicatorView 裡面的,所以在使用的時候提示是 UIActivityIndicatorView.Style,這樣的好處是不會汙染專案的名稱空間,它只有兩個型別可選。

public enum Style : Int {
      @available(iOS 13.0, *)
      case medium /// 尺寸是中等

      @available(iOS 13.0, *)
      case large // 尺寸是大的
}

我們再定義一個 color 屬性,用於改變載入檢視的顏色。在初始化檢視時,為了可以選擇忽略此屬性,因此我們使用 var 定義為可變屬性。

var color: UIColor? = nil
    
func makeUIView(context: UIViewRepresentableContext<GCIndicatorView>) -> UIActivityIndicatorView {
    let activityIndicatorView = UIActivityIndicatorView(style: style)
    activityIndicatorView.color = color
    return activityIndicatorView
}

這裡有一個小技巧,不知道你們發現了沒有?我在定義 color 屬性的時候,設定了它的預設值是 nil,這有什麼好處呢?這裡先看一下初始化時的程式碼提示。

它的作用就是可以讓你在初始化檢視時,有兩個方法讓你選擇,明確地告訴你可以忽略有 color 或者沒有 color 的定義。當然你不特定去設定預設值為 nil,你也可以在初始化時手動刪除 color 欄位,但我覺得按我這樣的方法會更清晰一點,在呼叫的時侯。

我們在開始請求網路時顯示載入檢視,在網路請求後隱藏載入檢視,為了實現這個操作,我們定義一個布林型別的 isShowing 屬性,同時還需使用 @Binding 修飾屬性。

使用 @Binding 修飾的屬性,屬性會變成一個引用型別,從父檢視傳遞給子檢視,這樣父子檢視的狀態就可以關聯起來了,當屬性變化時會同時改變父子檢視。

在 UIViewRepresentable 裡,它的改變會調起 updateUIView 方法,我們可以在此方法中更新檢視。

func updateUIView(_ uiView: UIActivityIndicatorView, context: UIViewRepresentableContext<GCIndicatorView>) {
    isShowing ? uiView.startAnimating() : uiView.stopAnimating()
}

小知識: UIActivityIndicatorView 元件需要調起 startAnimating 時才會顯示檢視,否則它是隱藏的

使用封裝好的載入檢視 GCIndicatorView

我們需要讓載入檢視顯示在介面的正中間,因此使用 ZStack,它可以使在其內的元件疊加起來。同時需要定義一個布林型的 isShowing 屬性,並使用 @State 修飾它。使用 @State 修飾的屬性,可以在其值發生變更時同時更新其關聯的所有檢視。

我們在介面上建立一個 ZStack,裡面包含有一個按鈕,點選按鈕時將顯示載入檢視,在3秒後自動消失。通過條件語句判斷 isShowing 為 true 時才顯示檢視,否則隱藏檢視。

在某些情況下,在顯示載入檢視的時候不允許使用者點選其它檢視,需要等待網路請求完成後才能進行操作,因此需要給 ZStack 加上 disabled 方法,用於禁止操作事件。

struct GCHomeView: View {
    @State var isShowing = false
    
    var body: some View {
        ZStack {
            Button(action: {
                self.isShowing = true
                DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
                    self.isShowing = false
                }
            }) {
                Text("網路請求開始")
            }
            if isShowing {
                GCIndicatorView(isShowing: $isShowing, style: .large)
            }
        }
        .disabled(isShowing)
    }
}

效果預覽

Demo 原始碼下載

我已經把 Demo 上傳至 GitHub 上面,有需要的朋友可以去下載執行一下,當然你也可以跟著文章去做一遍,這樣更有利於你掌握此方面的知識。

文章篇幅有點長,雖然教的東西也挺簡單,但概述得比較詳細。任何東西都是先從簡單入手的,才不會造成勸退不是嗎?哈哈,此文章針對於新手而言還是很友好的,對於已經會的人來講就可能廢話有點多了,如果必須要噴,請輕噴,我比較玻璃心。

如果你覺得本文章對你有幫助,請關注我,你的關注就是我寫文章的動力,下期會更精彩噢!

關於作者

博文作者:GarveyCalvin

微博:https://weibo.com/feiyueharia

部落格園:https://www.cnblogs.com/GarveyCalvin

本文版權歸作者,歡迎轉載,但必須保留此段宣告,並給出原文連結,謝謝合作!

公眾號

作者第一次運營公眾號,請你們一定要關注我的公眾號,給我點動力,後期主要運營公眾號為主。這是第一篇釋出文章,需要你們的支援,謝謝你們!

QQ群

一起討論 SwiftUI,群主喜歡看熱鬧,當吃瓜人員。進來時填寫你在哪裡看到此文章的,並介紹下自己,一句話就行。

相關推薦

SwiftUI - 使用UIViewRepresentable封裝網路載入檢視UIActivityIndicatorView

概述 網路載入檢視,在一個聯網的APP上可以講得上是必須要的元件,在SwiftUI中它並沒有提供如 UIKit 中的UIActivityIndicatorView直接提供給我們呼叫,但是我們可以通過 SwiftUI 中的UIViewRepresentable協議封裝UIActivityIndicatorVie

【Android】從無到有:手把手步步使用最簡單的Fragment

轉載請註明出處,原文連結:https://blog.csdn.net/u013642500/article/details/80585416 【本文適用讀者】         用程式碼建立並使用了 Fragment,新增 Fragment 之

【Android】從無到有:手把手步步使用最簡單的Fragment

轉載請註明出處,原文連結:https://blog.csdn.net/u013642500/article/details/80579389 【本文適用讀者】         targetSdkVersion 版本大於等於 21,即 app 即將有可能

手把手玩轉 CSS3 3D 技術轉載

是不是 col 默認 占滿 概念 ebe 說明 adb relative css3的3d起步 要玩轉css3的3d,就必須了解幾個詞匯,便是透視(perspective)、旋轉(rotate)和移動(translate)。透視即是以現實的視角來看屏幕上的2D事物,從而展現3

手把手做一個 C 語言編譯器8:表示式

這是整個編譯器的最後一部分,解析表示式。什麼是表示式?表示式是將各種語言要素的一個組合,用來求值。例如:函式呼叫、變數賦值、運算子運算等等。 表示式的解析難點有二:一是運算子的優先順序問題,二是如何將表示式編譯成目的碼。我們就來逐一說明。 本系列: 運算子的優先順

手把手做一個 C 語言編譯器7:語句

整個編譯器還剩下最後兩個部分:語句和表示式的解析。它們的內容比較多,主要涉及如何將語句和表示式編譯成彙編程式碼。這章講解語句的解析,相對於表示式來說它還是較為容易的。 本系列: 語句 C 語言區分“語句”(statement)和“表示式”(expression)兩

手把手做一個 C 語言編譯器9:總結

恭喜你完成了自己的 C 語言編譯器,本章中我們發一發牢騷,說一說編寫編譯器值得注意的一些問題;編寫編譯器時遇到的一些難題。 本系列: 虛擬機器與目的碼 整個系列的一開始,我們就著手虛擬機器的實現。不知道你是否有同感,這部分對於整個編譯器的編寫其實是十分重要的。我認

手把手做一個 C 語言編譯器2:虛擬機器

本章是“手把手教你構建 C 語言編譯器”系列的第三篇,本章我們要構建一臺虛擬的電腦,設計我們自己的指令集,執行我們的指令集,說得通俗一點就是自己實現一套匯編語言。它們將作為我們的編譯器最終輸出的目的碼。 本系列: 計算機的內部工作原理 我們關心計算機的三個基本部件

手把手做一個 C 語言編譯器6:函式定義

由於語法分析本身比較複雜,所以我們將它拆分成 3 個部分進行講解,分別是:變數定義、函式定義、表示式。本章講解函式定義相關的內容。 本系列: EBNF 表示 這是上一章的 EBNF 方法中與函式定義相關的內容。 C

手把手做一個 C 語言編譯器4:遞迴下降

本章我們將講解遞迴下降的方法,並用它完成一個基本的四則運算的語法分析器。 本系列: 什麼是遞迴下降 傳統上,編寫語法分析器有兩種方法,一種是自頂向下,一種是自底自上。自頂向下是從起始非終結符開始,不斷地對非終結符進行分解,直到匹配輸入的終結符;自底向上是不斷地將終

手把手做一個 C 語言編譯器3:詞法分析器

本章我們要講解如何構建詞法分析器。 本系列: 什麼是詞法分析器 簡而言之,詞法分析器用於對原始碼字串做預處理,以減少語法分析器的複雜程度。 詞法分析器以原始碼字串為輸入,輸出為標記流(token stream),即一連串的標記,每個標記通常包括: (token,

手把手做一個 C 語言編譯器0:前言

“手把手教你構建 C 語言編譯器” 這一系列教程將帶你從頭編寫一個 C 語言的編譯器。希望通過這個系列,我們能對編譯器的構建有一定的瞭解,同時,我們也將構建出一個能用的 C 語言編譯器,儘管有許多語法並不支援。 在開始進入正題之前,本篇是一些閒聊,談談這個系列的初衷

手把手做一個 C 語言編譯器1:設計

本章是“手把手教你構建 C 語言編譯器”系列的第二篇,我們要從整體上講解如何設計我們的 C 語言編譯器。 本系列: 首先要說明的是,雖然標題是編譯器,但實際上我們構建的是 C 語言的直譯器,這意味著我們可以像執行指令碼一樣去執行 C 語言的原始碼檔案。這麼做的理由

手把手做一個 C 語言編譯器5:變數定義

本章中我們用 EBNF 來大致描述我們實現的 C 語言的文法,並實現其中解析變數定義部分。 由於語法分析本身比較複雜,所以我們將它拆分成 3 個部分進行講解,分別是:變數定義、函式定義、表示式。 本系列: EBNF 表示 EBNF 是對前一章提到的 BNF 的擴充

手把手做藍芽聊天應用-藍芽連線模組

第4節 藍芽連線模組 藍芽連線的管理模組需要為ChatActivity提供於連線相關的所有功能,要設計的方便使用,並儘量隱藏連線的細節。 4.1 對外介面 我們首先來看看ConnectionManager需要向Chat Activity提供哪些介面。

誤刪除服務器上的git項目,如何利用本地git恢復gitlab

誤刪除 git text 提交 代碼 ffffff ges tps http 1、工作中,誤操作在所難免。記錄有一次不小心刪除了本地服務器上的項目代碼。由於gitlab采用分布式的代碼存儲結構。因此,我們可以將本地的項目重新提交到gitlab中,恢復服務器中不小心刪除的項目

手把手Spring Boot2.x整合ElasticsearchES

#文末會附上完整的程式碼包供大家下載參考,碼字不易,如果對你有幫助請給個點贊和關注,謝謝! #如果只是想看java對於Elasticsearch的操作可以直接看第四大點 ##一、docker部署Elasticsearch(下面簡稱es)單機版教程 ###1、部署es * 拉取es映象(這裡我使用的版本

寫一個快遞查詢APP適合新手

前言: 水平:自學Android十五天,以前有過混日子的程式設計經驗。 目標: 《第一行程式碼》學完之後,總想寫個APP,天氣的APP寫了個初版,後面再說,今天演示的是製作快遞查詢APP的整個經過。 適合人群:新手 工具:A

Docker安裝搭建GitLab倉庫用來做SpringCloudConfig配置中心

Docker 安裝 Git(以下在Centos7上操作,前提是已經安裝過docker)   a:拉取官方的映象   #docker pull gitlab/gitlab-ce:latest   b:執行容器   #docker run --detach \

跟我學習hadoop(5)----hadoop Map/Reduce教程2

submit calc run submitjob des conf sam ner 打開 Map/Reduce用戶界面 本節為用戶採用框架要面對的各個環節提供了具體的描寫敘述,旨在與幫助用戶對實現、配置和調優進行具體的設置。然而,開發時候還是要相應著API進行