我通过Sprite Kit进入iOS,我认为这是不明智的。
我的目标是在游戏结束时显示“分享”按钮。点击共享按钮应该呈现SLComposeViewController(Twitter Share)。场景的内容不应该改变。
决定“游戏结束”的游戏逻辑存在于SpriteMyScene.m中,这是SKScene的子类。
我可以通过这种方式在游戏中显示分享按钮:
-(void)update:(CFTimeInterval)currentTime {
if (gameOver){
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self
action:@selector(sendToController)
forControlEvents:UIControlEventTouchDown];
[button setTitle:@"Show View" forState:UIControlStateNormal];
button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
[self.view addSubview:button];
}
}
- (void)sendToController
{
NSLog(@"ok");
SpriteViewController *viewController = [SpriteViewController alloc];
[viewController openTweetSheet];
}
我遇到的问题是试图让showTweetButton方法起作用。我的SpriteViewController.m看起来像这样:
- (void)openTweetSheet
{
SLComposeViewController *tweetSheet = [SLComposeViewController
composeViewControllerForServiceType:
SLServiceTypeTwitter];
// Sets the completion handler. Note that we don't know which thread the
// block will be called on, so we need to ensure that any required UI
// updates occur on the main queue
tweetSheet.completionHandler = ^(SLComposeViewControllerResult result) {
switch(result) {
// This means the user cancelled without sending the Tweet
case SLComposeViewControllerResultCancelled:
break;
// This means the user hit 'Send'
case SLComposeViewControllerResultDone:
break;
}
};
// Set the initial body of the Tweet
[tweetSheet setInitialText:@"just setting up my twttr"];
// Adds an image to the Tweet. For demo purposes, assume we have an
// image named 'larry.png' that we wish to attach
if (![tweetSheet addImage:[UIImage imageNamed:@"larry.png"]]) {
NSLog(@"Unable to add the image!");
}
// Add an URL to the Tweet. You can add multiple URLs.
if (![tweetSheet addURL:[NSURL URLWithString:@"http://twitter.com/"]]){
NSLog(@"Unable to add the URL!");
}
// Presents the Tweet Sheet to the user
[self presentViewController:tweetSheet animated:NO completion:^{
NSLog(@"Tweet sheet has been presented.");
}];
}
我总是在日志中得到这样的东西:
- [UIView presentScene:]:无法识别的选择器发送到实例0x13e63d00 2013-10-17 18:40:01.611修复[33409:a0b] * 终止应用 由于未捕获的异常'NSInvalidArgumentException',原因: ' - [UIView presentScene:]:无法识别的选择器发送到实例 0x13e63d00'
答案 0 :(得分:11)
您正在创建一个新的视图控制器,但从未提供它:
SpriteViewController *viewController = [SpriteViewController alloc];
我假设SpriteViewController
是您SpriteMyScene
的内容,并且您希望将控制权交还给呈现SpriteViewController
。
您需要在SpriteViewController
子类中保留对SpriteMyScene
的引用,然后在致电openTweetSheet
时访问该引用。
在SpriteMyScene.h中
@class SpriteViewController;
@interface SpriteMyScene : SKScene
@property (nonatomic, weak) SpriteViewController *spriteViewController;
@end
SpriteViewController.m中的
// somewhere you initialize your SpriteMyScene object, I'm going to call it myScene
myScene.spriteViewController = self;
SpriteMyScene.m中的
#import "SpriteViewController.h"
- (void)sendToController
{
NSLog(@"ok");
// use the already-created spriteViewController
[_spriteViewController openTweetSheet];
}
答案 1 :(得分:4)
您可以使用
UIViewController *vc = self.view.window.rootViewController;
此代码将为您提供对根视图控制器的访问权限,以便您可以执行任何操作,您的视图控制器就像正常一样。
但是,你需要添加一个按钮吗?在这种情况下,使用精灵并向其添加事件会更好。请致电:
UIViewController *vc = self.view.window.rootViewController;
[vc openTweetSheet];
并且
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
NSArray *nodes = [self nodesAtPoint:[touch locationInNode:self]];
for (SKNode *node in nodes) {
if ([node.name isEqualToString:@"OpenTweet"]) {
UIViewController *vc = self.view.window.rootViewController;
[vc openTweetSheet];
}
}
}
答案 2 :(得分:3)
如果要从场景中打开另一个UIViewController,则必须首先在最初创建此场景的主View Controller中创建一个委托,以便场景可以通知其ViewController一个打开的推文动作。您将需要以下步骤:
以下是示例:
@protocol ViewControllerDelegate <NSObject>
-(void) openTweetSheet;
@end
扩展此ViewController以在其.h文件中支持此协议
@interface ViewController : UIViewController<ViewControllerDelegate>
@end
然后在.m文件中实现协议中的方法
-(void) openTweetSheet{
TweetSheetViewController *ctrl = [[TweetSheetViewController alloc] initWithNibName:@"TweetSheetViewController" bundle:nil];
[self presentViewController:ctrl animated:YES completion:nil];
}
在Scene头类中,添加委托属性
@interface MyScene : SKScene {
}
@property (nonatomic, weak) id <ViewControllerDelegate> delegate;
@end
在ViewController中,在呈现场景之前,在viewDidLoad方法中设置其委托:
// Create and configure the scene.
MyScene * scene = [MyScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
[scene setDelegate:self];
// Present the scene.
[skView presentScene:scene];
现在您的Scene可以将消息传递回ViewController,ViewController可以打开另一个ViewController。在场景类中,确定将触发打开TweetSheetViewController
的操作-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
/* Called when a touch begins */
for (UITouch *touch in touches) {
CGPoint location = [touch locationInNode:self];
SKAction *fadeOut = [SKAction fadeOutWithDuration:0.5];
SKAction *fadeIn = [SKAction fadeInWithDuration:1.0];
SKAction *sequence = [SKAction sequence:@[fadeOut,fadeIn]];
SKNode *node = [self nodeAtPoint:location];
if ([[node name] isEqual: @"openTweet"]) {
NSLog(@"help");
[node runAction:sequence];
[delegate openTweetSheet];
}
}
希望有所帮助。
答案 3 :(得分:1)
将SlComposeViewController方法写入您希望它发生的场景中。例如:
@interface GameOverScene: SKScene
...initwithsize bla bla bla
...
添加以下方法:
-(void)OpenTweetShet{
if ([SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter]) {
_composeTwitter = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
[_composeTwitter setInitialText:@"TWEET"];
然后致电:
self.view.window.rootViewController **to present the SLComposeViewController**
[self.view.window.rootViewController presentViewController:_composeTwitter animated:YES completion:nil];
}
[_composeTwitter setCompletionHandler:^(SLComposeViewControllerResult result){
NSString *output =[[NSString alloc]init];
switch (result) {
case SLComposeViewControllerResultCancelled:
output = @"Post cancelled";
break;
case SLComposeViewControllerResultDone:
output = @"Post Succesfull";
break;
default:
break;
}
以下是发送/取消后发布UIAlert的选项:
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Twitter" message:output delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles: nil];
[alert show];
}];
}
@end
答案 4 :(得分:0)
这对我有用:self.view.window.rootViewController
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
NSArray *nodes = [self nodesAtPoint:[touch locationInNode:self]];
for (SKNode *node in nodes) {
if ([node.name isEqualToString:@"OpenTweet"]) {
UIViewController *vc = self.view.window.rootViewController;
[self.view.window.rootViewController openTweetSheet];
}
}
}