FDHudView 一個簡單到令人發(fā)指的swiftUI彈框提示組件

最近更新了2.0版本焦人,解決了1.0版本的問題挥吵,并進(jìn)行了優(yōu)化。
當(dāng)前版本沒有更新庫花椭,因為網(wǎng)絡(luò)不太好忽匈,所以會直接放源碼。
先說思路矿辽,1.0版本的思路是直接在入口contentView上方一個View丹允,在有彈框需求時就展示這個view郭厌,并在上面展示hud,全局只有一個hud雕蔽,面對同時多個請求都需要展示彈框的需求就無法滿足折柠。針對這點,2.0優(yōu)化為了一組彈框批狐,在彈框管理器中有兩組數(shù)據(jù)扇售,一組管理臨時彈框,一組管理組合彈框嚣艇,每次彈框但是由單獨的對象進(jìn)行管理承冰,不會出現(xiàn)1.0的互相干擾問題。用法沒有任何改變食零。
FDHud的優(yōu)點:跟界面代碼完全撇開困乒,在任何數(shù)據(jù)、邏輯地區(qū)都能任意調(diào)用并進(jìn)行展示贰谣,使用代碼極少娜搂,使用風(fēng)格跟UIKit的彈框保持一致。

缺點:(如果沒得非push界面冈爹,就不存在此問題涌攻。全屏彈框也算不上問題)

最近使用發(fā)現(xiàn)的,在完全swiftUI的界面代碼下频伤,無法單獨為窗口進(jìn)行任何代碼設(shè)置恳谎,而入口的

showFDHud 代碼,僅適用于當(dāng)前View憋肖。表現(xiàn)為在彈出界面上無法直接展示因痛。比如,界面彈出一個登錄界面岸更,登錄界面是無法直接展示FDHud的彈框鸵膏,需要在被彈出界面再次調(diào)用showFDHud,才能展示彈框怎炊。這會導(dǎo)致另一個問題谭企,因為showFDHud是添加一個可放置彈框的背景,所以在登錄和主界面都會同步彈框评肆,畢竟使用的是同一個數(shù)據(jù)源债查,如果是登錄界面是全屏的,則界面上是沒有任何瑕疵的瓜挽。

pod沒更新盹廷,demo更新了 ,去掉了HUD出現(xiàn)時的動畫久橙,因為如果有兩個相近的接連show俄占,會導(dǎo)致崩潰

前言:

最近在學(xué)習(xí)swiftUI管怠,發(fā)現(xiàn)這玩意跟以前的UIKit框架差別還是挺大,許多思維都需要重新發(fā)散就比如彈框缸榄,在UIkit里面渤弛,是想在哪個界面彈框就能直接去彈出來,而且在swiftUI里面碰凶,如果不是直接在響應(yīng)方法暮芭,而是在邏輯處理方法里面想要彈框,就只能一開始就布局欲低,然后用狀態(tài)管理器去控制展現(xiàn)辕宏,就不如UIKit自由和自在,尤其是對于剛學(xué)習(xí)swiftUI的人來說砾莱,容易卡殼瑞筐。在一段時間學(xué)習(xí)后,我嘗試在項目運用學(xué)習(xí)成果腊瑟,在網(wǎng)絡(luò)請求的時候聚假,就發(fā)現(xiàn)了加載請求彈框的問題,度娘了之后闰非,也發(fā)現(xiàn)了別人的成果膘格,但是使用方面感覺完全沒得以前的使用自由,方便财松,所以瘪贱,結(jié)合別人的思路和自己的成果,寫出了這個控件辆毡,以達(dá)到在使用UIkit時的手感菜秦。

一 集成

集成非常簡單,使cocoaPods集成

pod 'FDHudView'

在入口做簡單的設(shè)置,在根視圖上注冊使用

import SwiftUI
import FDHudView
@main
struct DJLContractorApp: App {

 var body: some Scene {
     WindowGroup {
        TabbarView(manager: TabbarManager.manager)
            .showFDHud()
     }
 }
}

使用介紹

然后在任何需要使用的地方進(jìn)行使用
加載簡單的文字菊花效果

FDHud.show("加載中...") 
Simulator Screen Shot - iPhone 13 - 2022-03-03 at 11.31.06.png

加載純文字提示

FDHud.showMessage("加載中...")
Simulator Screen Shot - iPhone 13 - 2022-03-03 at 11.34.35.png

網(wǎng)絡(luò)數(shù)據(jù)加載 **注意,這是匹配使用的舶掖,一個負(fù)責(zé)展示球昨,一個負(fù)責(zé)消除

FDHud.showLoading()
FDHud.hideHud()
Simulator Screen Shot - iPhone 13 - 2022-03-03 at 11.39.19.png

目前就三個簡單的樣式,因為代碼也是簡潔明了眨攘,需要的可以自己修改成自己需要的樣式

FDHudView的特點就是全局就這一個主慰,通過一個單例管理對象進(jìn)行控制,如果界面已經(jīng)展示了鲫售,再次調(diào)用show方法河哑,會失效。目前還沒做多次調(diào)用等的優(yōu)化龟虎,只是一個最簡單的使用版本,勿噴沙庐,不接受鲤妥。
地址是demo佳吞,也可以下載后把FDHud文件夾直接拖進(jìn)工程使用
Github 地址傳送門
下面是斯坦福的教學(xué)視頻,2020棉安,2021的底扳,兩期內(nèi)容大致一樣,但是2021的相對更完善更全面贡耽,可以直接只看2021年的衷模,當(dāng)然,時間多的也可以全看蒲赂,話說阱冶,這個老大爺還是很有喜感的,講的也很好
學(xué)習(xí)地址傳送門

2.0源碼
管理器

import UIKit
import SwiftUI

class FSHud: ObservableObject {

   static let manager = FSHud()

   @Published var hudList = [FSHudItem]()
   @Published var hudLoadingList = [FSHudItem]()

   @Published var isShow: Bool = false

   public static func show(_ text: String) {
      manager.show(text)
   }
   public static func showMessage(_ text: String) {
      manager.showMessage(text)
   }
   public static func showLoading() {
      manager.showLoading()
   }
   public static func hideHud() {
      manager.hideHud()
   }
   private func show(_ text: String) {
      isShow = true
      let item = FSHudItem()
      item.text = text
      item.type = .textIcon
      withAnimation {
         hudList.append(item)
      }
      item.startDispatchTime {
         self.hudList.removeAll(where: { $0.id == item.id })
         self.checkIsShow()
      }
   }
   private func showMessage(_ text: String) {
      isShow = true
      let item = FSHudItem()
      item.text = text
      item.type = .text
      withAnimation {
         hudList.append(item)
      }
      item.startDispatchTime {
         self.hudList.removeAll(where: { $0.id == item.id })
         self.checkIsShow()
      }
   }
   private func showLoading() {
      isShow = true
      let item = FSHudItem()
      item.type = .icon
      withAnimation {
         hudLoadingList.append(item)
      }
   }
   private func hideHud() {
      if !hudLoadingList.isEmpty {
         hudLoadingList.removeLast()
      }
      checkIsShow()
   }
   private func checkIsShow() {
      if hudList.isEmpty && hudLoadingList.isEmpty {
         isShow = false
      }
   }
}
final class FSHudItem {
   var id = Date().timeIntervalSince1970
   var text: String?
   var type = FDHudType.text

   func startDispatchTime(_ block: @escaping () -> ()) {
      DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
         block()
      }
   }
}
extension View {
   public func showFSHud() -> some View {
      self.modifier(FSHudVM())
   }
}
struct FSHudVM: ViewModifier {
   func body(content: Content) -> some View {
      ZStack(alignment: .center) {
         content
         FSHudView()
            .zIndex(1)
      }
   }
}

界面代碼

struct FSHudView: View {
   @ObservedObject var viewModel = FSHud.manager
   var body: some View {
      if viewModel.isShow {
         ZStack {
            ForEach(viewModel.hudList, id: \.id) { item in
               FSHudItemView(item: item)
            }
            .padding(.horizontal, 0)
            .padding(12)
            .background(
               RoundedRectangle(cornerRadius: 4).fill(Color.hex(0x000000, 0.7))
                  .shadow(color: Color(.black).opacity(0.16), radius: 12, x: 0, y: 5)
            )
         }
         .frame(maxWidth: .infinity, maxHeight: .infinity)
         .background(
            Color.clear.ignoresSafeArea()
         )
      }
   }
}

struct FSHudItemView: View {
   var item: FSHudItem
   var body: some View {
      if item.type == .text {
         textContent
      } else if item.type == .icon {
         iconContent
      } else {
         textIconContent
      }
   }
}
extension FSHudItemView {
   var textContent: some View {
      Text(item.text ?? "")
         .foregroundColor(.white)
   }
   var iconContent: some View {
      Image(systemName: "rays").imageScale(.large).spinning()
         .padding([.top,.leading,.trailing,.bottom],10)
         .foregroundColor(Color.white)
   }
   var textIconContent: some View {
      VStack {
         Image(systemName: "rays").imageScale(.large).spinning()
            .padding([.top,.leading,.trailing,.bottom],10)
            .foregroundColor(Color.white)
         Text(item.text ?? "")
            .foregroundColor(.white)
      }
   }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末滥嘴,一起剝皮案震驚了整個濱河市木蹬,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌若皱,老刑警劉巖镊叁,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異走触,居然都是意外死亡晦譬,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進(jìn)店門互广,熙熙樓的掌柜王于貴愁眉苦臉地迎上來敛腌,“玉大人,你說我怎么就攤上這事兜辞∮疲” “怎么了?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵逸吵,是天一觀的道長凶硅。 經(jīng)常有香客問我,道長扫皱,這世上最難降的妖魔是什么足绅? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮韩脑,結(jié)果婚禮上氢妈,老公的妹妹穿的比我還像新娘。我一直安慰自己段多,他們只是感情好首量,可當(dāng)我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般加缘。 火紅的嫁衣襯著肌膚如雪鸭叙。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天拣宏,我揣著相機與錄音沈贝,去河邊找鬼。 笑死勋乾,一個胖子當(dāng)著我的面吹牛宋下,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播辑莫,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼学歧,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了摆昧?” 一聲冷哼從身側(cè)響起撩满,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎绅你,沒想到半個月后伺帘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡忌锯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年伪嫁,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片偶垮。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡张咳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出似舵,到底是詐尸還是另有隱情脚猾,我是刑警寧澤,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布砚哗,位于F島的核電站龙助,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蛛芥。R本人自食惡果不足惜提鸟,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望仅淑。 院中可真熱鬧称勋,春花似錦、人聲如沸涯竟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蝗蛙,卻和暖如春蝇庭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背捡硅。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留盗棵,地道東北人壮韭。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像纹因,于是被迫代替她去往敵國和親喷屋。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容