Для Segue или для didSelectRowAtIndexPath?
Ниже приведен код, который я сейчас запускаю. У меня есть настройка раскадровки с контроллером навигации и контроллером таблицы и контроллером вида. Я пытаюсь передать имя из 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;
}
Однако теперь, когда я выбираю строку, имя не будет отображаться в подробном контроллере при первом нажатии. Если вы вернетесь и выберите другое имя, первое имя, которое вы нажали, появится в контроллере представления. Любые предложения о том, почему это происходит?
Ответы
Ответ 1
Вам нужно использовать оба, в 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;
}
Ответ 2
Если возможно (и это имеет место практически во всех стандартных сценариях), я бы использовал Interface Builder для запуска segue. Вам все еще нужно реализовать prepareForSegue:
для настройки контроллера представления назначения.
Чтобы создать сегмент в IB, который вызывает подробный вид при нажатии на ячейку или кнопку аксессуара (справа на правой стороне ячейки), выполните следующие действия:
-
Управляйте перетаскиванием из Table View Cell в контроллер представления назначения и отпустите мышь или трекпад. Это открывает небольшую панель выбора.
-
Выберите источник триггера: " Сегмент выбора" или " Аксессуарное действие" и тип сегмента ( " push", " модальный" или " пользовательский" ).
-
В области "Инспектор атрибутов" определите "Идентификатор" сегмента, например. "UserShowSegue".
Здесь изображение из демонстрационной раскладки Demo в IB, которое иллюстрирует, как "Table View Cell" в контроллере представления "Пользователи" настроено на запуск "push" segue на контроллер подробного представления:
![enter image description here]()
Ответ 3
Может быть, старый вопрос, но более подробный, для кого это может касаться:
1- Используйте оба значения как "(@Peter-Foti)".
2- Segue должен быть связан с ParentVC с DestinationVC (НЕ из ячейки Prototype).
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;
}
Ответ 4
Поскольку 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
}