以下是我目前正在运行的代码。我有一个故事板设置与导航控制器和tableview控制器和视图控制器。我试图将我为表格设置的NSDictionary中的名称传递给详细视图控制器。我应该使用prepareforsegue或didselectrowatindexpath吗?我如何从字典中取出名称来传递它?
#import "FMInboxViewController.h"
#import "FMDetailViewController.h"
@interface FMInboxViewController ()
@end
@implementation FMInboxViewController
@synthesize keyArray;
@synthesize tableArray;
@synthesize tblDictionary;
@synthesize filteredArray;
- (void)viewDidLoad
{
[super viewDidLoad];
NSMutableArray *ary=[[NSMutableArray alloc]init];
[ary addObject:@"Adam"];
[ary addObject:@"Fred"];
[ary addObject:@"Angel"];
// ... many similar entries
[ary addObject:@"James"];
[ary addObject:@"Mukthesh"];
self.tblDictionary =[self fillingDictionary:ary];
}
表视图数据源
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return [keyArray count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
NSArray *ary = [self.tblDictionary valueForKey:[keyArray objectAtIndex:section]];
return [ary count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSString *key = [keyArray objectAtIndex:[indexPath section]];
NSArray *array = (NSArray *)[self.tblDictionary valueForKey:key];
NSString *cellTitle = [array objectAtIndex:[indexPath row]];
cell.textLabel.text = cellTitle;
// Configure the cell...
return cell;
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSString *title = [keyArray objectAtIndex:section];
return title;
}
//-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// NSString *key = [keyArray objectAtIndex:[indexPath section]];
// NSArray *array = (NSArray *)[self.tblDictionary valueForKey:key];
// self.selectedName = [array objectAtIndex:indexPath.row];
// NSLog(@"Selected Name in Did select: %@", self.selectedName);
//
// [self performSegueWithIdentifier:@"showDetail" sender:self];
//}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:@"showDetail"]) {
NSIndexPath *section = [self.tableView indexPathForSelectedRow];
NSString *key = [keyArray objectAtIndex:section];
NSArray *array = (NSArray *)[self.tblDictionary valueForKey:key];
NSString *cellTitle = [array objectAtIndex:[indexPath row]];
NSLog(@"Selected Name in Did select: %@", self.selectedName);
}
}
辅助方法
#pragma mark - Helper Methods
- (NSMutableDictionary *)fillingDictionary:(NSMutableArray *)sentArray {
keyArray = [[NSMutableArray alloc] init];
[keyArray removeAllObjects];
NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
[sentArray sortUsingSelector:@selector(compare:)];
for ( NSString *str in sentArray) {
NSString *charVal = [str substringToIndex:1];
NSString *charStr = [NSString stringWithString:charVal];
NSLog(@" charStr = %@", charStr);
if (![keyArray containsObject:charStr]) {
NSMutableArray *charArray = [[NSMutableArray alloc] init];
[charArray addObject:str];
[keyArray addObject:charStr];
[dic setValue:charArray forKey:charStr];
}
else {
NSMutableArray *prevArray = (NSMutableArray *)[dic valueForKey:charStr];
[prevArray addObject:str];
[dic setValue:prevArray forKeyPath:charStr];
}
}
return dic;
}
@end
好的,我将该部分改为看起来像这样
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *key = [keyArray objectAtIndex:[indexPath section]];
NSArray *array = (NSArray *)[self.tblDictionary valueForKey:key];
self.selectedName = [array objectAtIndex:indexPath.row];
NSLog(@"Selected Name in Did select: %@", self.selectedName);
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
FMDetailViewController *dvc = (FMDetailViewController *)segue.destinationViewController;
dvc.name = self.selectedName;
}
但是现在当我选择行时,第一次按下时名称将不会显示在细节控制器中。如果您返回并选择其他名称,则您按下的第一个名称将显示在视图控制器中。有关为何发生这种情况的任何建议?
答案 0 :(得分:33)
您需要同时使用这两者,didSelectRowAtIndexPath
您应该致电[self performSegueWithIdentifier:@"identifier" sender:self];
在同一个View Controller中,您应该使用prepareForSegue
方法从segue中取出destinationViewController
,然后在该视图控制器上设置您想要设置的任何属性。
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.someProperty = [self.someArray objectAtIndex:indexPath.row];
[self performSegueWithIdentifier:@"segueID" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
UIViewController *vcToPushTo = segue.destinationViewController;
vcToPushTo.propertyToSet = self.someProperty;
}
答案 1 :(得分:28)
如果可能的话(几乎所有标准场景都是这种情况),我会使用Interface Builder来触发segue。您仍然需要实现prepareForSegue:
来配置目标视图控制器。
为了在IB中创建一个segue,当点击单元格或附件按钮(在单元格的最右侧)时触发详细视图执行以下步骤:
控制从表格视图单元格拖动到目标视图控制器并释放鼠标或触控板。这将打开小型选择面板。
选择触发器的来源,“选择segue ”或“附件操作”以及segue的类型(“ push < / strong>“,”模态“或”自定义“)。
在“属性检查器”窗格中,定义segue的“标识符”,例如“UserShowSegue”。
这是来自IB演示故事板的图像,它说明了如何设置“用户”视图控制器中的“表视图单元”以触发“推送”segue到详细视图控制器:
答案 2 :(得分:2)
可能是一个老问题,但要更详细地说明可能涉及的人:
1-同时使用&#39;(@ Peter-Foti)&#39;提及。
2- Segue应该从ParentVC链接到DestinationVC(不是来自Prototype Cell)。
3-发件人应该正确设置。
4-设置你的&#39; @property(someProperty)&#39;。
示例代码:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.someProperty = [self.someArray objectAtIndex:indexPath.row];
[self performSegueWithIdentifier:@"segueID" sender:self.someProperty];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
UIViewController *vcToPushTo = segue.destinationViewController;
vcToPushTo.propertyToSet = sender;
}
答案 3 :(得分:2)
因为可以用故事板可视化编程替换didSelectRowAtIndexPath
,所以我建议像prepareForSegue
那样执行所有逻辑:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let cell = sender as! UITableViewCell
let indexPath = tableView.indexPath(for: cell)!
... and then use indexPath to set up the destination
}