如何使用社交框架呈现来自 SKscene 的 UIViewController?

Posted

技术标签:

【中文标题】如何使用社交框架呈现来自 SKscene 的 UIViewController?【英文标题】:How do I present UIViewController from SKscene with social framework? 【发布时间】:2014-03-15 08:03:41 【问题描述】:

我正在制作像 Flappy Bird 这样的游戏。如何呈现来自 SKScene 的 UIViewController? 首先,我告诉我的环境

Mac OS X 10.9 Xcode 5.0.2 Sprite Kit(framework)、social.framework(framework) 已添加到我的项目中

我的目标是在游戏结束时显示“分享”按钮。点击分享按钮图像应该会显示一个 SLComposeViewController (Twitter Share)。场景内容不应改变。 我想解决以下问题并将显示从 GameOverScene 更改为 tweetSheet(display) 由 social.framework 组成。

问题

[self presentViewController:tweetSheet animated:YES completion:nil];
//Error:No visible @interface for 'GameOverScene' declares the selector "presentViewController":animated:completion:

我的编码文件如下(我提取了部分重要代码)。

ViewController.h

import <UIKit/UIKit.h>
import <SpriteKit/SpriteKit.h>
import <iAd/iAd.h>

@interface ViewController : UIViewController<ADBannerViewDelegate><br>

@end

GameOverScene.h

#import <SpriteKit/SpriteKit.h> 

@class SpriteViewController;

@interface GameOverScene : SKScene 

@end

GameOverScene.m

#import "GameOverScene.h"
#import "NewGameScene.h"
#import "MainScene.h"
#import <Social/Social.h>
@implementation GameOverScene 
   //The twitter button 
    SKSpriteNode *_twitterbutton;

- (id)initWithSize:(CGSize)size

    if (self = [super initWithSize:size]) 
        //Creating the twitterbutton with the twitterbutton image from Images.xcassets
        _twitterbutton = [SKSpriteNode spriteNodeWithImageNamed:@"twitterbutton"];
        [_twitterbutton setSize:CGSizeMake(50, 50)];
        [_twitterbutton setPosition:CGPointMake(self.size.width/2, self.size.height/5 + 50)];
        //Adding the twitter button
        [self addChild:_twitterbutton];
        //Again, this is important, otherwise we can't identify what button is pressed
        _twitterbutton.name = @"twitterbutton";
        [_twitterbutton setPosition:CGPointMake(self.size.width/2, self.size.height/5 + 50)]
    
    return self;



- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

    //Same as in NewGameScene menu
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInNode:self];
    SKNode *node = [self nodeAtPoint:location];
    //Is the twitter button touched?
    if([node.name isEqualToString:@"twitterbutton"])
        if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter])
            SLComposeViewController *tweetSheet = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
            [tweetSheet setInitialText:@"TestTweet from the Game !!"];
            [self presentViewController:tweetSheet animated:YES completion:nil];
     **//Error:No visible @interface for 'GameOverScene' declares the selector "presentViewController":animated:completion:**
          
    

ViewControlloer.m

#import "ViewController.h"
#import "NewGameScene.h"
@implementation ViewController
//Loads the view onto our main class
- (void)loadView

  self.view  = [[SKView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];

//Executes when view finishes loading
- (void)viewWillLayoutSubviews

  [super viewDidLoad];

  //Set the resize mode to flexible width and height
  [self.view setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];

  //Create our view from our original view
  //Make sure to leave originalContentView in, otherwise the app will crash
  SKView *skView = (SKView *)self.originalContentView;

  //We create a new NewGameScene according to the current dimensions
  SKScene *scene = [NewGameScene sceneWithSize:skView.bounds.size];

  //Create a transition class with animation type fade and a duration of .4 seconds
  SKTransition *transition = [SKTransition fadeWithDuration:.4];

  //Present the menu view (NewGameScene) with our fade in transition
  [skView presentScene:scene transition:transition];


@end

【问题讨论】:

这里粘贴了很多代码,我怀疑有人会阅读所有这些。阅读本指南,了解如何最好地呈现您的问题:***.com/help/mcve 该过程也有助于您更好地理解它。 复制 [***.com/questions/19438719/… [1]: ***.com/questions/19438719/… >>Henrik 谢谢你的建议!这是我第一次提交我的问题。如果你感到生气,我很抱歉。先生,我将使用您的有益建议,非常感谢您。 >>Theis 谢谢你的建议。不过,我是 Xcode 的初学者。我知道这篇文章并阅读了越来越多的内容,但是我无法理解……所以,我提交了这个问题。我该怎么办你认为如何阅读这篇文章??? ***.com/questions/19438719/… @tomojiro 别担心,别生气,只是想帮助第一次发帖的人改进问题以获得更多答案。 :) 【参考方案1】:

您不能在 SKScene 中呈现 viewController,因为它实际上只在 SKView 上呈现。您需要一种向 viewController 发送消息的方法,然后 viewController 将呈现 viewController。为此,您可以使用委托

将以下协议定义添加到您的 SKScene 的 .h 文件中:

@protocol sceneDelegate <NSObject>
-(void)showShareScreen;
@end

并在接口中声明一个委托属性:

@property (weak, nonatomic) id <sceneDelegate> delegate;

然后,在您要显示共享屏幕的位置,而不是行:

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

使用这一行:

[self.delegate showShareScreen];

现在,在 viewController 的 .h 文件中,实现协议:

@interface ViewController : UIViewController <sceneDelegate>

并且,在您的 .m 文件中,在呈现场景之前添加以下行:

scene.delegate = self;

然后在此处添加以下方法:

-(void)presentShareScreen


    if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter])
    
        SLComposeViewController *tweetSheet = [SLComposeViewController
        composeViewControllerForServiceType:SLServiceTypeTwitter];
        [tweetSheet setInitialText:@"TestTweet from the Game !!"];
        [self presentViewController:tweetSheet animated:YES completion:nil];

    

另一种方法是使用 NSNotificationCenter

保留-presentShareScreen 方法,如上一个替代方案中所述。

-viewDidLoad 方法中将 viewController 作为监听器添加到通知中:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(presentShareScreen) name:@"showShareScreen" object:nil];

然后,在场景中要显示此 viewController 的位置,使用以下行:

[[NSNotificationCenter defaultCenter] postNotificationName:@"showShareScreen" object:nil];

【讨论】:

很高兴看到您的回答,谢谢。但是,我不知道如何使用下面这一行 scene.delegate = self;我应该在哪里使用 .m 文件?当我在 ViewController.m 文件中使用它时,它不起作用。也就是说,在“SKScene”类型的对象上找不到属性“委托” 您需要在GameOverScene的接口定义前添加协议 我现在很困惑...我应该搜索 SKScene 并将协议添加到 SKScene 的文件中。我将协议添加到 SKScene 的子类中,例如“@interface MainScene : SKScene ”我现在很困惑,但我会尽力而为:) 嗯...我替换了 [self.delegate showShareScreen];到我的 GameOverScene.m 的 twitter 方法。但是,我的 ViewController.m 没有委托方法(showShareScreen)。它有效,但它没有委托,因为当我在 showShareScreen 方法中使用断点时,它并没有停止......请问原因?顺便说一句,使用 scene.delegate = self;我从 GameOverScene 的实例中创建了实例。它可能对我有用。 @tomojiro 我已经为这个问题添加了一个更简单的替代方法。

以上是关于如何使用社交框架呈现来自 SKscene 的 UIViewController?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SKScene 中呈现 UIViewController?

斯威夫特:公共 Skscene 没有以文件名呈现?

从 UIViewController 呈现 SKScene - Swift

呈现 SKScene 后取消隐藏 UIButtons 时延迟?

从 SKScene 呈现后无法关闭视图控制器

如何在 Swift Playgrounds 中使用带有纹理的 SKNode 设置 SKScene?