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

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

Да, я рассмотрел другие вопросы и ответы, прежде чем публиковать этот вопрос. Они не помогли мне решить эту проблему. Вот что я делаю. Я призываю мой singleton class 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. Спасибо!

Ответ 1

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

- (void)postToFacebookFromVC:(UIViewController*) presentingVC

И внутри этого метода при вызове метода currentViewController:

[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];

Ответ 2

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

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

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

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

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

От Apple Страница справки UIViewController:

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

Ваш класс 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];

Контроллер оборотной стороны имеет кнопку "О кнопке", чтобы отображать оферту при нажатии; Я думаю, что вы не выполняете функцию currentViewController:

[self presentViewController:aboutViewController animated:YES];

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