Reputation: 17
I have a CClayer
class, called GridLayer I add the gesture recognizers (Pan ,Pinch and Rotate) to the view and it works fine, but if i add a CCMenuItem
is paste to the view so is affected by the rotate and pinch gestures , my question is who implement a independent CCMenuitem
from the View Size ,Scale and position.
//Adding Rotation Recognicer onEnter Method
self.rotationRecognicer =[[[UIRotationGestureRecognizer alloc]initWithTarget:self
action:@selector(rotate:)]autorelease];
[[[CCDirector sharedDirector] view] addGestureRecognizer:_rotationRecognicer];
//Adding CCMenuItem On Init Method
CCMenuItem *starMenuItem = [CCMenuItemImage
itemWithNormalImage:@"ButtonStar.png"
selectedImage:@"ButtonStarSel.png"
target:self
selector:@selector(starButtonTapped:)];
starMenuItem.position = ccp(60, 60);
CCMenu *starMenu = [CCMenu menuWithItems:starMenuItem, nil];
starMenu.position = CGPointZero;
[self addChild:starMenu];
//Rotation Method
- (void)rotate:(UIRotationGestureRecognizer *)gestureRecognizer
{
[self adjustAnchorPointForGestureRecognizer:gestureRecognizer];
if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged) {
[gestureRecognizer view].transform = CGAffineTransformRotate([[gestureRecognizer view] transform], [gestureRecognizer rotation]);
[gestureRecognizer setRotation:0];
}
}
Upvotes: 1
Views: 214
Reputation: 17
This approximation is based on the following example
http://www.raywenderlich.com/4817/how-to-integrate-cocos2d-and-uikit
Creating a UIViewController called RootViewControler that contain all the controls needed and adding like subview the [[CCDirector sharedDirector] view] with the gridLayer
//RootViewcontroler viewDidLoad Method:
[self.view insertSubview:[[CCDirector sharedDirector] view] atIndex:0];
CCScene *scene = [GridLayer scene];
[[CCDirector sharedDirector ]runWithScene: scene];
In the Appdelegate add the RootViewControler instance to the Navigation Controler
RootViewControler *rootViewcontroler =[[[RootViewControler alloc] initWithNibName:nil bundle:nil] autorelease];
// Create a Navigation Controller
navController_ = [[UINavigationController alloc] initWithRootViewController:rootViewcontroler];
Sure is not the unique posible solution, but for me works.
Upvotes: 0
Reputation: 2670
Your GUI controls need to exist on their own independent layer.
To accomplish this, you should add two separate layers to your CCScene container, or whatever is the parent node of your layer. This may look something like the following
@implementation SceneNode
@synthesize actionLayer;
-(id)init {
self = [super init];
if (self != nil) {
UILayer * uiLayer = [UILayer node];
self.actionLayer = [[ActionLayer alloc] initWithSceneUILayer:uiLayer];
[self addChild:uiLayer z:UI_LAYER_Z_VALUE];
[self addChild:actionLayer z:ACTION_LAYER_Z_VALUE];
} // end if
return self;
} // end init
@end
The tricky part is getting them to communicate without creating a tight coupling between the classes. It is likely you will want the action layer (your grid layer) to be informed when a control is interacted with on your GUI layer. This is where you will want to implement either the Command Design Pattern and or use Objective-C protocols with a delegate.
If you decide to use a protocol and delegate, it may look like the following
// In a header file
@protocol ControlsProtocols
-(void)fireButtonEvent;
-(void)angleSelectionEvent;
-(void)powerSelectionEvent:(int)powerRec;
@end
Create a delegate member data variable in the UILayer class
@interface ILayer : CCLayer {
CCMenu * ControlsMenu;
id <ControlsProtocols> delegate;
} // end ivar
@property (nonatomic, strong) id <ControlsProtocols> delegate;
@end
In your action layer (Grid Layer), which initializes with a pointer to the UILayer, assign itself as the delegate for the UILayer.
-(id)initWithSceneUILayer:(UILayer *)uiLayer {
self = [super init];
if (self != nil) {
// Store reference to UILayer and set UILayer delegate to self
UILayer = uiLayer;
uiLayer.delegate = self;
// More logic here
} // end if
return self;
} // end init
Lastly, be sure to implement the protocol methods in the Action Layer (grid layer) class and move the gesture recognition to this layer. My guess is that you only want the action layer to be manipulated when certain gestures occur, not the view which houses your scene and layers. Add logic to capture the gestures in your Action Layer and only manipulate this layer's appearance instead of the entire view.
Upvotes: 0