当前位置:网站首页>Swift简单实现待办事项
Swift简单实现待办事项
2022-07-25 09:21:00 【yueliangmua】
待办事项的创建无非就是实现增删改查,可以根据TableView自带的editing来实现更改顺序和滑动删除,创建button的点击事件来更改是否打勾的状态,通过正反向传值、设置代理来实现更改label内容和添加待办事项。
目录
最终效果图




视频效果
待办事项效果图
创建TableView
待办事项的设计通常使用tableVIew会让页面更加友好操作方便,我通常在mainstory里搭建所需页面。如下图所示。

先拉一个UITableView进来,再给里面拉一个TableViewCell进行操作。接着就是在cell里面添加构成元素了,根据图片很容易可以发现共含两个元素,一个就是可供点击的button,另一个就是展示内容的label,于是我们先添加一个占位符。
常量constant代码
import Foundation
import UIKit
let kTodoTableVCID = "TodoTableVCID"
let kTodoCellID = "TodoCellID"
let kAddTodoID = "AddTodoID"
let kEditTodoID = "EditTodoID"
func pointIcon(_ iconName: String, _ pointSize: CGFloat = 22) -> UIImage?{
let config = UIImage.SymbolConfiguration(pointSize: pointSize)
return UIImage(systemName: iconName, withConfiguration: config)
}
连接mainstory和代码
将刚刚所设计的UI连接上TodosTableView的swift文件。根据MVC模式,单独创建一个swift文件储存模版元素。
import Foundation
//class Todo{
// var name = ""
// var checked = ""
//}
struct Todo {
var name: String
var checked: Bool
}
在TodosTableVC.swift文件中用数组存储cell中的初始内容。
var todos = [
Todo(name: "旅游", checked: false),
Todo(name: "复习", checked: false),
Todo(name: "图书馆", checked: false),
Todo(name: "面试", checked: false),
Todo(name: "入职", checked: false)
]
//row用于后续使用
var row = 0将TableView放入navigation中,实现界面的出栈入栈
设置NavigationItem的内容,用UIControllerView自带的edititem实现编辑按钮。
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
editButtonItem.title = nil
editButtonItem.image = pointIcon("arrow.up.arrow.down.circle.fill")
navigationItem.leftBarButtonItem = editButtonItem
navigationItem.rightBarButtonItem?.image = pointIcon("plus.circle.fill", 22)
}
override func setEditing(_ editing: Bool, animated: Bool) {
super.setEditing(editing, animated: animated)
if isEditing{
editButtonItem.image = nil
editButtonItem.title = "完成"
}else{
editButtonItem.title = nil
editButtonItem.image = pointIcon("arrow.up.arrow.down.circle.fill")
}
}在prepar方法中设置页面跳转时的参数传递
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == kAddTodoID{
let vc = segue.destination as! TodoTableVC
vc.delegate = self
}else if segue.identifier == kEditTodoID{
let vc = segue.destination as! TodoTableVC
vc.delegate = self
let cell = sender as! TodoCell
//cell-->indexpath
//tableView.indexPath(for: cell)
//indexpath-->cell
//tableView.cellForRow(at: indexPath) as! TodoCell
row = tableView.indexPath(for: cell)!.row
vc.name = todos[row].name
}
}设置TodosTableVC的delegate
设置点击时的背景颜色只显示瞬间的灰色,在选中时就设置取消选中。
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
// let vc = storyboard?.instantiateViewController(withIdentifier: kTodoTableVCID) as! TodoTableVC//在storyboar上找制作好的vc
// navigationController?.pushViewController(vc, animated: true)
}设置编辑模式,在isEditing状态可以排序但取消删除并且取消锁进,非isEditing状态可以进行滑动删除。
override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
if !isEditing{
return .delete
}else{
return .none
}
}
override func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool {
return false
}TodoTableVCDelegate用于反向传值,实现新增待办事项和修改已有待办事项
extension TodosTableVC: TodoTableVCDelegate{
func didAdd(name: String) {
todos.append(Todo(name: name, checked: false))
tableView.insertRows(at: [IndexPath(row: todos.count - 1, section: 0)], with: .automatic)
// tableView.reloadData()
}
func didEdit(name: String) {
todos[row].name = name
let indexPath = IndexPath(row: 0, section: 0)
let cell = tableView.cellForRow(at: indexPath) as! TodoCell
cell.todoLabel.text = name
tableView.reloadData()
}
}
完整代码如下
import UIKit
extension TodosTableVC{
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
// let vc = storyboard?.instantiateViewController(withIdentifier: kTodoTableVCID) as! TodoTableVC//在storyboar上找制作好的vc
// navigationController?.pushViewController(vc, animated: true)
}
// override func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String? {
// return "点击以删除"
// }
override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
if !isEditing{
return .delete
}else{
return .none
}
}
override func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool {
return false
}
}
extension TodosTableVC: TodoTableVCDelegate{
func didAdd(name: String) {
todos.append(Todo(name: name, checked: false))
tableView.insertRows(at: [IndexPath(row: todos.count - 1, section: 0)], with: .automatic)
// tableView.reloadData()
}
func didEdit(name: String) {
todos[row].name = name
let indexPath = IndexPath(row: 0, section: 0)
let cell = tableView.cellForRow(at: indexPath) as! TodoCell
cell.todoLabel.text = name
tableView.reloadData()
}
}
设置TodosTableVC的dataSource
默认返回一个section和todos数据个cell
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return todos.count
}cell的复用方法中设置选中时图标的变化和字体颜色
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: kTodoCellID, for: indexPath) as! TodoCell
let checkBoxBtn = cell.checkBoxBtn!
let todoLabel = cell.todoLabel!
let initSelected = todos[indexPath.row].checked
// var contentConfiguration = cell.defaultContentConfiguration()
// contentConfiguration.text = "昵称"
// contentConfiguration.secondaryText = "个性签名"
// contentConfiguration.image = UIImage(systemName: "star")
// cell.contentConfiguration = contentConfiguration
// Configure the cell...
checkBoxBtn.isSelected = initSelected
todoLabel.text = todos[indexPath.row].name
todoLabel.textColor = initSelected ? .tertiaryLabel : .label
//改
// checkBoxBtn.addAction(UIAction(handler: { action in
// self.todos[indexPath.row].checked.toggle()
// let checked = self.todos[indexPath.row].checked
// checkBoxBtn.isSelected = checked
// todoLabel.textColor = checked ? .tertiaryLabel : .label
// }), for: .touchUpInside)
checkBoxBtn.tag = indexPath.row
checkBoxBtn.addTarget(self, action: #selector(toggleCheck), for: .touchUpInside)
return cell
}
@objc func toggleCheck(checkBoxBtn: UIButton){
// 改
let row = checkBoxBtn.tag
self.todos[row].checked.toggle()
let checked = self.todos[row].checked
checkBoxBtn.isSelected = checked
let cell = tableView.cellForRow(at: IndexPath(row: row, section: 0)) as! TodoCell
cell.todoLabel.textColor = checked ? .tertiaryLabel : .label
}设置移动时的数据变化
override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
let todoToRemove = todos[fromIndexPath.row]
todos.remove(at: fromIndexPath.row)
todos.insert(todoToRemove, at: to.row)
tableView.reloadData()
}完整代码如下
import UIKit
extension TodosTableVC{
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return todos.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: kTodoCellID, for: indexPath) as! TodoCell
let checkBoxBtn = cell.checkBoxBtn!
let todoLabel = cell.todoLabel!
let initSelected = todos[indexPath.row].checked
// var contentConfiguration = cell.defaultContentConfiguration()
// contentConfiguration.text = "昵称"
// contentConfiguration.secondaryText = "个性签名"
// contentConfiguration.image = UIImage(systemName: "star")
// cell.contentConfiguration = contentConfiguration
// Configure the cell...
checkBoxBtn.isSelected = initSelected
todoLabel.text = todos[indexPath.row].name
todoLabel.textColor = initSelected ? .tertiaryLabel : .label
//改
// checkBoxBtn.addAction(UIAction(handler: { action in
// self.todos[indexPath.row].checked.toggle()
// let checked = self.todos[indexPath.row].checked
// checkBoxBtn.isSelected = checked
// todoLabel.textColor = checked ? .tertiaryLabel : .label
// }), for: .touchUpInside)
checkBoxBtn.tag = indexPath.row
checkBoxBtn.addTarget(self, action: #selector(toggleCheck), for: .touchUpInside)
return cell
}
@objc func toggleCheck(checkBoxBtn: UIButton){
// 改
let row = checkBoxBtn.tag
self.todos[row].checked.toggle()
let checked = self.todos[row].checked
checkBoxBtn.isSelected = checked
let cell = tableView.cellForRow(at: IndexPath(row: row, section: 0)) as! TodoCell
cell.todoLabel.textColor = checked ? .tertiaryLabel : .label
}
// Override to support editing the table view.删
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// Delete the row from the data source
todos.remove(at: indexPath.row)
// tableView.deleteRows(at: [indexPath], with: .fade)
tableView.reloadData()
} else if editingStyle == .insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
let todoToRemove = todos[fromIndexPath.row]
todos.remove(at: fromIndexPath.row)
todos.insert(todoToRemove, at: to.row)
tableView.reloadData()
}
}
TodoCell的设置
import UIKit
class TodoCell: UITableViewCell {
@IBOutlet weak var todoLabel: UILabel!
@IBOutlet weak var checkBoxBtn: UIButton!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
checkBoxBtn.setImage(UIImage(systemName: "checkmark.circle.fill"), for: .selected)
checkBoxBtn.setImage(UIImage(systemName: "circle"), for: .normal)
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
cell中含todoLabel和checkBoxBtn,设置checkBoxBtn选中和未选中时的图标,setSelected设置选中标签时的背景。
创建第二个TableView,TodoTableView
搭建页面连接代码
设置didAdd和didEdit的协议
protocol TodoTableVCDelegate{
func didAdd(name: String)
func didEdit(name: String)
}通过textView输入框内容是否为空判断是增还是改
@IBAction func done(_ sender: Any) {
navigationController?.popViewController(animated: true)
if !todoTextView.text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty{
if name != nil{
delegate?.didEdit(name: todoTextView.text)
}else{
delegate?.didAdd(name: todoTextView.text)
}
}
}点击返回按钮和完成按钮页面出栈
@IBAction func back(_ sender: Any) {
navigationController?.popViewController(animated: true)
}设置顶部返回和完成图标
override func viewDidLoad() {
super.viewDidLoad()
todoTextView.becomeFirstResponder()
todoTextView.delegate = self
todoTextView.text = name
if name != nil{
navigationItem.title = "编辑待办事项"
}
navigationItem.leftBarButtonItem?.image = pointIcon("chevron.backward.circle.fill")
navigationItem.rightBarButtonItem?.image = pointIcon("checkmark.circle.fill")
}设置textview的实时换行,遵循textViewdelegat协议,实现实时检测换行方法
extension TodoTableVC: UITextViewDelegate{
func textViewDidChange(_ textView: UITextView) {
// tableView.beginUpdates()
// tableView.endUpdates()
tableView.performBatchUpdates { }
}
}布局刷新。
边栏推荐
猜你喜欢

~4.2 ccf 2021-12-1 序列查询

Data control language (DCL)

浏览器访问swagger失败,显示错误ERR_UNSAFE_PORT
![[GYCTF2020]Ez_Express](/img/ce/02b90708f215715bb53cacfd4c21f0.png)
[GYCTF2020]Ez_Express

DVWA练习一 暴力破解

Analysis of five data structure principles of redis
![[GKCTF 2021]easynode](/img/f0/1daf6f83fea66fdefd55608cbddac6.png)
[GKCTF 2021]easynode

¥1-2 例2.2 将两个集合的并集放到线性表中

*6-3 节约小能手

How to deploy the jar package to the server? Note: whether the startup command has nohup or not has a lot to do with it
随机推荐
Basic network knowledge
Redis string 结构命令
@3-2 CCF 2020-12-2 期末预测之最佳阈值
Go基础2
laravel 调用第三方 发送邮件 (php)
Go foundation 4
Week小结
< T> Generic method demonstration
How to convert object data into arrays
Go基础4
OC--继承和多态and指针
[GYCTF2020]Node Game
[GPLT] 2022 大众情人(floyd)
uni-app小程序如何自定义标题内容(如何解决小程序标题不居中)
sqli-labs Basic Challenges Less11-22
OC--Foundation--数组
用kotlin怎么写Android切换界面
DVWA练习一 暴力破解
OC--Foundation--字符串+日期和时间
The jar package has been launched on Alibaba cloud server and the security group has been opened, but postman still can't run. What should we do