Ok StackOverflow People ... У меня очень интересная проблема, которую я пытался решить в течение нескольких дней и не могу понять, поэтому мне нужно какая-то главная помощь. Это, скорее всего, будет очень длинным описанием, но, пожалуйста, несите меня и благодарите заблаговременно за то, что прочитали все это, потому что чем больше слов у меня есть, тем яснее я могу описать полную картину для всех вас. Я сделаю все возможное, чтобы быть как можно более кратким и последовательным. Пожалуйста, дайте мне знать, где бы я ни упал.UIRefreshControl Внутри UITableView, вызывающего приложение для замораживания при повороте - iOS 6+
Вот контекст моей проблемы: Я использую раскадровки для моего приложения IOS и для конкретной вкладки навигационной в моем приложении, мне пришлось создать две отдельные сцены и для портретного и альбомной ориентации. Причина для этого (вместо использования Autolayout) заключается в том, что на этой вкладке есть визуальные элементы (виды таблицы, веб-представления и т. Д.), Которые выложены по-разному в зависимости от ориентации, и это было намного проще создать отдельную сцену ориентации, чтобы справиться с этим изменением в пользовательском интерфейсе, а не делать это программно - (это также намного проще понять и более чисто по коду). Таким образом, убрать, чтобы иметь в виду все это, состоит в том, что эти две отдельные портретные и пейзажные сцены представляют собой ту же табуляцию в моем приложении. (Боковое примечание: эти сцены были сделаны в IB, конечно)
Теперь визуальные элементы, о которых я упоминал в пользовательском интерфейсе раньше - все глубже, все они контейнеры для разных UIViewControllers
. Я изолировал все в приложении и в значительной степени имел отношение 1 к 1 для всех вещей, поэтому эти контейнеры будут сопоставляться с моим подклассом UIViewControllers
, который я создал для их конкретных целей, - но это здесь, что первая оговорка моей проблемы возникает. Вот практический пример для более четкого изображения, у меня есть один UIViewController
, который содержит UITableView
под названием MXSAnnouncementsViewController
, и этот же контроллер представлений существует как в пейзажной, так и в портретной сценах. Я не создавал явную портретную или ландшафтную версию этого контроллера представления, но вместо этого попросите контроллер отслеживать два свойства IBOutlet
(tableViewLandscape
и tableViewPortrait
), которые указывают на ориентированный на ориентацию UITableViews
- и этот подход работает отлично. Более того, в моем MXSAnnouncementsViewController
у меня есть локальное свойство, называемое tableView
, которое абстрагирует ориентированные на ориентацию таблицы. Он получает набор в viewDidLoad
, которые вы можете увидеть ниже:
- (void)viewDidLoad
{
[super viewDidLoad];
if (self.tableViewPortrait) {
self.tableView = self.tableViewPortrait;
} else {
self.tableView = self.tableViewLandscape;
}
[self.tableView setDelegate:self];
[self.tableView setDataSource:self];
if (![MXSAnnouncementManager sharedAnnouncementManager].latestAnnouncements) {
[MXSAnnouncementManager loadModel:@"MXSAnnouncementGroupAllAnnouncements" withBlock:^(id model, NSError *error) {
if (!error) {
self.arrayLatestAnnouncements = [MXSAnnouncementManager sharedAnnouncementManager].latestAnnouncements;
[self.tableView reloadData];
} else {
// show some error msg
}
}];
} else {
self.arrayLatestAnnouncements = [MXSAnnouncementManager sharedAnnouncementManager].latestAnnouncements;
}
[self setupPullToRefresh];
}
Всякий раз, когда я нахожусь на вкладке, одна из двух ориентации специфичной IBOutlets
всегда активен и имеет адрес в памяти, а другой nil
. Всякий раз, когда я вращаюсь, роли обратные - то, что ранее имело адрес в памяти, теперь nil
, а другое было инициализировано и выделено, поэтому я делаю то, что я сделал с свойством tableView
в приведенном выше фрагменте. Вот здесь в картине появляется caveat # 2, и это doozy - это связано с жизненным циклом представления. Вот практический пример для ясности: Скажем, я загружаю приложение в альбомную ориентацию. Когда я это сделаю, у моей розетки tableViewLandscape
есть адрес в памяти, а мой вывод tableViewPortrait
- nil
. Это ожидаемое и желаемое поведение. Теперь, когда я поворачиваю приложение, начинается сумасшедший материал. Вот одно место, где мне нужна ясность от всех вас в отношении случаев UIViewControllers
, и что нормально, и что не так читать ОЧЕНЬ медленно и осторожно.
Вращение приложения сразу вызывает противоположную сцену ориентации (другая ИНСТАНЦИЯ MXSAnnouncementsViewController
???), чтобы вызвать ее метод viewDidLoad
(в этом примере мы находимся в Пейзаже, так что сценарий Portrait вызывает этот метод). В этом методе мое локальное свойство tableView
получает текущее активное представление таблицы для этой ориентации (см. Фрагмент выше).Когда этот метод заканчивается, предыдущий экземпляр LANDSCAPE MXSAnnouncementsViewController
вызывает его метод viewWillDisappear
, за которым следует вызов экземпляра PORTRAIT его метода viewWillAppear
, который затем заканчивается экземпляром LANDSCAPE, вызывающим его обратный вызов willRotateToInterfaceOrientation
, - это порядок работы, который I ' видя из точек останова. Я действительно надеюсь, что у тебя все получилось, потому что мой разум просто взорвался от всего этого.
Если вы все еще со мной на данный момент, спасибо, потому что мы наконец-то на родине. Как видно из названия этого сообщения, проблема, которую я пытаюсь решить, - это мое приложение, зависящее от вращения. Если вы не заметили на viewDidLoad
сниппета, последняя команда, чтобы получить казнены является setupPullToRefresh
метод, который заключается в следующем:
- (void)setupPullToRefresh
{
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:@selector(refreshTableView:) forControlEvents:UIControlEventValueChanged];
[self.tableView addSubview:refreshControl];
}
Так как я уже объяснил весь вид жизненного цикла порядок операций по ротации ранее, чтобы сделать очень длинная история, если я прокомментирую последнюю инструкцию setupPullToRefresh
в конце viewDidLoad
за MXSAnnouncementsViewController
, мое приложение отлично работает. Если я включу эту инструкцию, мое приложение перестанет отвечать на первое вращение, и я не могу понять, почему. Не уверен, что я имею дело с краевым случаем здесь или еще чем-то. Любые и всякие идеи приветствуются, и БЛАГОДАРИМ ВАС СКОЛЬКО для чтения всего этого!
Что приложение делает, пока он висит, основной поток? –
Я еще не профессионал в области разработки и отладки iOS, но я просто попытался использовать инструменты, и это не похоже на то, что основной поток ничего не делает. Я вижу что-то, что говорит <Достигнутый предел стека вызовов>, но я не уверен, что это значит. Я мог определенно копать глубже в небольшом направлении, но я так же полезен, как камень на земле один. – Danchez
Иногда возникают подсказки, когда вы приостанавливаете приложение с помощью || и посмотрите на стек основного потока. Разумеется, разуплотнение - снова несколько раз может дать разные результаты стека. –