2014-01-23 3 views
3

Похоже, я нашел ошибку в методе pushViewController navigationController. Для того, чтобы воссоздать его я взял мастер подробный пример проекта и внесли некоторые изменения в методе -didSelectRow::ios7 navigationController pushViewController анимированная ошибка

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    DetailViewController* view = [self.storyboard instantiateViewControllerWithIdentifier: @"view"]; 
    NSDate *object = _objects[indexPath.row]; 
    [view setDetailItem:object]; 
    [self.detailViewController.navigationController pushViewController:view animated:YES]; 
} 

Я также изменил раскадровки идентификатор подробный вид на «вид». Вот что происходит:

При выборе любого из рядов хозяйских медленно (когда толчок анимация закончена) он работает отлично: selecting rows slowly

При выборе любой из строк в то время как анимация все еще показывает, детальный вид становится неактивным (показывает последнюю строку, которая была вызвана с методом толкающего перед ошибкой), и только панель навигации показывает толкающую анимацию нового взгляда: selecting rows rapidly

Когда это произойдет, вы получите несколько предупреждений в выводе отладчика:

Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted. 

nested push animation can result in corrupted navigation bar 

Unbalanced calls to begin/end appearance transitions for <DetailViewController: 0x8a6e070>. 

Вот противная часть: если вы возвращаетесь на панели навигации подробного вида, а затем выберите другую строку в Tableview Учителей или вернуться дважды в деталях сбоев приложения с

Can't add self as subview 

НО если вы запустить тот же код на ios6, он работает без каких-либо проблем или предупреждений.

Существующие решения:

Вызов метода с анимационной: NO, кажется, работает без каких-либо проблем, очевидно, нет толчок анимации.

Другое решение состоит в том, чтобы иметь логическое значение в Master, чтобы установить значение false при вызове метода push и присвоении значения true из параметра Detail in DetailDidAppear. Таким образом, вы можете проверить значение при вызове метода push. Недостатки: tableView может выглядеть слишком долго, если вы попытаетесь быстро выбрать одну и ту же строку, если вы выберете другую строку быстро, тогда она не будет отображаться в деталях, но она будет выбрана в главном столе и подсвечена, вы можете сохранить выбранную строку индексировать и изменять выбор в коде, но это приводит к мерцанию выделения строк.

Оба решения предполагают некоторый компромисс, поэтому я хотел бы найти другой способ справиться с этим. Есть ли лучшие решения?

+0

Похоже, вы понимаете, что происходит, как и любой. Если у вас есть вопрос, пожалуйста, укажите его явно. Если вы просто предлагаете это как полезное наблюдение для других, вы должны переписать его в форме вопроса, добавить решения в ответ и принять ответ, чтобы было ясно, что вам не нужны люди, чтобы тратить на него время. Кроме того, если вы еще этого не сделали, вам следует сообщить об ошибке Apple (https://developer.apple.com/bug-reporting/). – Caleb

+0

Извините, что я намеревался опубликовать это, чтобы найти другие способы обойти это – Arnas

ответ

5

После некоторого тестирования выясняется, что в ios6, когда ячейка таблицы видна выбрана, и нажатие вызывает табличное представление, устанавливает .allowsSelection в NO до тех пор, пока не нажимается кнопка.

Это может быть легко воспроизведен в ios7 путем установки .allowsSelection к NO после метода толчка в didSelectRowAtIndexPath: и имеющей функцию обратного вызова в didAppear: методы просмотра деталей, где мы устанавливаем .allowsSelection к YES в точке зрения на мастер Tableview в.

Хотя это работает отлично, я нашел его немного раздражающим, когда быстро выбирал две разные ячейки один за другим, чтобы второй проигнорировал.

Итак, я установил, что если другая ячейка выбрана, пока анимация push не закончилась, я сохраняю ссылку на новое представление и нажимаю ее, как только закончится первая анимация. Делая это, tableView выглядит, по-моему, более отзывчивым.

1

Причина в том, что вы нажимаете контроллер просмотра, а другой не полностью нажат (журналы уже предупреждают вас об этом).

Ожидается, что анимация push займет около 0,4 секунды, поэтому пользователь должен быть достаточно быстрым, чтобы нажимать другую строку в течение 0,4 секунды, да, это применимо, но это не нормальное поведение.

, что вы можете сделать, это изменить время анимации, чтобы быть меньше, чем 0,4 сек (может быть 0,1 или 0,2), используя приведенную ниже код в вашем -didSelectRow: методе:

DetailViewController* view = [self.storyboard instantiateViewControllerWithIdentifier: @"view"]; 
NSDate *object = _objects[indexPath.row]; 
[view setDetailItem:object]; 

[UIView beginAnimations:@"ShowDetails" context: nil]; 
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut]; 
[UIView setAnimationDuration:0.2]; 
[self.detailViewController.navigationController pushViewController:view animated:NO]; 
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.navigationController.view cache:NO]; 
[UIView commitAnimations]; 

Надеется, что это помогает :)

+0

, анимация push со стороны сделала больше смысла в моем приложении, поэтому я выбрал ее вместо этого, но другие приложения могут предпочесть UIViewAnimations больше, потому что ее проще просто делайте это вместо обработки, когда анимация начинается и заканчивается. – Arnas

Смежные вопросы