gomzyakov
@gomzyakov
Руководитель проектов

Проблема с segue-переходом в Storyboard?

Есть UITableViewController с UISearchDisplayController в которых выводятся списки неких товаров. Для того, чтобы и в основной таблице и в таблице поиска информация преподносилась одинаково была создана ячейка GoodsCell (унаследована от UITableViewCell). GoodsCell создана программно и имеет следующий простой вид:

@interface GoodsCell ()
{
	UIImageView *photoView;
	UILabel *titleLabel;
}

@end

@implementation GoodsCell

- (GoodsCell *)init {
	CGRect frame = CGRectMake(0.0f, 0.0f, 320.0f, 70.0f);

	self = [super initWithFrame:frame];
	if (self) {
		photoView = [[UIImageView alloc] initWithFrame:CGRectMake(10.0f, 10.0f, 50.0f, 50.0f)];
		[self addSubview:photoView];

		self.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

		titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(70.0f, 10.0f, 215.0f, 50.0f)];
		// задаём некоторые атрибуты метки
		[self addSubview:titleLabel];
	}
	
	return self;
}

- (void)setPhoto:(UIImage *)photo {
	photoView.image = photo;
}

- (void)setTitle:(NSString *)title {
	[titleLabel setText:title];
}

@end



В Storyboard-е создан Seque от непосредственно GoodsViewController (отвечает за отображение списка товаров) к GoodsDetailViewController (детальная информация о товаре). Обработка нажатия происходит следующим образом:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
	UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
	[self performSegueWithIdentifier:@"goodsDetail" sender:tableView];
}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
	if ([[segue identifier] isEqualToString:@"goodsDetail"])
	{
		GoodsDetailViewController *goodsDetailViewController = (GoodsDetailViewController *)[segue destinationViewController];
		
		if (sender == self.searchDisplayController.searchResultsTableView)
		{
			NSIndexPath *indexPath = [self.searchDisplayController.searchResultsTableView indexPathForSelectedRow];
			Goods *goods = [foundGoodsObjects objectAtIndex:indexPath.row];
			[goodsDetailViewController setGoods:goods];
		}
		else
		{
			NSIndexPath *indexPath = [goodsTable indexPathForSelectedRow];
			Goods *goods = [goodsObjects objectAtIndex:indexPath.row];
			[goodsDetailViewController setGoods:goods];
		}
	}
}



При нажатии на ячейку приложение падает с ошибкой:

*** Assertion failure in -[GoodsCell layoutSublayersOfLayer:], /SourceCache/UIKit/UIKit-2372/UIView.m:5776
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Auto Layout still required after executing -layoutSubviews. GoodsCell's implementation of -layoutSubviews needs to call super.'



Код в текущую версию проекта был перенесен из другой git-ветки, при не очень удачном конфликтном слиянии. Элементы в Storyboard и IBOutlet-ы добавлялись вручную. В оригинальной ветке всё прекрасно работает — переход на детализированное представление происходит, ничего не падает.


Голову себе сломал, в чём проблема. Need help, уважаемые хабрознатоки!


P.S. Пробовал размещать фэйковую ячейку в таблице и делать seque от неё — не помогает, результат тот же самый.
  • Вопрос задан
  • 4169 просмотров
Пригласить эксперта
Ответы на вопрос 7
@IgorFedorchuk
Можно посмотреть на эту тему здесь, а также здесь
Ответ написан
Комментировать
LIAL
@LIAL
Так в ошибке же указано что он хочет: GoodsCell's implementation of -layoutSubviews needs to call super.
Судя по этому косяк не в приведенном вами коде, а там где TableView своими GoodCell заполняете — там надо пнуть родителя
Ответ написан
Комментировать
по-моему нехорошо в init вызывать initWithFrame, перегрузите уже сразу initWithFrame. задание высоты ячейки здесь ничего не даст, это всё равно будет управляться таблицей в heightForRowAtIndexPath:
Ответ написан
Комментировать
Segue можно тянуть прямо из ячеек, тогда не нужно будет реализовывать такой didSelectRowForIndexPath
Ответ написан
Комментировать
usgleb
@usgleb
Ух ты! А как вы ячейки создаете? [[GoodsCell alloc] init]?
Ответ написан
@Zoxaer
Если вы используете NSLayoutConstraint для расстановки titleLabel в ячейки, то надо указать titleLabel.translatesAutoresizingMaskIntoConstraints = NO.
Вообще для всех UIView, которые расстанавливаются через NSLayoutConstraint (это AutoLayout), надо указывать view.translatesAutoresizingMaskIntoConstraints = NO.
А если использовать AutoLayout через InterfaceBuilder, то он автоматически этот флаг изменяет.
Ответ написан
Комментировать
внимательно не вникал, но перегружать init, да еще и с вызовом initWithFrame - не лучшая идея
точно не уверен, но кажется, если и перегружать, то
- initWithStyle:reuseIdentifier:
в вашем viewController у таблицы стоит сделать
- registerClass:forCellReuseIdentifier:
и потом как обычно использовать
- dequeueReusableCellWithIdentifier:

или даже сделать xib для ячейки, там всё расставить, наделать констрейнтов и использовать
UITableView registerNib:forCellReuseIdentifier:
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы