创建 UITableView
表视图是可以选择的行列表。每行都是从数据源填充的。此示例创建一个简单的表视图,其中每行是单行文本。
在故事板中添加 UITableView
尽管有许多方法可以创建 UITableView
,但最简单的方法之一是在 Storyboard 中添加一个。打开你的故事板并将 UITableView
拖到你的 UIViewController
上。确保使用自动布局正确对齐工作台(将所有四个边都固定)。
用数据填充表格
为了在表视图中动态显示内容(即从数组源,核心数据模型,网络服务器等数据源加载),你需要设置数据源。
创建一个简单的数据源
如上所述,数据源可以是包含数据的任何数据源。它完全取决于你如何格式化它和它的内容。唯一的要求是你必须能够稍后阅读它,以便你可以在需要时使用数据填充表格的每一行。
在这个例子中,我们只是设置一个数组,其中包含一些字符串(文本)作为我们的数据源:
迅速
let myDataArray: [String] = ["Row one", "Row two", "Row three", "Row four", "Row five"]
Objective-C
// You'll need to define this variable as a global variable (like an @property) so that you can access it later when needed.
NSArray *myDataArray = @[@"Row one", @"Row two", @"Row three", @"Row four", @"Row five"];
在 View Controller 中设置数据源
确保你的视图控制器符合 UITableViewDataSource
协议。
迅速
class ViewController: UIViewController, UITableViewDataSource {
Objective-C
@interface ViewController : UIViewController <UITableViewDataSource>
一旦你的视图控制器声明它将符合 UITableViewDataSource
(这就是我们上面刚刚完成的),你需要在视图控制器类中至少实现以下方法:
-
tableView:numberOfRowsInSection
,这会询问你的表视图应该有多少行。// Swift func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return self.myDataArray.count }
-
tableView:cellForRowAtIndexPath
,请求你为tableView:numberOfRowsInSection
中指定的每一行创建并返回一个单元格。因此,如果你说需要 10 行,则每行调用此方法十次,并且你需要为每个行创建一个单元格。// Swift func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { // Create a new cell here. The cellReuseIdentifier needs to match the reuse identifier from the cell in your Storyboard let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier(cellReuseIdentifier) as UITableViewCell! // Set the label on your cell to the text from your data array cell.textLabel?.text = self.myDataArray[indexPath.row] return cell }
警告 : 对于
cellForRowAtIndexPath:
中的任何单元格,你不能返回 nil。这将导致你的应用程序崩溃,你将在控制台中看到以下错误:Uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'
将表视图的数据源连接到视图控制器
你可以通过在视图控制器上将表的 dataSource
属性设置为 self
来通过代码执行此操作。或者你可以在你的故事板中选择你的表视图,打开属性检查器中,选择 dataSource
的奥特莱斯面板,然后拖动到你的视图控制器( 注 :请确保你连接到的 UIViewController,不是一个 UIView 或其他物体在你的 UIViewController 中)。
处理行选择
当用户点击表格视图中的某一行时,通常情况下,你需要做一些事情 - 要做出回应。在许多应用中,当你点按一行时,会显示有关你点按的项目的详细信息。想想消息应用程序:当你点击显示某个联系人的行时,与该人的对话将显示在屏幕上。
要做到这一点,你必须遵守 UITableViewDelegate
协议。这样做符合数据源协议。但是这一次,你只需将它添加到 UITableViewDataSource
旁边并用逗号分隔。所以看起来应该是这样的:
迅速
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
Objective-C
@interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
没有必要的方法来实现表视图的委托。但是,要处理行选择,你需要使用以下方法:
-
tableView:didSelectRowAtIndexPath
,只要轻敲一行就会调用它,这样就可以做出响应。对于我们的示例,我们只需在 Xcode 日志中打印确认声明。// Swift func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { print("You tapped cell number \(indexPath.row).") } // Objective-C - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSLog(@"You tapped cell number %ld.", (long)indexPath.row); }
最终的解决方案
请参阅下面的完整设置,仅提供代码,无需解释。
迅速
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
// Data model: These strings will be the data for the table view cells
let myDataArray: [String] = ["Row one", "Row two", "Row three", "Row four", "Row five"]
// cell reuse id (cells that scroll out of view can be reused)
let cellReuseIdentifier = "cell"
// don't forget to hook this up from the storyboard
@IBOutlet var myTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Register the table view cell class and its reuse id
myTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: cellReuseIdentifier)
// This view controller itself will provide the delegate methods and row data for the table view.
myTableView.delegate = self
myTableView.dataSource = self
}
// number of rows in table view
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.myDataArray.count
}
// create a cell for each table view row
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// create a new cell if needed or reuse an old one
let cell:UITableViewCell = tableView.dequeueReusableCellWithIdentifier(cellReuseIdentifier) as UITableViewCell!
// set the text from the data model
cell.textLabel?.text = self.myDataArray[indexPath.row]
return cell
}
// method to run when table view cell is tapped
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("You tapped cell number \(indexPath.row).")
}
}
Objective-C
ViewController.h
#import <UIKit/UIKit.h>
@interface ViewController: UIViewController <UITableViewDelegate, UITableViewDataSource> {
IBOutlet UITableView *myTableView;
NSArray *myDataArray;
}
@end
ViewController.m
#import "ViewController.h"
// cell reuse id (cells that scroll out of view can be reused)
NSString * _Nonnull cellReuseIdentifier = @"cell";
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Data model: These strings will be the data for the table view cells
myDataArray = @[@"Row one", @"Row two", @"Row three", @"Row four", @"Row five"];
// Register the table view cell class and its reuse id
[myTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:cellReuseIdentifier];
// This view controller itself will provide the delegate methods and row data for the table view.
myTableView.delegate = self;
myTableView.dataSource = self;
}
// number of rows in table view
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return myDataArray.count;
}
// create a cell for each table view row
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// create a new cell if needed or reuse an old one
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellReuseIdentifier];
// set the text from the data model
cell.textLabel.text = myDataArray[indexPath.row];
return cell;
}
// method to run when table view cell is tapped
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSLog(@"You tapped cell number %ld.", (long)indexPath.row);
}
@end