这个教程涉及以下内容
- Array(数组)基础
- 通过 DataSource(数据源)显示tableView内容
- 通过 Delegate(委托)使tableView可以响应用户操作
- 使用storyboard的segue实现基本的页面跳转及界面间传值
- 字符串的截取
UITableView
教程实现的这种类似的滚动表格的界面所有智能手机的用户应该都会很熟悉,微信的聊天界面,淘宝的宝贝列表都是这种结构。这是App最常用的一种控件之一。
UITableView有两个重要接口,dataSource和delegate
- dataSource,数据源,顾名思义,它定义了列表的每个cell显示什么样数据信息。(静态)
- delegate,委托,定义了列表如何与用户交互。(动态)
让UITableView显示内容
tableView中的内容不实凭空显示出来的,绝大多数情况下,我们列表的信息是通过数组(Array)这种数据结构存储的,通过如下代码定义并初始化一个数组,里面存储了我们要显示的各种各样的动物。
var animalList = ["🐶 dog", "🐱 cat", "🐸 frog", "🐼 panda", "🐍 snake",
"🐒 monkey", "🦊 fox", "🐝 bee", "🦈 shark", "🐡 puffer",
"🐬 dolphin", "🦎 lizard", "🦍 gorilla", "🐎 horse", "🐖 pig",
"🐄 cow", "🐿 squirrel", "🐆 cheetah", "🐋 whale", "🦏 rhinoceros"]
将tabelView拖入stroyboard并设置为全屏显示,并在ViewController中实现datasource接口方法
extension ViewController: UITableViewDataSource {
//定义了每个cell的显示方式,每次从数组中取出
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "animal cell", for: indexPath)
cell.textLabel?.text = animalList[indexPath.row]
return cell
}
//定义了列表每个section有多少行
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return animalList.count
}
//定义了列表有多少区(section)
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
}
让UITableView响应用户点击
extension ViewController: UITableViewDelegate{
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
animalList.insert(animalList.remove(at: indexPath.row), at: 0)
animalsTableView.moveRow(at: indexPath, to: [0,0])
}
}
这时每次被点击的行就会移到列表的顶部,同时数组也做相应的更新。
Segue实现页面跳转并传值
首先在storyboard中通过拖拽新建一个ViewController命名,并新建一个swift文件与ViewController进行连接,类名设置为DetailViewController。
在新的DetailViewController中拖入两个Label,调整大小并用StackView包裹后居中。
并将label与代码建立连接:
class DetailViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
var fullTitle: String? //用来接收segue传过来的字符串
@IBOutlet weak var emojiTextView: UILabel!
@IBOutlet weak var nameTextView: UILabel!
}
然后在两个Controller之间拖拽新建Segue,将Segue的Identifier设置为"show detail"
在ViewController中设置prepare()方法传值
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let indexPath = sender as! IndexPath
if segue.identifier == "show detail"{
let vc = segue.destination as! DetailViewController
print(animalList[(indexPath.row)])
vc.fullTitle = animalList[(indexPath.row)]
//注意
// 此处不可以直接对 label.text 字符属性进行操作,因为此时 label 为 nil
// vc.emojiTextView.text = animalList[(indexPath.row)] 会导致 crash
}
}
并在DetailViewController中的viewDidLoad中对字符串进行处理并设置对应的Label显示指定内容
override func viewDidLoad() {
super.viewDidLoad()
//分割字符串,从首字符到指定字符
emojiTextView.text = fullTitle?.substring(to: (fullTitle?.index((fullTitle?.startIndex)!, offsetBy: 1))!)
//分割字符串从制定字符到尾字符
nameTextView.text = fullTitle?.substring(from: (fullTitle?.index((fullTitle?.startIndex)!, offsetBy: 4))!)
self.navigationItem.title = nameTextView.text
}
这样这个简单的动物列表就完成啦