iOS开发Swift-13-界面跳转,新增待办事项,实时刷新,反向传值-待办事项App(2)
1.制作新增界面UI
进入Main界面,选中当前页面,点击右下角,选择Navigation Controller.Navigation Controller是一个容器,用于控制页面跳转.
新建一个Table View Controller,作为跳转之后的页面.
选中Table View,将他的Content改为Static Cells.
选中Table View Section,将Rows改为1.
将Table View的Style改为Inset Grouped.
选中首页的Navigation Otem,将Title改为待办事项.
2.制作主界面新增按钮
要在Navigetion Item中新增按钮,需要使用Bar Button Item.拉到待办事项的右侧,作为新增待办事项的加号➕.
将Item的Tint和Image改成相应的样式.
3.跳转
将加号按钮Ctrl加拖拽到右边的Table View Controller页面.
拖拽并选择后呈现效果如下.
4.将"待办事项"修改为大标题.
选中Navigation Controller的Navigation Bar,勾选Prefers Large Titles.启动运行即可发现,"待办事项已经成为了大标题.
5.将新增页面上的"<待办事项"这个返回按钮修改成一个返回图标.
新增一个Bar Butten Item,拖拽覆盖掉"<待办事项".在界面右上角也添加一个Bar Butten Item作为完成图标.
将返回键的图标修改成对应样式.
为完成键添加对应样式.
6.新增一个CocoaTouch Class类型的class,类型选择为UITableViewController,取名为TodoTableViewController.
在新增页中连接Class:TodoTableViewController.
创建返回按钮的IBAction:back.
创建完成按钮的IBAction:done.
为back和done编写代码使点击他们能够返回首页.
TodoTableViewController:
import UIKit class TodoTableViewController: UITableViewController { override func viewDidLoad() { super.viewDidLoad() } @IBAction func back(_ sender: Any) { navigationController?.popViewController(animated: true) } @IBAction func done(_ sender: Any) { navigationController?.popViewController(animated: true) } }
7.将新增图标,返回图标,完成图标变大.
Constants:
import Foundation import UIKit let kTodoCellID = "TodoCellID" //将图标变大的方法 func pointIcon(_ iconName: String, _ pointSize: CGFloat = 22) -> UIImage{ let config = UIImage.SymbolConfiguration(pointSize: pointSize) return UIImage(systemName:iconName, withConfiguration: config)! }
TodosViewController:
import UIKit class TodosViewController: UITableViewController { var todos = [ Todo(name: "学习iOS课程的基础课", checked: false), Todo(name: "学习iOS课程的零基础赏月App开发", checked: true), Todo(name: "学习iOS课程的零基础木琴App开发", checked: false), Todo(name: "学习iOS课程的零基础和风天气App开发", checked: false), Todo(name: "学习iOS课程的零基础待办事项App开发", checked: false), Todo(name: "学习iOS课程的小红书App开发", checked: false) ] override func viewDidLoad() { super.viewDidLoad() navigationItem.rightBarButtonItem?.image = pointIcon("plus.circle.fill") // 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. // self.navigationItem.rightBarButtonItem = self.editButtonItem } // MARK: - Table view data source //配置TableView的一些数据 override func numberOfSections(in tableView: UITableView) -> Int { // #warning Incomplete implementation, return the number of sections return 1 //总共有1个分类 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // #warning Incomplete implementation, return the number of rows return todos.count //总共有10个待办事项 } 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.todoLable! let initSelected = todos[indexPath.row].checked // // Configure the cell... // //配置主标题的文本 // var contentConfiguration = cell.defaultContentConfiguration() // contentConfiguration.text = "昵称" //主标题 // contentConfiguration.secondaryText = "个性签名" //副标题 // contentConfiguration.image = UIImage(systemName: "star") //图片 // cell.contentConfiguration = contentConfiguration checkBoxBtn.isSelected = initSelected //将cell的是否被选中属性改为todos的当前行的checked属性 todoLabel.text = todos[indexPath.row].name todoLabel.textColor = initSelected ? .tertiaryLabel : .label //三元运算符.根据是否被选中进行判断,如果被选中的话变成浅色,未被选中就是原来的Lable Color. cell.checkBoxBtn.addAction(UIAction(handler: { action in self.todos[indexPath.row].checked.toggle() //如果check原来是true,被点击之后就进行取反,变成false. let checked = self.todos[indexPath.row].checked checkBoxBtn.isSelected = checked todoLabel.textColor = checked ? .tertiaryLabel : .label }), for: .touchUpInside) return cell } /* // Override to support conditional editing of the table view. override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { // Return false if you do not want the specified item to be editable. return true } */ /* // 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 tableView.deleteRows(at: [indexPath], with: .fade) } 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) { } override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { } /* // Override to support conditional rearranging of the table view. override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool { // Return false if you do not want the item to be re-orderable. return true } */ // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // Get the new view controller using segue.destination. // Pass the selected object to the new view controller. } }
TodoTableViewController:
import UIKit class TodoTableViewController: UITableViewController { override func viewDidLoad() { super.viewDidLoad() navigationItem.leftBarButtonItem?.image = pointIcon("chevron.left.circle.fill") navigationItem.rightBarButtonItem?.image = pointIcon("checkmark.circle.fill") } @IBAction func back(_ sender: Any) { navigationController?.popViewController(animated: true) } @IBAction func done(_ sender: Any) { navigationController?.popViewController(animated: true) } }
8.使新增框可以输入多行文本
将多行文本控件text view拖入Table view中.
修改Text View中Text的文本,将可滚动Scrolling Enable以及上面的上下滚动和左右滚动取消勾选.
设置TextView的上下左右约束.
将TextView作为Outlet拖拽到TodoTableViewController中.
9.将输入的Text反向传值到首页.
指定identifier为AddTodoID.
Constants:
import Foundation import UIKit let kTodoCellID = "TodoCellID" let kAddTodoID = "AddTodoID" //将图标变大的方法 func pointIcon(_ iconName: String, _ pointSize: CGFloat = 22) -> UIImage{ let config = UIImage.SymbolConfiguration(pointSize: pointSize) return UIImage(systemName:iconName, withConfiguration: config)! }
TodosViewController:
import UIKit class TodosViewController: UITableViewController { var todos = [ Todo(name: "学习iOS课程的基础课", checked: false), Todo(name: "学习iOS课程的零基础赏月App开发", checked: true), Todo(name: "学习iOS课程的零基础木琴App开发", checked: false), Todo(name: "学习iOS课程的零基础和风天气App开发", checked: false), Todo(name: "学习iOS课程的零基础待办事项App开发", checked: false), Todo(name: "学习iOS课程的小红书App开发", checked: false) ] override func viewDidLoad() { super.viewDidLoad() navigationItem.rightBarButtonItem?.image = pointIcon("plus.circle.fill") // 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. // self.navigationItem.rightBarButtonItem = self.editButtonItem } // MARK: - Table view data source //配置TableView的一些数据 override func numberOfSections(in tableView: UITableView) -> Int { // #warning Incomplete implementation, return the number of sections return 1 //总共有1个分类 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // #warning Incomplete implementation, return the number of rows return todos.count //总共有10个待办事项 } 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.todoLable! let initSelected = todos[indexPath.row].checked // // Configure the cell... // //配置主标题的文本 // var contentConfiguration = cell.defaultContentConfiguration() // contentConfiguration.text = "昵称" //主标题 // contentConfiguration.secondaryText = "个性签名" //副标题 // contentConfiguration.image = UIImage(systemName: "star") //图片 // cell.contentConfiguration = contentConfiguration checkBoxBtn.isSelected = initSelected //将cell的是否被选中属性改为todos的当前行的checked属性 todoLabel.text = todos[indexPath.row].name todoLabel.textColor = initSelected ? .tertiaryLabel : .label //三元运算符.根据是否被选中进行判断,如果被选中的话变成浅色,未被选中就是原来的Lable Color. cell.checkBoxBtn.addAction(UIAction(handler: { action in self.todos[indexPath.row].checked.toggle() //如果check原来是true,被点击之后就进行取反,变成false. let checked = self.todos[indexPath.row].checked checkBoxBtn.isSelected = checked todoLabel.textColor = checked ? .tertiaryLabel : .label }), for: .touchUpInside) return cell } /* // Override to support conditional editing of the table view. override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { // Return false if you do not want the specified item to be editable. return true } */ /* // 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 tableView.deleteRows(at: [indexPath], with: .fade) } 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) { } override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { } /* // Override to support conditional rearranging of the table view. override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool { // Return false if you do not want the item to be re-orderable. return true } */ // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == kAddTodoID{ let vc = segue.destination as! TodoTableViewController vc.delegate = self } } } extension TodosViewController: TodoTableViewControllerDelegate{ func didAdd(name: String){ print(name) } }
TodoTableViewController:
import UIKit protocol TodoTableViewControllerDelegate{ func didAdd(name: String) } class TodoTableViewController: UITableViewController { var delegate: TodoTableViewControllerDelegate? @IBOutlet weak var todoTextView: UITextView! override func viewDidLoad() { super.viewDidLoad() navigationItem.leftBarButtonItem?.image = pointIcon("chevron.left.circle.fill") navigationItem.rightBarButtonItem?.image = pointIcon("checkmark.circle.fill") } @IBAction func back(_ sender: Any) { navigationController?.popViewController(animated: true) } @IBAction func done(_ sender: Any) { if !todoTextView.text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty{ delegate?.didAdd(name: todoTextView.text) } navigationController?.popViewController(animated: true) } }
测试一下:
10.传值后在首页显示已新增的待办事项.
TodosViewController:
import UIKit class TodosViewController: UITableViewController { var todos = [ Todo(name: "学习iOS课程的基础课", checked: false), Todo(name: "学习iOS课程的零基础赏月App开发", checked: true), Todo(name: "学习iOS课程的零基础木琴App开发", checked: false), Todo(name: "学习iOS课程的零基础和风天气App开发", checked: false), Todo(name: "学习iOS课程的零基础待办事项App开发", checked: false), Todo(name: "学习iOS课程的小红书App开发", checked: false) ] override func viewDidLoad() { super.viewDidLoad() navigationItem.rightBarButtonItem?.image = pointIcon("plus.circle.fill") // 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. // self.navigationItem.rightBarButtonItem = self.editButtonItem } // MARK: - Table view data source //配置TableView的一些数据 override func numberOfSections(in tableView: UITableView) -> Int { // #warning Incomplete implementation, return the number of sections return 1 //总共有1个分类 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // #warning Incomplete implementation, return the number of rows return todos.count //总共有10个待办事项 } 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.todoLable! let initSelected = todos[indexPath.row].checked // // Configure the cell... // //配置主标题的文本 // var contentConfiguration = cell.defaultContentConfiguration() // contentConfiguration.text = "昵称" //主标题 // contentConfiguration.secondaryText = "个性签名" //副标题 // contentConfiguration.image = UIImage(systemName: "star") //图片 // cell.contentConfiguration = contentConfiguration checkBoxBtn.isSelected = initSelected //将cell的是否被选中属性改为todos的当前行的checked属性 todoLabel.text = todos[indexPath.row].name todoLabel.textColor = initSelected ? .tertiaryLabel : .label //三元运算符.根据是否被选中进行判断,如果被选中的话变成浅色,未被选中就是原来的Lable Color. cell.checkBoxBtn.addAction(UIAction(handler: { action in self.todos[indexPath.row].checked.toggle() //如果check原来是true,被点击之后就进行取反,变成false. let checked = self.todos[indexPath.row].checked checkBoxBtn.isSelected = checked todoLabel.textColor = checked ? .tertiaryLabel : .label }), for: .touchUpInside) return cell } /* // Override to support conditional editing of the table view. override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { // Return false if you do not want the specified item to be editable. return true } */ /* // 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 tableView.deleteRows(at: [indexPath], with: .fade) } 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) { } override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { } /* // Override to support conditional rearranging of the table view. override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool { // Return false if you do not want the item to be re-orderable. return true } */ // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == kAddTodoID{ let vc = segue.destination as! TodoTableViewController vc.delegate = self } } } extension TodosViewController: TodoTableViewControllerDelegate{ func didAdd(name: String){ todos.append(Todo(name: name, checked: false)) tableView.insertRows(at: [IndexPath(row: todos.count - 1, section: 0)], with: .automatic) } }
启动测试:
11.实现用户输入新增待办事项时实时换行.
将Todo Text View Ctrl拖拽到添加待办事项这里,选择delegate.
TodoTableViewController:
import UIKit protocol TodoTableViewControllerDelegate{ func didAdd(name: String) } class TodoTableViewController: UITableViewController { var delegate: TodoTableViewControllerDelegate? @IBOutlet weak var todoTextView: UITextView! override func viewDidLoad() { super.viewDidLoad() navigationItem.leftBarButtonItem?.image = pointIcon("chevron.left.circle.fill") navigationItem.rightBarButtonItem?.image = pointIcon("checkmark.circle.fill") } @IBAction func back(_ sender: Any) { navigationController?.popViewController(animated: true) } @IBAction func done(_ sender: Any) { if !todoTextView.text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty{ delegate?.didAdd(name: todoTextView.text) } navigationController?.popViewController(animated: true) } } extension TodoTableViewController: UITextViewDelegate{ func textViewDidChange(_ textView: UITextView) { //将Table View重新布局 tableView.performBatchUpdates { //不需要放任何东西就可以自动刷新布局 } } }
测试:
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性