web-dev-qa-db-ja.com

セグエまたはdidSelectRowAtIndexPath?

以下は、私が現在実行しているコードです。 navコントローラーと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

OK、セクションを次のように変更しました

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

しかし、今私が行を選択すると、名前は最初のプレスの詳細コントローラーに表示されません。戻って別の名前を選択すると、押した最初の名前がビューコントローラに表示されます。これが発生する理由について何か提案はありますか?

13
fbm351

両方を使用する必要があります。didSelectRowAtIndexPathでは、[self performSegueWithIdentifier:@"identifier" sender:self];を呼び出す必要があります

同じビューコントローラーで、prepareForSegueメソッドがセグエから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;
}
33
Peter Foti

可能であれば(そしてこれはほとんどすべての標準的なシナリオに当てはまります)、Interface Builderを使用してセグエをトリガーします。宛先のビューコントローラを構成するには、prepareForSegue:を実装する必要があります。

セルまたはアクセサリボタン(セルの右端)をタップしたときに詳細ビューをトリガーするセグエットをIBで作成するには、次の手順を実行します。

  1. テーブルビューセルから目的のビューコントローラーへのドラッグを制御し、マウスまたはトラックパッドを離します。小さな選択パネルが開きます。

  2. トリガーのソース、「選択セグエ」または「アクセサリアクション」とセグエのタイプ(「プッシュ」、 modal "または" custom ")。

  3. [属性インスペクター]ペインで、セグエの「識別子」を定義します。 「UserShowSegue」。

以下は、IBのデモストーリーボードの画像で、「ユーザー」ビューコントローラーの「テーブルビューセル」が詳細ビューコントローラーへの「プッシュ」セグエをトリガーするように設定されている様子を示しています。

enter image description here

28
CouchDeveloper

古い質問かもしれませんが、それが関係するかもしれない誰のためにもっと詳細に:

1-言及されている「(@ Peter-Foti)」のように両方を使用します。

2-セグエは、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;
}
2
iTRQ

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