范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

干货swift实现todo状态切换

  置顶
  菜鸟入门,各位大佬轻喷,如有谬误之处欢迎讨论建议,也欢迎各位道友与我同行
  "不积跬步,无以至千里;不积小流,无以成江海"
  继续
  上文中已经实现了  TODO  页面的基本新增逻辑以及删除功能
  本文将实现数据每一个  TODO  项的完成状态切换、创建时间
  以及滑动删除功能。
  同时完成一个数据的抽象,即将数据处理的部分抽象到一个对象内,页面中只管调用即可。
  最终效果如下:
  思考
  还是老规矩,既然要抽象一个数据模型出来,那就是一个独立的文件。
  一个关于  TODO  的数据模型。
  至少有两个  struct  ,一个 todoItem  的定义,另一个是 todoList  的定义
  这个数据模型中是所有的关于这个  todo lists  的操作
  如果所有的操作都集中在这个模型中,那我我们的 todo 页面中的所有操作即可调用这个数据模型。 实现
  我们新增一个  TodoModel.swift ,内容如下: import SwiftUI;  // 这里是定义 todo 项的数据结构,结构体用于定义结构,类用于定义完整数据对象 struct TodoItem:Identifiable,Equatable{     // 给生成一个唯一的id作为标识,相当于实现了 Identifiable     let id = UUID();     // todo项名称     var name:String ;     // 是否已经完成,默认为false     var isFinished:Bool = false;     // 创建时间     var createTime:Int = 0;     // 完成时间     var finishTime:Int = 0;     // 用来展示的时间,这里相当于是个 computed     var createdAt:String {         // 将时间戳转为时间字符串         if(createTime == 0) {             return "";         }         let date:Date = Date.init(timeIntervalSince1970: Double(createTime))         let formatter = DateFormatter.init()         formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"         return formatter.string(from: date as Date)     } }  // ObservableObject 代表这是一个可以被观察的对象 class TodoLists : ObservableObject {     // @Published 代表这个变量的任何变化都会被发布到外面使用这个变量的地方,更新视图     // private(set) 代表这个变量的设置、修改等对外隐藏,但是对外可见     // [TodoItem] 代表这是一个数组,里面的每一条数据都是 TodoItem 类型的     @Published private(set) var todoList:[TodoItem];          init(todoList: [TodoItem]) {         self.todoList = todoList         // 如果是个空数组,那么先放一个进去         if(todoList.count == 0 ){             add(name: "请添加TODO")         }     }          // 添加一条 todo项,只要名称即可     func add(name:String){         if(name == ""){             return ;         }         var item = TodoItem(name: name);         item.createTime = Int(Date().timeIntervalSince1970);         self.todoList.insert(item,at: 0);     }          // 切换todo项的是否完成状态,如果完成状态为true那更新finishTime     func toggle(item:TodoItem){         // 找到这一条的索引 index,$0代表这个方法的第一个参数         let index = todoList.firstIndex(where: {$0.id == item.id})         if index != nil {             // index! 代表我知道这个index一定存在,不用再进行判断了             todoList[index!].isFinished.toggle()             // 如果是完成,那么更新已完成时间,否则改为0             if(todoList[index!].isFinished == true){                 todoList[index!].finishTime = Int(Date().timeIntervalSince1970);             }else{                 todoList[index!].finishTime = 0;             }         }     }          // 删除todo     func delete(offsets: IndexSet){         offsets.forEach { index in             todoList.remove(at: index)         }     } }
  既然我们数据模型已经定义好了,那么自然要修改  TodoView.swift 页面中的使用
  修改如下:
  TodoView.swift  import SwiftUI  struct TodoView: View {     // 是否已经登陆     @AppStorage("isLogin") private var isLogin:Bool = false;     // 已经登陆的用户名     @AppStorage("userName") private var userName:String = "";     // 输入框输入的新的TODO     @State private var newItem:String = "";     // 使用我们新的数据模型     @StateObject private var todos = TodoLists(todoList: []);          var body: some View {         VStack{             HStack{                 TextField("请输入新的TODO",text:$newItem).onSubmit {                     todos.add(name: newItem)                     newItem = ""                 }                 Button("确认"){                     todos.add(name: newItem)                     newItem = ""                 }             }.padding()             List{                 // Foreach 开始循环 TodoLists 的indices,需要它的索引值,用于删除等                 // id 需要为一个 Identifier,可以预见,之后我们自己构造数据类型的时候也需要一个 Identifier                 ForEach(todos.todoList){ item in                     HStack{                         VStack{                             HStack{                                 // 字符串拼接,之前已有使用                                 Text("(item.name)")                                 Spacer()                             }                             HStack{                                 Text("(item.createdAt)").font(.subheadline)                                 Spacer()                             }                         }.foregroundColor(item.isFinished ? .gray : .primary)                         // 这里用个Group套起来,里面用三元实现点击切换图标,展示是否已经完成                         Group{                             item.isFinished ?                             Image(systemName: "circle.fill") :                             Image(systemName: "circle")                         }                     }.contentShape(Rectangle())                     .onTapGesture {                         todos.toggle(item: item)                     }                 // 这个调用将实现横滑删除功能                 }.onDelete{ IndexSet in                     todos.delete(offsets: IndexSet)                 }             }.animation(.default,value:todos.todoList)         }     } }  struct TodoView_Previews: PreviewProvider {     static var previews: some View {         TodoView()     } }总结1.  ObservableObject  与 @Published  是在主动定义一个可观察的对象,虽然可以添加许多操作,但是感觉上反而不如 reactive  方法更简洁2. 目前看来, Struct  一般用来定义结构或者视图,Class  才是我们普遍意义上的类。3. 数据抽象虽然简化了View,但是感觉比较繁琐,或许我应该考虑直接都放到  Struct View 里面去,参考 Vue  的结构进行编排,各有优劣,后头试试4. 横滑删除的功能非常好实现,直接在  Foreach 后加上 .onDelete  即可5.  SwiftUI  中有很多这种加方法调用即可实现视图以及功能的方法,也许可以参考到 Vue  或者其他的前端封装里面6. 想实现一个  computed 变量,直接 var  一个,然后在底下写方法即可

观察以色列与伊朗的影子战争特约撰稿杨玉龙据半岛电视台等外媒7月24日报道,近日伊朗情报部门宣布破获了一个位于伊朗境内的间谍网络组织,逮捕数名长期为以色列情报机构摩萨德服务的该组织成员。伊朗情报部门在一份声明英雄联盟电竞经理最鹅式的手游,我愿称其为国产年度最佳英雄联盟可以说是一代玩家的青春,即使现在不怎么玩游戏了,但偶尔看到相关的内容还是忍不住点看回忆一下青春。而作为全球知名IP衍生而出的游戏也不在少数,而目前全网媒体一致好评的英雄联盟窃格瓦拉还是得打工?出狱后当老板接连翻车艾瑞巴蒂,我是鸭鸭!不知道最近,大家有没有关注网红窃格瓦拉周立齐的最新消息。哎?提到周立齐这个名字,可能很多人并不清楚他是谁。但下面这张图,以及这辈子不可能打工的至理名言,大家一定贪官携巨款逃窜6国,和情人躲小岛20天出次门,却因特殊爱好暴露贪官携巨款逃窜6国,和情人躲小岛20天出次门,却因特殊爱好暴露2016年2月1日中午,加勒比海岛国圣文森特和格林纳丁斯(圣格)的付耀波的房子里,突然传来了敲门声。当门被打开时,外面68岁赵雅芝不惧38度高温跑步,打扮精致穿10厘米高跟鞋仍步伐稳健今天,赵雅芝在自己的社交网站上晒出一组视频画面,原来是自己跑步的视频画面,瞬间吸引不少人的围观,网友们都表示还是第一次见到白娘子跑步呢,纷纷点赞赵雅芝真的是超级卖力和敬业。68岁的如何做好一个中层管理者?没有那么多废话,花里胡哨的,就直接教你怎么来第一招向上管理中层管理者70的时间应该用来做向上管理。我这么跟你们说吧,中层管理的核心是服务你的上级,满足上级的一切需求。到了职场中后期尚敬华胜钱学森,似鲁迅,我愿微光追随您尚敬华胜钱学森,似鲁迅,我愿微光追随您这篇文章我思考了好久,却久久不知如何下笔,面对这样的一位伟人,卑微如草芥的我,觉得应该让更多的人觉醒,最后终于鼓起勇气写下这篇拙文,望自己能像一念成魔,四川沐川80后民警请自首吧人的一生会遇到很多的岔路口,站在路口看取舍!就像二舅一念之间人生改写,就像四川民警李强一念之间跌落地狱。是什么让一个热血青年从见义勇为的人民好警察蜕变成今天的杀人犯,这是一个沉重的王丽的双面人生在外穿破洞裤子,金屋内穿戴奢侈品欣赏自己2017年6月13日,青海省西宁市一处高档小区里,一个年近六旬的妇女打开了自己的金屋。虽然已经快六十岁,穿着一身廉价的西装套装,但妇女保养得当,行为举止处处透露着优雅。打开门后,与54岁港星举家定居泰国!女儿学费14万1年,住258万豪宅生活惬意54岁港星陈国邦定居泰国7月27日。知名香港明星陈国邦正式举家搬迁,他们要搬迁的目的地,并不是中国内地,而是要从香港,搬到泰国曼谷生活。陈国邦晒出与家人搭乘飞机的照片,照片中,陈国云南特警执行绝密任务失联,86天后妻子收6个字短信,嚎啕大哭2011年底的一天,云南特警邹路遥,接到了上级领导的一通电话。电话里,领导要求邹路遥收拾好东西前往机场,从指定人员手中拿到机票后,前往任务地点完成任务。到达目的地,妻子却发现丈夫失
人民日报每日金句摘抄1。如果你不花时间,去创造你想要的生活,你将被迫花很多时间,去应付你所不想要的生活,成功的路上,没有人会叫你起床,也没有人会为你买单,你需要自我管理,自我约束,自我突破。2。时间流湖北枣阳大黑马白手起家,29岁办公司,已年入836588万元湖北省,是我国中部地区的经济大省,经济体量在全国排名位居前十,主要经济产业较为发达,加上经济结构常年不断优化,所以,该省综合经济实力较强,尤其在中部地区属于数一数二的经济强省,人均中国经济正在向好继11月上旬的第一轮人民币资产保卫战大获全胜之后,第二轮反击在近日又展开了!最亮眼的标志是,人民币对美元的离岸价,在昨夜今晨逼近了7。02。虽然截至12月1日,人民币对美元的离岸价苹果10月国内市场份额达25,网友华为Mate50系列也挡不住?最近市场调研机构Counterpoint的月度销量数据显示,2022年10月苹果手机的销量环比增长了21,市场份额达到了25,达到了历史最高水平,也就是说每卖出4部手机,里面就有1恭喜詹姆斯!湖人更新出战名单,佩林卡对杜兰特感兴趣北京时间12月1日,NBA常规赛已经开启第六十二天左右,其中追梦格林表示,兰姆首次训练就用投篮征服了我,他这个赛季的表现一直发挥出色,东契奇透露,裁判吹这么多走步让我有点惊讶,很高加纳VS乌拉圭韩国VS葡萄牙加纳VS乌拉圭加纳有利情报加纳自1963年起,参加过23次非洲杯,4次拿到过该项赛事的冠军。加纳参加了2006年世界杯,在2010年南非世界杯上,他们成为第三支进入世界杯八强的非洲阿根廷出线,外媒更新夺冠概率荷兰5,葡萄牙8,一队高达25过去的一天时间,世界杯又进行了4场小组赛,赛果分别是澳大利亚10丹麦,突尼斯10法国,沙特12墨西哥,波兰02阿根廷。C组和D组的排名也就全部诞生了,阿根廷顺利拿到6分,成为C组头高血压患者这种思想不能有今天接诊一位高血压患者,与其短短几分钟的对话,发人深思。该患者自诉高血压病史已经20多年了,最高血压180110mmHg,但平时没有任何症状。我问他您平时吃什么药啊?患者回答我吃的5年阴囊潮湿,内裤湿异味重,调理2个多月,解决男人的困扰阴囊潮湿,是男性常见的问题,我之前门诊上就有很多这样的患者。前阵子在门诊上遇到周先生,他才38岁,有阴囊潮湿已经5年了,一开始就只是感觉下面湿漉漉的,有时候内裤都湿了,很难受。从中梅西传从侏儒症患者到世界球王,13岁打远走他乡打生长激素你一定会成为这个世界上最好的球员,梅西的外婆摸着年仅6岁的梅西的头说道,梅西对此深信不疑。那一天,外婆的话在他瘦弱矮小的身体里发芽长大。十岁那年,一直激励梅西前进的外婆不幸去世。祸口臭,大便溏泄,小便黄,肢体困倦,脾胃湿热该怎么办?脾胃是我们人体十分重要的器官,能帮我们运化水谷,转化为我们人体所需要的能量,一旦脾胃出了问题,就容易产生很多疾病,比较常见的就是由于脾胃湿热带来的大便溏泄,小便黄,乏力,口臭,厌食