XCode TableViewController 在 Objective-C 中详细介绍

Posted

技术标签:

【中文标题】XCode TableViewController 在 Objective-C 中详细介绍【英文标题】:XCode TableViewController to detail in Objective-C 【发布时间】:2015-08-09 02:53:42 【问题描述】:

我有一个带有 4 个选项卡的 TabBarController,其中 3 个是表格视图。我正在尝试为每个表格视图单元格添加详细信息,但我认为故事板效率不高,因为我有 50 多个详细信息页面。我对这一切都很陌生,我试图找出如何将细节链接到每个选项卡几个小时。我的表视图从第二个视图控制器开始。 这是 SecondViewController.m:

#import "SecondViewController.h"
@implementation SecondViewController

    NSArray *tableData;

@synthesize tableData;

#pragma mark - View lifecycle

- (void)viewDidLoad

    tableData = [NSArray arrayWithObjects:@"Carter", @"Greene", @"Hancock", @"Hawkins", @"Johnson", @"Sullivan", @"Unicoi", @"Washington", nil];
    [super viewDidLoad];



#pragma mark - TableView Data Source methods

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:    (NSInteger)section

    return [tableData count];


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:    (NSIndexPath *)indexPath


    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyCell"];

    if (cell == nil)
    
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"MyCell"];
    

    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    cell.textLabel.text = [tableData objectAtIndex:indexPath.row];


    return cell;


@end

这里是 SecondViewController.h:

#import <UIKit/UIKit.h>

@interface SecondViewController : UIViewController <UITableViewDelegate,
UITableViewDataSource>

@property(nonatomic, retain) NSArray *tableData;
@end

如果这有帮助,这是我的故事板。

如果有人可以帮助我以最轻松的方式为每个表格视图单元格单独添加详细信息,我将不胜感激。谢谢!

【问题讨论】:

您可能需要更多地解释您所说的细节是什么意思?当用户点击您的一个单元格时打开详细视图控制器?请详细说明。 我使用的是 Swift,所以很遗憾我可能无法在 Obj-C 中为您详细说明,但我可以提供一个高级别的解决方案。你应该创建另一个UIViewController.....比如说DetailViewController。你可以按照你想要的视觉方式进行设置,然后当用户点击TableViewCell 时,对DetailViewController 执行segue 并将数据从单元格传递到视图控制器。 为什么您认为故事板效率不高?以我的经验,你可以在情节提要中拥有相当数量的对象,并且它们在运行时被拆分并分部分加载,很少有任何运行时问题。另外,你真的有 50 个不同的详情页面,还是它们都是相同的布局,只是内容不同? Meredith,您的 50 个不同的详细信息页面在结构上是不同的,还是它们真的只是相同样式的详细信息页面(或某些有限数量的详细信息页面类型)的不同排列,只是显示不同的详细信息数据?通常你会看到几种类型的细节场景,这只是目标场景中显示什么数据的问题。如果不了解这些细节场景之间变化的本质,就很难回答这个问题。 @Rob,每个详细信息页面的格式完全相同。基本上是标题标签、电话号码和邮寄地址 【参考方案1】:

如果使用故事板,过程相当简单。

首先,我建议将原型“表格视图单元格”拖到您的表格视图中。然后,您可以 control-从该原型单元拖动到您的目标场景,以在单元和下一个场景之间添加一个转场:

确保选择该原型单元并设置其故事板标识符(我使用“单元”)。您将需要引用该故事板标识符,如下面的代码示例所示。我还在 IB 的那个单元原型中配置了外观相关的东西(比如披露指示器),所以我不必担心在代码中这样做,我可以看到 UI 在 IB 中的样子。

现在您可以转到表格视图控制器并 (a) 简化 cellForRowAtIndexPath(因为在使用单元原型时您不需要关于 if (cell == nil) ... 的逻辑);还要实现prepareForSegue 将数据传递到目标场景:

//  SecondViewController.m

#import "SecondViewController.h"
#import "DetailsViewController.h"

@interface SecondViewController ()
@property (nonatomic, strong) NSArray *tableData;
@end

@implementation SecondViewController

- (void)viewDidLoad 
    [super viewDidLoad];

    self.tableData = @[@"Carter", @"Greene", @"Hancock", @"Hawkins", @"Johnson", @"Sullivan", @"Unicoi", @"Washington"];


- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
    if ([segue.destinationViewController isKindOfClass:[DetailsViewController class]]) 
        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
        NSString *name = self.tableData[indexPath.row];
        [(DetailsViewController *)segue.destinationViewController setName:name];
    


- (IBAction)unwindToTableView:(UIStoryboardSegue *)segue 
    // this is intentionally blank; but needed if we want to unwind back here


#pragma mark - Table view data source

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
    return self.tableData.count;


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];

    cell.textLabel.text = self.tableData[indexPath.row];

    return cell;


@end

显然,这假设您创建了一个 DetailsViewController 并将其指定为目标场景的基类,然后为您想要传递给该目标场景的任何值创建属性:

//  DetailsViewController.h

#import <UIKit/UIKit.h>

@interface DetailsViewController : UIViewController

@property (nonatomic, copy) NSString *name;

@end

然后这个目标场景将获取传递给它的name 值并填写UILabel

//  DetailsViewController.m

#import "DetailsViewController.h"

@interface DetailsViewController ()

@property (weak, nonatomic) IBOutlet UILabel *nameLabel;

@end

@implementation DetailsViewController

- (void)viewDidLoad 
    [super viewDidLoad];

    self.nameLabel.text = self.name;


@end

坦率地说,这个过程无疑会在任何 UITableView 教程中更清楚地描述,包括对“单元原型”的讨论(您的代码示例表明您使用的是早于单元原型的旧教程)。

【讨论】:

是的,非常感谢!我开始了解代码和故事板之间的关系,这对我有很大帮助!【参考方案2】:

我认为代码和storyboard的关系如下:

    代码实现应用程序的功能。 Storyboard包含很多场景,这些场景实现了用户界面,包括数据展示、数据输入、数据输出。 代码从这些场景中读取数据并将结果输出到场景中。 代码是内部逻辑功能实体和用户界面呈现的故事板。

【讨论】:

以上是关于XCode TableViewController 在 Objective-C 中详细介绍的主要内容,如果未能解决你的问题,请参考以下文章

我现有的 TableViewController 在 Xcode 11 beta1 上崩溃

Xcode Storyboard 问题 - 按钮栏按钮仅出现在 TableViewController 的底部

XCode TableViewController 在 Objective-C 中详细介绍

设置变异 TableViewController 的背景图像

向 TableViewController 添加边距

一个 TableViewController,多个 segue 动作和返回