zoukankan      html  css  js  c++  java
  • 简单APP——ToDoList的二次开发(日期规范化+构建搜索栏)

    极简第一版

    极简版教学:SwiftUI:从零点五开始的APP开发之路 https://www.bilibili.com/video/BV1Kg4y1i7dd?p=1
    原项目代码为自己寒假在跟学时的代码,由于版本不同所以和原视频的代码在通知推送方面有一些出入

    运行效果

    已实现功能

    该APP已经是个完整的独立APP,已实现功能如下:
    1、自定义添加、收藏和取消收藏、删除事项,并同时支持单选和多选统一操作
    2、在事项结束时间到达时向用户发送通知和提醒,在首次打开APP前询问用户许可发送通知权限

    待完善

    1、日期格式并没有进行设置和规范化
    2、在进行事项按时间排序时,对id进行了修改,在swiftUI中很容易会导致一些奇怪的问题
    3、已完成数据的增删改而没有查找功能

    二次开发

    日期格式

    原版的日期格式是这个样子的:

    这非常乱码,那么我们只需要在初始化的时候,规范一下日期格式
    为了方便使用,我们定义一个Date转为规范模式后的String(因为我们输出的时候时以字符串的方式)的方法:

    //日期 -> 字符串
    func date2String(_ date:Date, dateFormat:String = "yyyy-MM-dd HH:mm:ss") -> String {
        let formatter = DateFormatter()
        formatter.locale = Locale.init(identifier: "zh_CN")
        formatter.dateFormat = dateFormat
        let date = formatter.string(from: date)
        return date
    }
    

    然后在SingleCardView中,更改显示日期部分的代码

        Text(date2String(self.UsrData.ToDoList[index].duedate)) //原代码为:self.UsrDate.ToDoList[index].duedate.description,即仅仅将date转换为string
                                .font(.subheadline)
                                .foregroundColor(Color.gray)
    

    完成后新的效果如下:

    id的维护

    在第一版中,我们在sort排序后,对id进行了更新和修改。在swiftUI中尽量不要修改元素的id,因为id是区分不同View的方式,所以直接更改id会出现一些问题(尤其是动画方面)
    对此进行进一步完善主要涉及到UserData里的sort()和ContentView中的SingleCardView

    sort()

    对于sort()的修改方式及其简单暴力——直接把id更新删掉即可

    //第一版:
    func sort() {
            self.ToDoList.sort(by: {(data1, data2) in
                return(data1.duedate.timeIntervalSince1970 < data2.duedate.timeIntervalSince1970)
            })
            
            for i in 0..<self.count {
                self.ToDoList[i].id = i
            }
        }
    
    //第二版:
    func sort() {
            self.ToDoList.sort(by: {(data1, data2) in
                return(data1.duedate.timeIntervalSince1970 < data2.duedate.timeIntervalSince1970)
            })
        }
    

    SingleCardView

    由于sort方法没有更改id,因此元素的id不再与其在数组ToDoList中的个数(index)相同;因此我们使用一个计算属性index来找到ToDoList中对应的singleToDo是在数组中的哪一个;
    我们在SingleCardView中以前的index改为以下代码

        var singleData: SingleToDo
        var index: Int{
            self.UsrData.ToDoList.firstIndex(where: {data in data.id == self.singleData.id})!
        }
    

    并在Content()调用SIngleCardView时将传入的index改为singleData

    查找(搜索)功能

    与uIKit不同的是,SwiftUI没有内置的搜索栏控制,但是搭建一个并不很难

    搜索栏UI

    IOS中的标准搜索栏,它实际上由一个文本字段和一个取消按钮组成。
    首先,我们声明了两个变量:一个是搜索文本的绑定,另一个是存储搜索字段状态的变量(编辑与否)。并且,只有当用户点击搜索字段时,才会显示取消按钮

    import SwiftUI
    
    struct Search: View {
        @Binding var text: String
        @State private var isEditing = false
        
        var body: some View {
            
            HStack {
                TextField("Search...", text: self.$text)
                    .padding(7)
                    .padding(.horizontal, 25)
                    .background(Color(.systemGray6))
                    .cornerRadius(8)
                    .overlay(                                        //文本字段上覆盖两个系统图像
                        HStack {
                            Image(systemName: "magnifyingglass")
                                .foregroundColor(.gray)
                                .frame(minWidth:0, maxWidth: .infinity, alignment: .leading)
                                .padding(.leading, 8)
                            if isEditing {
                                Button(action: {
                                    self.text = ""
                                }) {
                                    Image(systemName: "multiply.circle.fill")
                                        .foregroundColor(.gray)
                                        .padding(.trailing, 8)
                                }
                            }
                        }
                    )
                    .padding(.horizontal, 10)
                    .onTapGesture {
                        self.isEditing = true
                }
                
                if isEditing {
                    Button(action: {
                        self.isEditing = false
                        self.text = ""
                    }) {
                        Text("Cancel")
                    }
                    .padding(.trailing, 10)
                    .transition(.move(edge: .trailing))
                    .animation(.default)
                }
            }
        }
    }
    
    struct Search_Previews: PreviewProvider {
        static var previews: some View {
            Search(text: .constant(""))
                .padding(.leading)
        }
    }
    
    

    效果如下:

    使用搜索栏进行数据过滤

    切换到ContentView.swift并将搜索栏添加到列表视图中
    在body中添加

      Search(text: self.$searchText)
            .padding(.top, 11.0)
    

    视图如下:

    然后在显示的时候再加一个判断当前是否在搜索,如果不在就都显示,如果在搜索就只显示title中包含搜索词的事项卡片

                            
                            if searchText.isEmpty {
                                ForEach (self.UsrData.ToDoList) { item in
                                    if item.deleted == false {
                                        if !self.showFavouriteOnly || item.isFavourite {
                                            SingleCardView(singleData : item, editingMode: self.$editingMode, selected: self.$selected)
                                                .environmentObject(self.UsrData)
                                                .padding()
                                                .animation(.spring())
                                                .transition(.slide)
                                        }
                                    }
                                }
                            } else {
                                ForEach (self.UsrData.ToDoList) { item in
                                    if item.deleted == false {
                                        if item.title.contains(self.searchText) {
                                            SingleCardView(singleData : item, editingMode: self.$editingMode, selected: self.$selected)
                                                .environmentObject(self.UsrData)
                                                .padding()
                                                .animation(.spring())
                                                .transition(.slide)
                                        }
                                    }
                                }
                            }
    

    完善后效果

    小结

    SwiftUI的既有他的方便快捷的方式,也方便开发者面向其他UI最终效果进行一个项目的迁移和设计
    与Android开发还是有一定不同,优化和美化也是不断学习完善的过程

  • 相关阅读:
    短信平台接口调用方法参考
    C#部分类与部分方法
    Oracle表字段类型更改的一个经验
    ueditor的上传文件漏洞(c#)
    判断一个文件是否是指定后缀名的文件
    利用FluorineFx的ByteArray上传图片
    FluorineFx 播放FLV 时堆棧溢出解决 FluorineFx NetStream.play 并发时,无法全部连接成功的解决办法
    Flex数据交互之Remoting[转]
    fluorinefx使用手册
    SharedObject使用:在FluorineFx.net与Flex中使用共享对象维护在线用户列表实例【转】
  • 原文地址:https://www.cnblogs.com/Eirlys/p/14497623.html
Copyright © 2011-2022 走看看