SwiftUI:看我展示52張撲克牌,「很快啊!」

思路

使用 SwiftUI 創建 UI 結構;

使用 swift 的枚舉和結構體實現數據生成,通過 viewModel 整合數據用於展示(交互暫時未做,因此不涉及 MVVM 設計模式中的數據綁定)。

效果圖

畫布實時預覽 iphone 效果圖:

截屏2020-11-20 下午6.00.37

運行 iphone11 黑暗模式效果圖:

Simulator Screen Shot - iPhone 11 - 2020-11-25 at 11.25.13

運行 ipad air 模擬器效果圖:

Simulator Screen Shot - iPad Air (4th generation) - 2020-11-23 at 11.42.50

相關程式碼解析

枚舉創建撲克牌號碼

//CaseIterable:當需要對枚舉進行遍歷時,需要遵守 CaseIterable 協議,然後對枚舉的 allCases 類屬性進行遍歷即可
enum Rank:Int, CaseIterable {
    case ace = 1
    
    //未指定確定值的類別,默認值是「依次」加1,因此,two 的 rawValue 為2,three 的 rawValue 為 3,以此類推
    case two,three,four,five,six,seven,eight,nine,ten
    case J,Q,K
    
    //swift的枚舉,可以自定義方法。寫程式碼時,「很快啊!」
    func customDescription()->String{
        switch self {
        case .ace:
            return "A"
        case .J:
            return "J"
        case .Q:
            return "Q"
        case .K:
            return "K"
        default:
            return "\(self.rawValue)"
        }
    }
}

枚舉創建撲克牌類型

enum CardType: CaseIterable{
    case heart,spades,club,diamond
    
    func customDescription() -> String {
        switch self {
        case .heart:
            
            //command+ctrl+space,快速調出 emoji 窗口,可以搜索,"很6啊!"
            return "♥️"
        case .spades:
            return "♠️"
        case .club:
            return "♦️"
        default:
            return "♣️"
        }
    }
}

viewModel邏輯

struct GameVM {
    
    /// 聲明為 private,符合封裝的思想,通過方法初始化時,必須是類方法(static func)!如果用實例方法,創建實例時,屬性還未初始化,不符合語法!
    private var model:GameM = generateGame()
    
    //數組的泛型不能直接聲明為 Card 類型,會提示找不到。需要通過結構體名點出來!
    var cards: Array<GameM.Card> {
        return model.cards
    }
     
    static func generateGame()->GameM{
        var lArr: Array<GameM.Card> = Array<GameM.Card>()
        
        //兩個循環就創建好了數據源,"很快啊!"
        for type in CardType.allCases {
            for rank in Rank.allCases{
                lArr.append(GameM.Card(rank: rank, type:type))
            }
        }
        return GameM(cards: lArr)
    }
}

UI實現

/// 聲明式UI編程,"很快啊!"
struct ContentView: View {
    var viewModel: GameVM
    
    var body: some View {
        let columnNum = 4
        let rowNum = viewModel.cards.count/columnNum
        
        return
            HStack{
                ForEach(0..<columnNum){column in
                    VStack{
                        ForEach(0..<rowNum){row in
                            let index = (rowNum) * column + row
                            let card = viewModel.cards[index]
                            Card(cardM:card)
                        }
                    }
                }
            }.padding()
    }
}

源碼

FullDeckOfCards_SwiftUI

感受

swift 語法在構建數據類型時比 OC 方便太多了,枚舉和結構體(值類型,copy-on-write)都很強大。

非共享數據優先使用結構體,類一般只用於 viewModel,用於數據共享給多個 view。

SwiftUI 使用聲明式方法構建 UI,程式碼方面簡潔了很多,一套程式碼,三端適用(iOS,iPadOS,macOS(M1))。而且支援實時預覽,大大提高了 UI 開發效率!

距離 APP 支援最低版本 iOS13 應該也不遠了(微信目前最低支援 iOS11.0),iOSer 們,是時候學習一波 SwiftUI 了!隨便再溫習下 swift 相關語法。

展望未來,iOSer 們實現需求起來,終於可以大喊:”很快啊!”

自娛自樂:

剛才有個朋友問我,”OC老師”發生什麼事了,我說怎麼回事,給我發了幾張截圖,我一看,嗷,原來是昨天,有兩個年輕人,實現需求,一個用時九十多分鐘,一個用時八十多分鐘……

但是沒關係啊,我兩百分多鐘以後,需求也做好了。我說 Kotlin 你不講武德,你不懂,他說 “OC 老師”對不起,我不懂,我亂打的,後來他說他練過三四年 Java,看來是有 bear 而來,這個年輕人不講發德,來,騙,來,偷襲,我二十九歲+的老同志,這好嗎?這不好,我勸,這位年輕人好自為之,好好反思,以後不要再犯這樣的錯誤,小聰明啊,開發要以和為貴,要講發德,不要搞窩裡斗,謝謝朋友們。

歡迎掃描下面二維碼,關注我,謝謝!

qrcode_for_gh_b4657e673349_258