SwiftUI:看我展示52张扑克牌,“很快啊!”
思路
使用 SwiftUI 创建 UI 结构;
使用 swift 的枚举和结构体实现数据生成,通过 viewModel 整合数据用于展示(交互暂时未做,因此不涉及 MVVM 设计模式中的数据绑定)。
效果图
画布实时预览 iphone 效果图:

运行 iphone11 黑暗模式效果图:

运行 ipad air 模拟器效果图:

相关代码解析
枚举创建扑克牌号码
//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()
}
}
源码
感受
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 而来,这个年轻人不讲发德,来,骗,来,偷袭,我二十九岁+的老同志,这好吗?这不好,我劝,这位年轻人好自为之,好好反思,以后不要再犯这样的错误,小聪明啊,开发要以和为贵,要讲发德,不要搞窝里斗,谢谢朋友们。
欢迎扫描下面二维码,关注我,谢谢!

SwiftUI:看我展示52张扑克牌,“很快啊!”的更多相关文章
- Java 用LinkdeList实现52张扑克牌
用LinkdeList实现52张扑克牌(不含大小王)的洗牌功能.提示:花色 ,和数字分别用数组存储. import java.util.LinkedList; import java.util.Ran ...
- 理解面向对象编程---C#控制台实现52张扑克牌的分法
52张牌随机分给4个玩家,要求每个玩家的牌用一个一维数组表示. 我们采用模拟大法.初始化一副扑克牌,洗牌,发牌. using System; using System.Collections.Gene ...
- 52张扑克牌快速生成js
function* generatePoker() { const points = ['A', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K']; yield* ...
- 贝叶斯公式52张牌猜黑桃A策略
贝叶斯公式52张牌猜黑桃A策略 考虑有208平行世界,其中有4个世界(1/52)的黑桃A方在第一张牌的位置,余下204个世界中,有4个世界的黑桃A在第2张牌的位置,4个世界在第3张牌的位置..... ...
- Java基础练习——读心术(扑克牌魔术——21张扑克牌)
Java基础练习--读心术(扑克牌魔术--21张扑克牌) 用到了Scanner,for循环,if-else语句,集合,线程的Thread.sleep()方法 话不多说,直接上代码!
- jquery.elevateZoom实现仿淘宝看图片,一张小的,一张大用于鼠标经过时候显示
实现这个效果你需要准备两张图片,一张小的,一张大用于鼠标经过时候显示.然后我们只要为img标签添加data-zoom-image属性,其值为大图的地址,最后在javascript中选择该图片调用ele ...
- 看过这两张图,就明白 Buffer 和 Cache 之间区别
Buffer常见的是这个: 对,就是铁道端头那个巨大的弹簧一类的东西.作用是万一车没停住,撞弹簧上减速慢,危险小一些.叫缓冲. Cache常见的是这个: 没错,就是一种保管箱.看到右边那个被锈掉的Fo ...
- 零基础入门Python数据分析,只需要看懂这一张图,附下载链接!
摘要 在做数据分析的过程中,经常会想数据分析到底是什么?为什么要做数据数据分析?数据分析到底该怎么做?等这些问题.对于这些问题,一开始也只是有个很笼统的认识. 最近这两天,读了一下早就被很多人推荐的& ...
- 看了这一张GIF图你就明白什么回事了,必看的经典!--快速构建一个请假流程
下面介绍一下FSBPM构建一个请假单流程 1.数据模型的构建 输入业务中需要的数据项即可,比如[申请人,开始时间,结束时间,请假天数,请假理由,附件上传..........] 2.自定义流程 审批节点 ...
随机推荐
- 欧拉计划第十一题--java实现
先做个说明,里面所有的题都是我自己写的解题报告,由于我的能力有限,是个刚学java的小白,有很多不足的地方,还望各位大佬不奢赐教,谢谢! Largest product in a grid In th ...
- 一些常见JAVA问题
原文:https://blog.csdn.net/weiyongxuan/article/details/45920765 一.Java的异常的基类是java.lang.Throwable 二.守护线 ...
- 还在本地安装MySQL/RabbitMQ/MongoDB 吗 ? 或许你可以试试这个【附下载】
我们经常在Windows开发的时候,需要在本地进行调试.当然也免不了安装数据库.消息队列 等一些开发软件.等什么时候我们重新安装了这边软件.如此的繁琐. 尤其是安装RabbitMQ 消息队列的时候,居 ...
- pxe装机部署
批量全自动安装操作系统 dhcp:自动分配IP tftp:微系统安装系统 httpd:网络源 检查环境(永久性关闭selinux) setenforce 0 sed -i s/=enforcing/= ...
- 4G DTU数据传输终端的功能介绍
4G DTU是基于4G网络的自动化数据传输终端,是一种物联网无线数据传输设备,使用公用运营商的4G网络为用户提供无线远距离数据传输功能,使用工业级32位的高性能通信处理器和工业级无线模块,以嵌入式实时 ...
- MYSQL中inner join、left join 和 right join的区别
首先join连接是用来进行多表关联查询的,join连接方式有三种连接方式:inner join.left join 和 right join 1.inner join 可以简写成join,叫内连接,查 ...
- NOIP2018 填坑记
Oct,22ed,2018 DAY -18 又是颓废的一天呢 我好菜啊,一个圆方树弄了一整天(点双怎么那么毒瘤).(铁人两项怎么那么多点) Oct,23rd,2018 DAY -17 又双叒叕颓了一天 ...
- drf JWT认证模块与自定制
JWT模块 在djangorestframework中,有一款扩展模块可用于做JWT认证,使用如下命令进行安装: pip install djangorestframework-jwt 现在,就让我们 ...
- 你说一下对Java中的volatile的理解吧
前言 volatile相关的知识其实自己一直都是有掌握的,能大概讲出一些知识,例如:它可以保证可见性:禁止指令重排.这两个特性张口就来,但要再往深了问,具体是如何实现这两个特性的,以及在什么场景下使用 ...
- AQS解析
什么是AQS? AQS是JUC内存的基石,它本质上是一个抽象类,定义了多线程下资源争夺与释放的规则和过程,许多实现类都是继承于AQS,使用AQS的骨架. AQS的原理 AQS总体上来看是由一个FIFO ...