Чье представление не входит в проблему иерархии окон?

Предупреждение: Попытайтесь представить, чей вид не входит в иерархию окон!

Да, я просмотрел другие вопросы и ответы перед тем, как опубликовать этот вопрос. Они не помогли мне решить эту проблему. Вот что я делаю. Я вызываю свой одноэлементный класс socialHelper, чтобы отобразить лист действий, где метод postToFacebook - это вариант для выбора. При нажатии на это действие я получаю предупреждение выше, а postToFacebook не отображается. Я вызываю это из UIViewController с UINavigationController в качестве основного контроллера, а мой класс SocialHelper - NSOject.

- (void)postToFacebook
{
    if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook]) {

    slComposeViewController = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
    [slComposeViewController setInitialText:@"Building stairs? Checkout StairsPro on the app store!"];
    [slComposeViewController addImage:[UIImage imageNamed:@"StairsIcon120x120.png"]];
    [slComposeViewController addURL:[NSURL URLWithString:@"https://itunes.apple.com/us/app/stairs-pro/id477032819?ls=1&mt=8"]];

    [self presentViewController:slComposeViewController animated:YES completion:nil];

    // I've also tried this, which shows the post window, but after hitting cancel or post, my previous viewController is not the current viewController. So my navigation bar is gone and can't move around in my app. 
    // [[[[UIApplication sharedApplication]delegate]window]setRootViewController:slComposeViewController];

    }else{
        UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"No Facebook Account" message:@"No Facebook account has been configured. You can configure or create a Facebook account in settings." delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles:nil];
        [alert show];
}
}

Я спрашиваю, как лучше всего отобразить slComposerViewController в этом случае, а также как мы могли бы использовать параметр UIApplication. Спасибо!


person Jason    schedule 31.05.2014    source источник
comment
SocialHelper действительно на экране?   -  person Paul.s    schedule 31.05.2014
comment
Когда он вызывается до окна PostToFacebook, на экране ничего не отображается. Просто с экрана, с которого я звонил. Но UActionSheet работает, затем я нажимаю «Опубликовать в Facebook», получаю предупреждение, и UIActionSheet исчезает, и просто возвращается к экрану, с которого я его вызвал.   -  person Jason    schedule 31.05.2014
comment
presentViewController:animated:completion: необходимо вызывать из viewController, который в данный момент отображается на экране. Если SocialHelper не является представленным в настоящее время viewController, вам не следует вызывать для него этот метод.   -  person Paul.s    schedule 31.05.2014
comment
Я попытался переместить все в отображаемый класс UIViewController и получил такое же предупреждение.   -  person Jason    schedule 31.05.2014
comment
Вы уверены, что у вас правильный viewController?   -  person Paul.s    schedule 31.05.2014
comment
Нет, не совсем, я уверен, что делаю что-то не так ... просто не знаю что. Прекрасно работает на Cocos2d с CCDirector. Сообщение в facebook вызывается из моего aboutView viewController с [[SocialHelper sharedInstance]shareActionSheet];, который работает и показывает лист действий ... но как только нажимаю postToFacebook, я получаю предупреждение. Любые идеи? Я использую раскадровки для aboutView, если это важно.   -  person Jason    schedule 01.06.2014
comment
пожалуйста, поделитесь своим проектом; возможно, иерархия представлений может быть беспорядочной, но, не видя, как построена иерархия представлений, очень сложно даже догадаться, где может быть проблема ...   -  person holex    schedule 05.06.2014
comment
UINavigationController - это представление представления. Я запустил NSLog, чтобы узнать, каким был текущий viewController.   -  person Jason    schedule 06.06.2014
comment
Вам нужно решить проблему. Однажды у меня была такая проблема, мне потребовался целый день, чтобы понять, что мне не хватает «супер» звонка. Попробуйте представить простой контроллер представления [self presentViewController: [UIViewController новый] анимированный: ДА, завершение: ноль];   -  person Saqib Saud    schedule 10.06.2014
comment
Если вы вызываете свой одноэлементный класс socialHelper для отображения листа действий, а ваш класс SocialHelper является NSOject, тогда вы не хотите (или не можете) использовать self для отображения листа действий, потому что self - это объект, которого нет в просматривать иерархию. Вам нужно использовать контроллер представления для отображения листа действий.   -  person Only You    schedule 10.06.2014
comment
Вот что у меня есть ... MainViewController с UINavigationController, его FlipsideViewController для настроек, затем кнопка для страницы, которая также является UIViewController. Я добавил журнал о том, откуда вызывается UIActionSheet (показывает, что UINavigation является текущим ViewController). Метод для UIActionSheet находится в классе socialhelper, который называется NSObject. Я пробовал переместить все в класс About UIViewController ... который дал тот же результат. Надеюсь это поможет   -  person Jason    schedule 11.06.2014


Ответы (2)


Я бы изменил метод передачи в ViewController, чтобы убедиться, что правильный VC представляет его следующим образом:

- (void)postToFacebookFromVC:(UIViewController*) presentingVC

И внутри этого метода при вызове presentViewController используйте:

[presentingVC presentViewController:slComposeViewController animated:YES completion:nil];

Тогда я предполагаю, что использование вашего singleton-класса socialHelper будет примерно таким:

[[socialHelper sharedResource] postToFacebookFromVC:self]; //inside the VC that you want to display it

Для вашего второго вопроса об использовании rootViewController попробуйте следующее:

[[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:slComposeViewController animated:YES completion:nil];

Изменить: поскольку первые два предложения не сработали для вашего проекта, попробуйте получить topMost ViewController и представить из него slComposeViewController вместо «self», например:

UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;

while (topController.presentedViewController) {
    topController = topController.presentedViewController;
}

[topController presentViewController:slComposeViewController animated:YES completion:nil];
person rymagno    schedule 05.06.2014
comment
UINavigationController - это представление представления. Я запустил NSLog, чтобы узнать, каким был текущий viewController. Пробовал оба варианта в текущем ответе, ни один из них не работал. - person Jason; 06.06.2014
comment
Вот что у меня есть ... MainViewController с UINavigationController, его FlipsideViewController для настроек, затем кнопка для страницы, которая также является UIViewController. Я добавил журнал о том, откуда вызывается UIActionSheet (показывает, что UINavigation является текущим ViewController). Метод для UIActionSheet находится в классе socialhelper, который называется NSObject. Я пробовал переместить все в класс About UIViewController ... который дал тот же результат. Надеюсь это поможет - person Jason; 11.06.2014
comment
попробовал ваш topViewController, ничего не сделал. Никаких ошибок или сбоев, просто ничего. - person Jason; 13.06.2014

Этот ответ не решит вашу проблему, но он должен объяснить, почему он не работает, и помочь вам найти правильное решение для того, что вы изначально планировали.

SLComposeViewController, являющийся UIViewController, имеет связанный UIView, который будет отображаться поверх представления контроллера, получающего сообщение presentViewController.

Как правильно сделано в этой строке, но self должен быть UIViewController (объект, имеющий свойство представления).

[self presentViewController:slComposeViewController animated:YES completion:nil];

Это сработает, если вы переместите свой -postToFaceBook метод из класса SocialHelper и поместите его в свой UIViewController класс (файл), который будет отображать лист действий, так что self фактически будет UIViewController вместо NSObject.

Из Apple справочная страница UIViewController:

Когда вы вызываете метод presentViewController в UIViewController, он устанавливает свойство PresentViewController на указанный контроллер представления, изменяет размер представления этого контроллера представления, а затем добавляет представление в иерархию представлений.

Ваш SocialHelper класс не является контроллером представления, поэтому у него нет представления, в которое можно было бы добавить представление листа действий для его отображения (вверху).

Я думаю, даже если вы унаследуете свой SocialHelper от UIViewController, представление вашего SocialHelper не будет в иерархии представлений вашего контроллера.

Если вам нужно отобразить лист действий только на двух или трех контроллерах представления, я бы реплицировал код вместо создания отдельного класса; если это несколько контроллеров представления, тогда имеет смысл иметь логику отображения листа действий как отдельный класс, вам просто нужно найти правильный шаблон проектирования для этого.

Изменить 1

Забыл упомянуть, что в объявлении вашей переменной отсутствует SLComposeViewController *

Это просто отсутствует в вашем сообщении или вы объявили переменную где-то еще в своем классе viewcontroller?

Попробуйте объявить его прямо здесь, в той же строке, в которой вы создаете SLComposeViewController; это может решить проблему. Если это не помогло, дважды проверьте все, что вам нужно сделать для поддержки Facebook в своем приложении, посмотрев на этот самый простое и удобное руководство.

SLComposeViewController *slComposeViewController = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];

Я предполагаю, что вы создали свой контроллер навигации с основным контроллером представления в качестве корня:

navigationController = [[UINavigationController alloc] initWithRootViewController:mainViewController];

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

[[self navigationController] pushViewController:flipSideViewController animated:NO];

На оборотной стороне контроллера есть кнопка about, при нажатии на которую отображается обзор; Я думаю, вы делаете PresentViewController, а не толкаете:

[self presentViewController:aboutViewController animated:YES];

Наконец, в контроллере вида about у вас должен быть метод -postToFacebook с исправленной строкой, упомянутой выше; который будет вызываться журналом (кнопка?).

person Only You    schedule 10.06.2014
comment
Вот что у меня есть ... MainViewController с UINavigationController, его FlipsideViewController для настроек, затем кнопка для страницы, которая также является UIViewController. Я добавил журнал о том, откуда вызывается UIActionSheet (показывает, что UINavigation является текущим ViewController). Метод для UIActionSheet находится в классе socialhelper, который называется NSObject. Я пробовал переместить все в класс About UIViewController ... который дал тот же результат. Надеюсь это поможет - person Jason; 11.06.2014