Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 要继续还是选择Rowatindexpath?_Ios_Objective C_Uitableview_Didselectrowatindexpath_Detailview - Fatal编程技术网

Ios 要继续还是选择Rowatindexpath?

Ios 要继续还是选择Rowatindexpath?,ios,objective-c,uitableview,didselectrowatindexpath,detailview,Ios,Objective C,Uitableview,Didselectrowatindexpath,Detailview,下面是我当前正在运行的代码。我有一个带有导航控制器、tableview控制器和视图控制器的故事板设置。我正在尝试将为表设置的NSDictionary中的名称传递给detail view控制器。我应该使用prepareforsegue还是didselectrowatindexpath?我应该如何从字典中获取名称来传递 #import "FMInboxViewController.h" #import "FMDetailViewController.h" @interface FMInboxVie

下面是我当前正在运行的代码。我有一个带有导航控制器、tableview控制器和视图控制器的故事板设置。我正在尝试将为表设置的NSDictionary中的名称传递给detail view控制器。我应该使用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;
}
但是现在,当我选择行时,第一次按下时,名称将不会显示在详细信息控制器中。如果返回并选择其他名称,则按下的第一个名称将显示在视图控制器中。关于发生这种情况的原因有什么建议吗?

您需要同时使用这两种方法,在didSelectRowAtIndexPath中,您应该调用[self-PerformsgueWithIdentifier:@identifier sender:self]

在同一视图控制器中,您应该使用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;
}

如果可能的话,在几乎所有的标准场景中都是这样,我会使用Interface Builder来触发segue。您仍然需要实现prepareforsgue:来配置目标视图控制器

要在IB中创建一个序列,在点击单元格或单元格最右侧的附件按钮时触发详细视图,请执行以下步骤:

控制从“表视图”单元格拖动到目标视图控制器,然后释放鼠标或轨迹板。这将打开小的选择面板

选择触发器的来源、选择序列或附件动作以及序列推送的类型、模式或自定义

在属性检查器窗格中,定义序列的标识符,例如UserShowSegue

以下是IB中演示故事板中的图像,该图像说明了如何设置用户视图控制器中的表视图单元,以触发推送序列到详细视图控制器:


这可能是一个老问题,但更详细地说,这可能与谁有关:

1-将两者都用作提到的“@Peter Foti”

2-Segue应该从ParentVC链接到DestinationVC,而不是从原型单元格链接

3-发送器应正确设置

4-设置您的“@property someProperty”

示例代码:

- (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;
}
因为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
}

为什么他需要同时使用这两个呢?如果你已经在prepareForSegue中实例化了一个ViewController,他可以在didSelectRow中使用它。执行一个segue和准备一个segue是两件不同的事情。我理解,但是,如果你不想改变动画,而你只需要使用navigationController的pushViewController方法,那么做一个序列就没有意义了。坦白说,我不明白为什么他们会这么做——为了简单起见?我一直按照@CouchDeveloper说的方式做。如果从单元连接segue,则不需要实现didSelectRowAtIndexPath或调用PerformsgueWithIdentifier。在prepareForSegue中,您可以使用sender参数(该参数将是单元格)来获取所选单元格的indexPath,以便将数据传递到目标视图控制器。当您对单元格使用Xib时,这是一种很好的方法,并且无法将segue直接连接到单元格。这比只使用pushViewController要好,因为它允许您在情节提要中使用表示,以直观地查看正在发生的事情。在prepareForSegue中:您的意思可能是:NSString*key=[keyArray objectAtIndex:section.row]?index.row而不是indexI看不到您调用的[self-PerformsgueWithIdentifier:asdf sender:self]在didSelectRowAtIndexPath中的位置;我把你的代码分成了几个部分,因为大部分代码都隐藏在滚动条后面。我还删除了一些冗余数据。你的问题应该尽量简洁。谢谢你的帮助@JamesWebster这似乎是最现代的方法,可以使用更多的向上投票来击败当前选定的答案。但在这个答案中,您并不是说如何将数据从选定的行传递到目标controller@sports您可以从prepareForSegue:segue:sender:中的sender参数检索数据。发送方是启动segue的对象。您可以使用此参数根据从该对象检索的数据分别启动segue的控件或其他对象来执行不同的操作。如何使发送方成为被点击的行?如果发送者从原型单元格转到新的ViewController,是否是自动的?@sports如果我没有偏离目标,发送者就是实际的UITableViewCell,其中包含已标记的附件视图。当您拥有单元格时,有几种方法可以获取索引路径。另见