如何在表视图中选择后将数据传递到详细视图?

时间:2011-09-26 22:48:33

标签: iphone objective-c ios xcode uitableview

我有一个UITableViewController,其中包含一个名为userList的NSMutableArray填充的数据。选择特定用户后,它将转到详细视图,并更新NavBar中的标题,但它不会传递数据以更新UIView中的UILabel。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

[tableView deselectRowAtIndexPath:indexPath animated:NO];

//Attempt at a singleton to pass the data
DetailView *details = [[DetailView alloc] init];
details.userNameLbl = [userList objectAtIndex:indexPath.row];


DetailView *detailVC = [[DetailView alloc] initWithNibName:nil bundle:nil];

//This line doesn't pass the data
detailVC.userNameLbl.text = [userList objectAtIndex:indexPath.row];

//This line does update the title in the NavBar
detailVC.navigationItem.title = [userList objectAtIndex:indexPath.row];

[self.navigationController pushViewController:detailVC animated:YES];

[details release];
[detailVC release];

}

我是否应该尝试将数据从表格视图推送到详细视图,或者让详细视图尝试从表格视图中提取数据?

DetailView.h具有以下一行,实际上已连接到IB。

IBOutlet UILabel *userNameLbl

3 个答案:

答案 0 :(得分:11)

在从nib文件加载视图之前,不会实例化userNamelbl。这不会在初始化时立即发生,但会在调用viewDidLoad时发生。

因此,您应该在DetailView中声明一个属性来存储您的标题,然后在userNamelbl.text方法中将该值分配给viewDidLoad

例如,在你的表viewController中:

DetailView *detailVC = [[DetailView alloc] initWithNibName:nil bundle:nil];
detailVC.userName = [userList objectAtIndex: indexPath.row];

并在您的详细视图中查看:

- (void) viewDidLoad
{
   [super viewDidLoad];
   self.userNameLbl.text = self.userName;
}

viewController的navigationItem属性是在viewController初始化时创建的,因此您可以立即分配给navigationItem.title


Swift代码

let detailVC = DetailView(nibName: nil, bundle: nil)
detailVC.userName = userList.objectAtIndex(indexPath.row) as? NSString

class DetailView: UIViewController {

    @IBOutlet var userNameLbl: UILabel
    var userName:NSString?

    override func viewDidLoad() {
        super.viewDidLoad()
        self.userNameLbl.text = self.userName
    }    
} 

答案 1 :(得分:4)

您是在混合UIViews还是UIViewControllers?你应该有一个DetailViewController类,它继承自UIViewController或某个sublcass(如UITableViewController);它将有DetailViewController.mDetailViewController.h个文件来声明和定义您的类。它应该有一个相应的笔尖,用于定义UIView加载的UIViewController;它将有一个DetailView.xib文件。

您无法直接将值分配给UILabel,因为在您需要分配用户名值时尚未加载UIView

为了做你想做的事,你应该声明一个公共属性(userName),将值从主控制器“推”到详细视图控制器上。加载详细信息视图后,它可以将属性中的值分配给标签和导航栏。

在主视图控制器(UITableViewController)中:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:NO];

    DetailViewController *detailVC = [[DetailView alloc] initWithNibName:@"DetailView" bundle:nil];

    detailVC.userName = [userList objectAtIndex:indexPath.row];

    [self.navigationController pushViewController:detailVC animated:YES];

    [detailVC release];
}

在您的详细视图控制器中:

DetailViewController.h

@property (retain) NSString* userName;
@property (nonatomic, retain) IBOutlet UILabel *userNameLbl;

DetailViewController.m

@synthesize userName;
@synthesize userNameLbl;

-(void) viewDidLoad {
    [super viewDidLoad];
    self.userNameLbl.text = self.userName;
    self.navigationItem.title = self.userName;
}

答案 2 :(得分:0)

大概您的DetailView要求所选行中的数据正常运行吗?

如果是这样,我会说“正确”的方法是创建一个传递所需数据的自定义init方法。例如:

[[DetailView alloc] initWithTitle:(NSString *)title text:(NSString *)text]

您的方法没有任何本质上的错误,但传递视图控制器在创建时所需的数据在架构上更好(在我看来,我确信有人会不同意!)。例如,考虑一个表视图控制器 - 您在init方法中传递表视图样式,稍后不进行设置。对于UIImageView也是如此 - 您可以使用initWithImage方法在创建时设置图像。