How to pass data to detail view after being selected in a table view?

守給你的承諾、 提交于 2020-01-19 11:52:47

问题


I have a UITableViewController that has data populated from an NSMutableArray called userList. When specific user is selected, it goes to a detail view, and updates the title in the NavBar, but it wont pass the data to update a UILabel in the UIView.

- (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];

}

Should I be trying to push the data from the table view to the detail view, or have the detail view try to pull the data from the table view?

DetailView.h has the following line that is in fact hooked up in IB.

IBOutlet UILabel *userNameLbl

回答1:


The userNamelbl isn't instantiated until the view is loaded from the nib file. This doesn't happen immediately at initialisation, but will have happened by the time viewDidLoad is called.

So, you should to declare a property in DetailView to store your title, and then assign that value to userNamelbl.text in the viewDidLoad method.

For example, in your table viewController:

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

and in your detail viewController:

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

The viewController's navigationItem property is created when the viewController is initialised, hence you can assign to the navigationItem.title immediately.


Swift code

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

and

class DetailView: UIViewController {

    @IBOutlet var userNameLbl: UILabel
    var userName:NSString?

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



回答2:


Are you mixing UIViews and UIViewControllers? You should have a DetailViewController class that inherits from UIViewController or some sublcass (like UITableViewController); it will have DetailViewController.m and DetailViewController.h files to declare and define your class. It should have a corresponding nib that defines the UIView that the UIViewController loads; it will have a DetailView.xib file.

You can't assign the value to the UILabel directly because UIView hasn't been loaded at the time you need to assign the user name value.

In order to do what you want, you should declare a public property (userName) to "push" the value onto the detail view controller from the master controller. Once the detail view is loaded, it can assign the value from the property to the label and nav bar.

In your master view controller (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];
}

In your detail view controller:

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;
}



回答3:


Presumably your DetailView requires the data from your selected row to function?

If so, I'd say the 'correct' approach would be to create a custom init method that passed in the data you required. For example:

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

There's nothing inherently wrong with your approach, but passing the data the view controller requires at its creation is architecturally better (in my opinion, I'm sure someone will disagree!). For example, think of a table view controller - you pass in the table view style in the init method, you don't set it later on. Same for a UIImageView - you have an initWithImage method that lets you set the image at creation.



来源:https://stackoverflow.com/questions/7562258/how-to-pass-data-to-detail-view-after-being-selected-in-a-table-view

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!