How to start a Cocos2D Scene when pushing a UIViewController - ios

I'm working on a project for iOS 5 and 6, iPad 3.
My problem is that I need to draw something with Cocos2D in a scene, but it doesn't work.
I'm starting to code in AppDelegate - setting a rootViewController (MainViewController)
In this MainViewController, I have a button, that fires a method called -draw:
The -draw: method is very simple.
DrawController * c = [DrawController alloc]init];
[self.navigationController pushViewController:c animated:YES];
Now when the App pushes the DrawController,
my App should make a Scene with Cocos2D using CCDirector.
but its very frustrating, because I have always a black gap on the screen.
DrawController
- (void)viewDidLoad
{
[super viewDidLoad];
glView = [CCGLView viewWithFrame:[self.view bounds]
pixelFormat:kEAGLColorFormatRGB565 //kEAGLColorFormatRGBA8
depthFormat:0 //GL_DEPTH_COMPONENT24_OES
preserveBackbuffer:NO
sharegroup:nil
multiSampling:NO
numberOfSamples:0];
director_ = (CCDirectorIOS*) [CCDirector sharedDirector];
director_.wantsFullScreenLayout = YES;
// Display FSP and SPF
[director_ setDisplayStats:YES];
// set FPS at 60
[director_ setAnimationInterval:1.0/60];
// attach the openglView to the director
[director_ setView:glView];
// for rotation and other messages
[director_ setDelegate:(id <CCDirectorDelegate>) [[UIApplication sharedApplication] delegate]];
UIButton * redColor = [UIButton buttonWithType:UIButtonTypeRoundedRect];
redColor.tag = 1;
redColor.frame = CGRectMake(658, 80, 100, 30);
[redColor setTitle:#"ROT" forState:UIControlStateNormal];
[redColor addTarget:self action:#selector(changeColor:) forControlEvents:UIControlEventTouchUpInside];
[glView addSubview:redColor];
UIButton * blueColor = [UIButton buttonWithType:UIButtonTypeRoundedRect];
blueColor.tag = 2;
blueColor.frame = CGRectMake(658, 80+30+30, 100, 30);
[blueColor setTitle:#"BLAU" forState:UIControlStateNormal];
[blueColor addTarget:self action:#selector(changeColor:) forControlEvents:UIControlEventTouchUpInside];
[glView addSubview:blueColor];
UIButton * undo = [UIButton buttonWithType:UIButtonTypeRoundedRect];
undo.tag = 1;
undo.frame = CGRectMake(658, 80 +30+30 +30+30, 100, 30);
[undo setTitle:#"UNDO" forState:UIControlStateNormal];
[undo addTarget:self action:#selector(changeHistory:) forControlEvents:UIControlEventTouchUpInside];
[glView addSubview:undo];
UIButton * foto = [UIButton buttonWithType:UIButtonTypeRoundedRect];
foto.tag = 1;
foto.frame = CGRectMake(658, 80 +30+30 +30+30 +30+30, 100, 30);
[foto setTitle:#"FOTO" forState:UIControlStateNormal];
[foto addTarget:self action:#selector(takeScreenshot:) forControlEvents:UIControlEventTouchUpInside];
[glView addSubview:foto];
UIStepper * overdrawStepper = [[UIStepper alloc] initWithFrame:CGRectMake(658, 80 +30+30 +30+30 +30+30 +30+30, 100, 30)];
overdrawStepper.value = 1;
overdrawStepper.minimumValue = 1;
overdrawStepper.maximumValue = 18;
overdrawStepper.stepValue = 1;
[overdrawStepper addTarget:self action:#selector(overdraw:) forControlEvents:UIControlEventValueChanged];
[glView addSubview:overdrawStepper];
UIStepper * thicknessStepper = [[UIStepper alloc] initWithFrame:CGRectMake(658, 80 +30+30 +30+30 +30+30 +30+30 +30+30, 100, 30)];
thicknessStepper.value = 3;
thicknessStepper.minimumValue = 1;
thicknessStepper.maximumValue = 30;
thicknessStepper.stepValue = 1;
[thicknessStepper addTarget:self action:#selector(thickness:) forControlEvents:UIControlEventValueChanged];
[glView addSubview:thicknessStepper];
UIStepper * alphaStepper = [[UIStepper alloc] initWithFrame:CGRectMake(658, 80 +30+30 +30+30 +30+30 +30+30 +30+30 +30+30, 100, 30)];
alphaStepper.value = 1;
alphaStepper.minimumValue = 0.1;
alphaStepper.maximumValue = 1;
alphaStepper.stepValue = 0.1;
[alphaStepper addTarget:self action:#selector(alpha:) forControlEvents:UIControlEventValueChanged];
[glView addSubview:alphaStepper];
UIButton * eraser = [UIButton buttonWithType:UIButtonTypeRoundedRect];
eraser.tag = 1;
eraser.frame = CGRectMake(658, 80 +30+30 +30+30 +30+30 +30+30 +30+30 +30+30 +30+30, 100, 30);
[eraser setTitle:#"Eraser" forState:UIControlStateNormal];
[eraser addTarget:self action:#selector(erase:) forControlEvents:UIControlEventTouchUpInside];
[glView addSubview:eraser];
// 2D projection
[director_ setProjection:kCCDirectorProjection2D];
// [director setProjection:kCCDirectorProjection3D];
// Enables High Res mode (Retina Display) on iPhone 4 and maintains low res on all other devices
if( ! [director_ enableRetinaDisplay:YES] )
CCLOG(#"Retina Display Not supported");
// set the Navigation Controller as the root view controller
// there is a iOS 6 Bug, so we need have this workaround
[self addChildViewController:director_];
// Add the director's OpenGL view as a subview so we can see it.
[self.view addSubview:director_.view];
// Finish up our view controller containment responsibilities.
[director_ didMoveToParentViewController:self];
// director_.view.frame = CGRectMake(0, 0, 1024, 1024);
// Default texture format for PNG/BMP/TIFF/JPEG/GIF images
// It can be RGBA8888, RGBA4444, RGB5_A1, RGB565
// You can change anytime.
[CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888];
// Assume that PVR images have premultiplied alpha
[CCTexture2D PVRImagesHavePremultipliedAlpha:YES];
// and add the scene to the stack. The director will run it when it automatically when the view is displayed.
self.view.backgroundColor = [UIColor orangeColor];
if ([self loadImage]) {
lineDrawer = [[LineDrawer alloc] initWithImage:[self loadImage]];
} else {
lineDrawer = [LineDrawer node];
}
CCScene *scene = [CCScene node];
//[scene setContentSize:glView.frame.size];
[scene addChild:lineDrawer];
[director_ pushScene: scene];
NSLog(#"self.view.frame %#", NSStringFromCGRect(self.view.frame));
// Do any additional setup after loading the view.
#import "cocos2d.h"
#interface LineDrawer : CCLayer
- (id)initWithImage:(UIImage*)imageName;
// change the color of line
- (void)changeLineColorToRed:(float)r_ green:(float)g_ blue:(float)b_ alpha:(float)a_;
// the undo function to call. When you undo the last line, the also will be an change in line color
- (void)undo;
// get the actual drawing from screen
- (UIImage*)getScreenShot;
// property change methods
- (void)changeOverdraw:(float)overdraw_;
- (void)changeThikness:(int)thikness_;
- (void)changeAlpha:(float)alpha_;
#end
- (id)initWithImage:(UIImage *)image
{
self = [super init];
if (self) {
points = [NSMutableArray array];
velocities = [NSMutableArray array];
circlesPoints = [NSMutableArray array];
_undoManager = [[RMUndoManager alloc] init];
shaderProgram_ = [[CCShaderCache sharedShaderCache] programForKey:kCCShader_PositionColor];
overdraw = 1.0f;
CCTexture2D * imageTexture = [[CCTexture2D alloc] initWithCGImage:image.CGImage
resolutionType:kCCResolutioniPadRetinaDisplay];
CCSprite *backGroundSprite = [[CCSprite alloc] initWithTexture: imageTexture];
[backGroundSprite setPosition:CGPointMake(768/2, 1024/2)];
renderTexture = [[CCRenderTexture alloc] initWithWidth:(int)self.contentSize.width
height:(int)self.contentSize.height
pixelFormat:kCCTexture2DPixelFormat_RGBA8888];
renderTexture.anchorPoint = ccp(0,0);
renderTexture.position = ccp(1024 * 0.5f, 768 * 0.5f);
renderTexture.sprite = backGroundSprite;
[[renderTexture sprite] setBlendFunc:(ccBlendFunc){GL_ONE, GL_ONE_MINUS_SRC_ALPHA}];
[renderTexture clear:1.0f g:1.0f b:1.0f a:0];
[renderTexture begin];
[backGroundSprite visit];
[renderTexture end];
[self addChild:renderTexture];
self.isTouchEnabled = YES;
ccColor4F c = {0, 0, 190.0f/255.0f, 1};
drawColor = c;
thikness = 3;
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self
action:#selector(handlePanGesture:)];
panGestureRecognizer.maximumNumberOfTouches = 1;
[self addGestureRecognizer:panGestureRecognizer];
UILongPressGestureRecognizer *longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self
action:#selector(handleLongPress:)];
[self addGestureRecognizer:longPressGestureRecognizer];
UITapGestureRecognizer * tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(handleTap:)];
tapGestureRecognizer.numberOfTapsRequired = 1;
[self addGestureRecognizer:tapGestureRecognizer];
}
return self;
}
can someone help me with this?
https://dl.dropbox.com/u/15710714/iOS%20Simulator%20Bildschirmfoto%2023.01.2013%2016.17.57.png

just add [director_ startAnimation];
below [director_ pushScene: scene];

Related

Setting frame to view during UIPanGesture recognition

I'm trying to update frames for two labels during UIPanGesture recognition of a UIView (centre grey color).
Functionality
I need to choose a language between English and Arabic. There is a slider button in middle (grey view) and I have applied UIPanGesture to that. So while swiping towards Arabic the language English should move to centre and assumes that its selected and vice versa.
I tried my level best but I can only make upto this. Frames are not setting properly and I don't know is there any other easy way to do this.
Code
- (void)viewDidLoad {
[super viewDidLoad];
UIPanGestureRecognizer *gesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handleGesture:)];
[dragview addGestureRecognizer:gesture];
}
- (void)handleGesture:(UIPanGestureRecognizer *)gestureRecognizer
{
CGPoint velocity = [gestureRecognizer velocityInView: gestureRecognizer.view];
CGPoint location = [gestureRecognizer locationInView: gestureRecognizer.view];
if(velocity.x > 0)
{
NSLog(#"gesture went right");
if (dragview.frame.origin.x + dragview.frame.size.width >= dragV.frame.size.width) {
[dragview setFrame:CGRectMake(dragV.frame.size.width - dragview.frame.size.width, dragview.frame.origin.y, dragview.frame.size.width, dragview.frame.size.height)];
english.center = CGPointMake(dragV.frame.size.width / 2,
dragV.frame.size.height / 2);
} else {
float dX = location.x-panCoord.x;
gestureRecognizer.view.frame = CGRectMake(gestureRecognizer.view.frame.origin.x+dX, 0, gestureRecognizer.view.frame.size.width, gestureRecognizer.view.frame.size.height);
[english setFrame:CGRectMake(english.frame.origin.x + 1.0f, english.frame.origin.y, english.frame.size.width, english.frame.size.height)];
[arabic setFrame:CGRectMake(arabic.frame.origin.x + 1.0f, arabic.frame.origin.y, arabic.frame.size.width, arabic.frame.size.height)];
}
}
else
{
NSLog(#"gesture went left");
if (dragview.frame.origin.x <= 0) {
[dragview setFrame:CGRectMake(0, dragview.frame.origin.y, dragview.frame.size.width, dragview.frame.size.height)];
arabic.center = CGPointMake(dragV.frame.size.width / 2,
dragV.frame.size.height / 2);
} else {
float dX = location.x+panCoord.x;
gestureRecognizer.view.frame = CGRectMake(gestureRecognizer.view.frame.origin.x+dX, 0, gestureRecognizer.view.frame.size.width, gestureRecognizer.view.frame.size.height);
[english setFrame:CGRectMake(english.frame.origin.x - 1.0f, english.frame.origin.y, english.frame.size.width, english.frame.size.height)];
[arabic setFrame:CGRectMake(arabic.frame.origin.x - 1.0f, arabic.frame.origin.y, arabic.frame.size.width, arabic.frame.size.height)];
}
}
}
Screenshots
Initially it looks like this,
While dragging towards arabic,
While dragging towards english,
Answers are appreciated!!
I got output.I tried your code and I used SwipeGestureRecognizer code.It works fine now.
I tried with 2 optins
OPTION 1:SwipeGestureRecognizer
- (void)viewDidLoad
{
[super viewDidLoad];
// Swipe Left
UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeLeft:)];
swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
[arabicView addGestureRecognizer:swipeLeft];
// Swipe Right
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeRight:)];
swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
[englishView addGestureRecognizer:swipeRight];
}
- (void)handleSwipeLeft:(UISwipeGestureRecognizer *)recognizer
{
[self performSelector:#selector(moveAtRight) withObject:nil afterDelay:0.01f];
}
- (void)handleSwipeRight:(UISwipeGestureRecognizer *)recognizer
{
[self performSelector:#selector(moveAtLeft) withObject:nil afterDelay:0.01f];
}
-(void)moveAtRight
{
englishView.frame = CGRectMake(0, 0, 53, 53);
englishView.backgroundColor = [UIColor lightGrayColor];
arabicView.frame = CGRectMake(53, 0, 205, 53);
english.text = #"English";
arabic.text = #"Arabic";
arabicView.backgroundColor = [UIColor blueColor];
[dragview removeFromSuperview];
}
-(void)moveAtLeft
{
englishView.frame = CGRectMake(0, 0, 205, 53);
arabicView.frame = CGRectMake(205, 0, 53, 53);
arabicView.backgroundColor = [UIColor lightGrayColor];
englishView.backgroundColor = [UIColor blueColor];
english.text = #"English";
arabic.text = #"Arabic";
[dragview removeFromSuperview];
}
In above code I set background color to blue.If you want to any other color change.
At Initial
When I swipe towards Arabic
When I swipe towards English
Above these are output.
OPTION 2:PanGestureRecognizer
Now I tried with your PanGestureRecognizer Code.I set frame and background color for englishView and arabicView separately.Now it works fine.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_drawPath = [UIBezierPath
bezierPathWithRoundedRect:CGRectMake(0, 0, 140, 35)
byRoundingCorners:(UIRectCornerBottomLeft | UIRectCornerBottomRight | UIRectCornerTopLeft | UIRectCornerTopRight)
cornerRadii:CGSizeMake(4, 4)
];
_rectLayer = [[CAShapeLayer alloc] init];
_rectLayer.path = _drawPath.CGPath;
_rectLayer.strokeColor = [UIColor blackColor].CGColor;
_rectLayer.lineWidth = 2.0f;
_rectLayer.fillColor = [UIColor clearColor].CGColor;
_rectLayer.strokeEnd = 0.f;
[vi.layer addSublayer:_rectLayer];
[self drawRectangle:nil];
UIPanGestureRecognizer *gesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handleGesture:)];
[gesture setMinimumNumberOfTouches:1];
[gesture setMaximumNumberOfTouches:1];
[englishView addGestureRecognizer:gesture];
UIPanGestureRecognizer *gesture1 = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handleGesture:)];
[gesture1 setMinimumNumberOfTouches:1];
[gesture1 setMaximumNumberOfTouches:1];
[arabicView addGestureRecognizer:gesture1];
}
- (void)handleGesture:(UIPanGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state == UIGestureRecognizerStateChanged)
{
NSLog(#"Changed");
CGPoint velocity = [gestureRecognizer velocityInView:gestureRecognizer.view];
CGPoint translation = [gestureRecognizer translationInView:gestureRecognizer.view];
if(velocity.x > 0)
{
NSLog(#"gesture went right");
gestureRecognizer.view.frame = CGRectMake(gestureRecognizer.view.frame.origin.x + translation.x, 0, gestureRecognizer.view.frame.size.width, gestureRecognizer.view.frame.size.height);
NSLog(#"The gestureRecognizer frame is - %#",NSStringFromCGRect(gestureRecognizer.view.frame));
[englishView setFrame:CGRectMake(0, englishView.frame.origin.y, 205, englishView.frame.size.height)];
[englishView setBackgroundColor:[UIColor colorWithRed:(15/255.0f) green:(97/255.0f) blue:(163/255.0f) alpha:1.0f]];
[arabicView setFrame:CGRectMake(205, arabicView.frame.origin.y, 53, arabicView.frame.size.height)];
[arabicView setBackgroundColor:[UIColor lightGrayColor]];
[gestureRecognizer setTranslation:CGPointMake(0, 0) inView:dragV];
[dragview removeFromSuperview];
}
else
{
NSLog(#"gesture went left");
gestureRecognizer.view.frame = CGRectMake(gestureRecognizer.view.frame.origin.x + translation.x, 0, gestureRecognizer.view.frame.size.width, gestureRecognizer.view.frame.size.height);
[arabicView setFrame:CGRectMake(53, arabicView.frame.origin.y, 205, arabicView.frame.size.height)];
[englishView setFrame:CGRectMake(0, englishView.frame.origin.y,53,englishView.frame.size.height)];
[arabicView setBackgroundColor:[UIColor colorWithRed:(15/255.0f) green:(97/255.0f) blue:(163/255.0f) alpha:1.0f]];
[englishView setBackgroundColor:[UIColor lightGrayColor]];
[gestureRecognizer setTranslation:CGPointMake(0, 0) inView:dragV];
[dragview removeFromSuperview];
}
}
}
At First once I run the app
Middle Finger towards Arabic View
Middle Finger towards English View

animation not works in the non-initial UIViewController

I have a UIView called loadingView shows some UIActivityIndicatorView-like animation. There are two UIViewControllers that all have such UIView.
The initial UIViewController's code:
- (void)viewDidLoad {
self.loadingView = [[LoadingView alloc] initWithFrame:CGRectMake(10, 1, 120, 120)];
[self.view addSubview:self.loadingView];
}
Also it has a button to present the second UIViewController:
- (void)buttonPressed {
SecondViewController *sVC = [[SecondViewController alloc] init];
[self presentViewController:sVC animated:YES completion:nil];
}
The second ViewController's viewDidLoad method code:
- (void)viewDidLoad {
self.loadingView = [[LoadingView alloc] initWithFrame:CGRectMake(10, 1, 120, 120)];
[self.view addSubview:self.loadingView];
}
As you can see, the two UIViewControllers has the same viewDidLoad method code.
The loadingView works well in the initial UIViewController.
But in the second UIViewController, the loadingView only displays the black frame( I set the background colour to black).
Here is my loadingView implement code:
#define NUMBER_OF_DOT 15
#define DURATION 1.5
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.replicatorLayer = [[CAReplicatorLayer alloc] init];
self.replicatorLayer.frame = frame;
self.replicatorLayer.cornerRadius = 10.0;
self.replicatorLayer.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.86].CGColor;
self.replicatorLayer.position = self.center;
self.replicatorLayer.instanceDelay = DURATION/NUMBER_OF_DOT;
[self.layer addSublayer:self.replicatorLayer];
float size = frame.size.width*14/200;
self.dot = [[CALayer alloc] init];
self.dot.bounds = CGRectMake(0, 0, size, size);
self.dot.position = CGPointMake(frame.size.width/2, frame.size.height/5);
self.dot.backgroundColor = [UIColor colorWithWhite:0.8 alpha:1.0].CGColor;
self.dot.borderColor = [UIColor whiteColor].CGColor;
self.dot.borderWidth = 1.0;
self.dot.cornerRadius = 1.5;
self.dot.transform = CATransform3DMakeScale(0.01, 0.01, 0.01);
[self.replicatorLayer addSublayer:self.dot];
self.replicatorLayer.instanceCount = NUMBER_OF_DOT;
float angle = 2*M_PI/NUMBER_OF_DOT;
self.replicatorLayer.instanceTransform = CATransform3DMakeRotation(angle, 0.0, 0.0, 0.1);
self.shrink = [[CABasicAnimation alloc] init];
self.shrink.keyPath = #"transform.scale";
self.shrink.fromValue = [NSNumber numberWithFloat:1.0];
self.shrink.toValue = [NSNumber numberWithFloat:0.1];
self.shrink.duration = DURATION;
self.shrink.repeatCount = INFINITY;
[self.dot addAnimation:self.shrink forKey:nil];
}
return self;
}
-(void)viewDidAppear:(BOOL)animated
{
self.loadingView = [[LoadingView alloc] initWithFrame:CGRectMake(10, 1, 120, 120)];
[self.view addSubview:self.loadingView];
}
Put this code in viewDidAppear of SecondViewController so it works in present mode as well.

Possible to use scenekit in cocos2d project to render 3d objects?

-(id) init {
self = [super init];
CGSize wSize = [[CCDirector sharedDirector] viewSize];
CCSprite*imgBackground = [CCSprite spriteWithImageNamed:#"imgBackground.png"];
imgBackground.anchorPoint = ccp(0, 0);
[self addChild:imgBackground];
//adding the plus button
btnPlus = [CCButton buttonWithTitle:#"[ Plus ]" fontName:#"Georgia" fontSize:16.0f];
btnPlus.positionType = CCPositionTypeNormalized;
btnPlus.position = ccp(0.25f, 0.25f);
[btnPlus setTarget:self selector:#selector(btnPlusClicked)];
[self addChild:btnPlus];
btnMinus = [CCButton buttonWithTitle:#"[ Minus ]" fontName:#"Georgia" fontSize:16.0f];
btnMinus.positionType = CCPositionTypeNormalized;
btnMinus.position = ccp(0.75f, 0.25f);
[btnMinus setTarget:self selector:#selector(btnMinusClicked)];
[self addChild:btnMinus];
//view.scene = (SCNScene*)self.scene;
UIView *overlay = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 560)];
SCNBox* boxGeometry = [SCNBox boxWithWidth:10.0 height:10.0 length:10.0 chamferRadius:1.0];
dScene = [[SCNScene alloc] init];
node = [SCNNode nodeWithGeometry:boxGeometry];
//view = [[SCNView alloc] init];
//view.scene = dScene;
//overlay.backgroundColor = [UIColor colorWithWhite:1 alpha:.5];
//view = [[SCNView alloc] init];
//view.backgroundColor =[UIColor colorWithWhite:0 alpha:.5];
//[overlay addSubview:view];
[[[CCDirector sharedDirector] view] addSubview:overlay];
[dScene.rootNode addChildNode:node];
//[self.scene addChild:node];
//node.light = SCNLightTypeAmbient;
return self;
}
I am trying to add a 3d object using scenekit to a cocos2d project because scenekit looks promising.
However, I'm getting error
OpenGL error GL_INVALID_FRAMEBUFFER_OPERATION detected at CCRenderStateGLTransition 298
OpenGL error GL_INVALID_FRAMEBUFFER_OPERATION detected at CCRenderStateGLTransition 298
OpenGL error GL_INVALID_FRAMEBUFFER_OPERATION detected at CCRenderStateGLTransition 298
Anyone knows if it is possible to do so? Any advice would be grateful. Thanks!

enable pinch to zoom in viewcontroller

I want users to be able to use pinch to zoom in my app which uses Storyboard and programmatically generated buttons and labels to produce a View within a Viewcontroller. In the View's Attribute inspector I have checked both User Interaction Enabled and Multiple Touch. But no pinch to zoom seems to work.
The code which creates the important part of the View is as follows.
- (void)viewDidLoad
{
[super viewDidLoad];
NSInteger xPipsOrigin = 0;
NSInteger xPipsStep = 22.0;
NSString* cards = #"AKQJT98765432";
NSInteger yPipsOrigin = 100;
if (UI_USER_INTERFACE_IDIOM()== UIUserInterfaceIdiomPhone){
xPipsOrigin = 0;
xPipsStep = 22.0;
xPipsStep = 34.0;
}
else{
xPipsOrigin = 100;
xPipsStep = 40.0;
}
NSInteger xPipsCurrent = xPipsOrigin;
self.countCards = 0;
self.cardList = [NSMutableArray arrayWithCapacity:0];
yPipsOrigin = 100;
xPipsCurrent = xPipsOrigin;
for( int x=0;x<[cards length]; x++ ){
[cards substringWithRange:NSMakeRange(x,1)];
UIButton *b= [UIButton buttonWithType:UIButtonTypeRoundedRect];
xPipsCurrent += xPipsStep;
[b setTitle:[cards substringWithRange:NSMakeRange(x,1)] forState:UIControlStateNormal];
[b setTitle:#" " forState:UIControlStateDisabled];
[b setFrame:CGRectMake(xPipsCurrent, yPipsOrigin, 20, 20)];
[b setEnabled:YES];
[b setUserInteractionEnabled:YES];
[self.view addSubview:b];
[b addTarget:self action:#selector(spadeButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
}
xPipsCurrent = xPipsOrigin + xPipsStep/2;
for( int x=0;x<[cards length]-1; x++ ){
xPipsCurrent += xPipsStep;
UILabel *lab = [[UILabel alloc] initWithFrame:CGRectMake( 0, 0, 20, 20)];
lab.text = #"\u2660";
lab.backgroundColor = [UIColor clearColor];
lab.center = CGPointMake(xPipsCurrent+10, yPipsOrigin+10);
[self.view addSubview:lab];
}
}
How can I enable Pinch to Zoom in this app?
If you want to enable pinch to zoom on a UIView you have to wrap it into a UIScrollView first
Whilst you can use User Interaction Enabled and try do it that way, it'll be easier to add a UIGestureRecogniser to your UIView. That way it handles most of the setup code for you, and when it detects a pinch triggers a method.
Basic example in Objective-C:
UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(handlePinchGesture:)];
[self.view addGestureRecognizer:pinchGesture];
- (void)handlePinchGesture:(id)sender
{
NSLog(#"Recieved pinch");
UIPinchGestureRecognizer *senderGR = (UIPinchGestureRecognizer *)sender;
NSLog(#"Scale is: %f", senderGR.scale);
}
And in Swift:
let pinchGestureRecognizer = UIPinchGestureRecognizer.init(target: self, action: #selector(ViewController.handlePinchGesture(_:)))
self.view.addGestureRecognizer(pinchGestureRecognizer)
func handlePinchGesture(sender:AnyObject) {
print("Received pinch")
let senderGR = sender as! UIPinchGestureRecognizer
print("Scale is \(senderGR.scale)")
}

Scrolling UIScrollView on external screen attached to an iPad

Hey. I've achieved making a programmatic UIScrollView with zooming, but now I've been trying to take the scrollable/zoomable image to an external screen if plugged in.
#implementation MapVC
UIScrollView *mapScrollView;
UIImageView *mapImageView;
UIImageView *mapImageViewEx;
CGFloat lastScale = 0;
NSMutableArray *map_List;
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
mainMenuAppDelegate *del = (mainMenuAppDelegate *)[[UIApplication sharedApplication] delegate];
map_List = [[NSMutableArray alloc] init];
[map_List addObject:#"Pacific_Map.png"];
[map_List addObject:#"Atlantic_Map.png"];
CGRect mapScrollViewFrame = CGRectMake(0, 0, 1024, 768);
mapScrollView = [[UIScrollView alloc] initWithFrame:mapScrollViewFrame];
mapScrollView.backgroundColor = [UIColor blackColor];
[mapScrollView setDelegate:(id<UIScrollViewDelegate>)self];
mapScrollView.contentSize = CGSizeMake(2437, 1536);
mapScrollView.bounces = NO;
mapScrollView.bouncesZoom = NO;
mapScrollView.minimumZoomScale = .5;
mapScrollView.maximumZoomScale = 1.5;
[mapScrollView setZoomScale:mapScrollView.minimumZoomScale];
UIImage *mapImage = [UIImage imageNamed:[map_List objectAtIndex:mapNum]];
mapImageView = [[UIImageView alloc] initWithImage: mapImage];
[mapImage release];
if(exScreenEnabled==1){
UIImage *mapImageEx = [UIImage imageNamed:[map_List objectAtIndex:mapNum]];
mapImageViewEx = [[UIImageView alloc] initWithImage: mapImageEx];
[mapImageEx release];
UIView *containerExViewP = (UIView*)[del.switchExVC.view viewWithTag:9000];
[containerExViewP addSubview:mapImageViewEx];
}else{
[mapScrollView addSubview:mapImageView];
}
[self addSubview:mapScrollView];
mapImageView.userInteractionEnabled = YES;
UIImage *footerMapIMG = [UIImage imageNamed:#"footer_map_alternate.png"];
UIImageView *footerMapView = [[UIImageView alloc] initWithImage:(UIImage *)footerMapIMG];
CGRect footerMapFrame = CGRectMake(0, 686, 213, 82);
footerMapView.frame = footerMapFrame;
[self addSubview:footerMapView];
footerMapView.image = footerMapIMG;
[footerMapView release];
CGRect backBTNFrame = CGRectMake(20, 714, 140, 52);
UIButton *MAP_backButton = [[UIButton alloc] init];
MAP_backButton.frame = backBTNFrame;
UIImage *MAP_backButtonIMG = [UIImage imageNamed:#"button_back.png"];
[MAP_backButton setImage:MAP_backButtonIMG forState:UIControlStateNormal];
MAP_backButton.backgroundColor = [UIColor clearColor];
[self addSubview:MAP_backButton];
[MAP_backButton release];
[MAP_backButton addTarget:del.switchVC
action:#selector(gotoMapAndListChooser)
forControlEvents:UIControlEventTouchUpInside];
}
return self;
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
if(exScreenEnabled==1){
return mapImageViewEx;
}else{
return mapImageView;
}
}
(Sorry I've had no luck getting that formatted to look right on this site)
If a video cable is plugged into an iPad, there's no image on the iPad, which is what I want. The image on the external screen zooms correctly when you do the gesture on the iPad, but I can't figure out how to make it scroll. Thanks in advance.
edit: I now have this -
#implementation MapVC
UIScrollView *mapScrollView;
UIImageView *mapImageView;
UIImageView *mapImageViewEx;
CGFloat lastScale = 0;
NSMutableArray *map_List;
int touchesNum = 0;
-(void)touchesBegan:(NSSet *)theTouches withEvent:(UIEvent *)event {
NSSet *touches = [event allTouches];
touchesNum=[touches count];
NSLog(#"number of touches %i", touchesNum);
}
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
mainMenuAppDelegate *del = (mainMenuAppDelegate *)[[UIApplication sharedApplication] delegate];
map_List = [[NSMutableArray alloc] init];
[map_List addObject:#"Pacific_Map.png"];
[map_List addObject:#"Atlantic_Map.png"];
CGRect mapScrollViewFrame = CGRectMake(0, 0, 1024, 768);
mapScrollView = [[UIScrollView alloc] initWithFrame:mapScrollViewFrame];
mapScrollView.backgroundColor = [UIColor blackColor];
[mapScrollView setDelegate:(id<UIScrollViewDelegate>)self];
mapScrollView.contentSize = CGSizeMake(2437, 1536);
mapScrollView.bounces = NO;
mapScrollView.bouncesZoom = NO;
mapScrollView.minimumZoomScale = .5;
mapScrollView.maximumZoomScale = 1.5;
[mapScrollView setZoomScale:mapScrollView.minimumZoomScale];
UIImage *mapImage = [UIImage imageNamed:[map_List objectAtIndex:mapNum]];
mapImageView = [[UIImageView alloc] initWithImage: mapImage];
[mapImage release];
if(exScreenEnabled==1){
UIImage *mapImageEx = [UIImage imageNamed:[map_List objectAtIndex:mapNum]];
mapImageViewEx = [[UIImageView alloc] initWithImage: mapImageEx];
[mapImageEx release];
UIView *containerExViewP = (UIView*)[del.switchExVC.view viewWithTag:9000];
[containerExViewP addSubview:mapImageViewEx];
}else{
[mapScrollView addSubview:mapImageView];
}
[self addSubview:mapScrollView];
mapImageView.userInteractionEnabled = YES;
UIImage *footerMapIMG = [UIImage imageNamed:#"footer_map_alternate.png"];
UIImageView *footerMapView = [[UIImageView alloc] initWithImage:(UIImage *)footerMapIMG];
CGRect footerMapFrame = CGRectMake(0, 686, 213, 82);
footerMapView.frame = footerMapFrame;
[self addSubview:footerMapView];
footerMapView.image = footerMapIMG;
[footerMapView release];
CGRect backBTNFrame = CGRectMake(20, 714, 140, 52);
UIButton *MAP_backButton = [[UIButton alloc] init];
MAP_backButton.frame = backBTNFrame;
UIImage *MAP_backButtonIMG = [UIImage imageNamed:#"button_back.png"];
[MAP_backButton setImage:MAP_backButtonIMG forState:UIControlStateNormal];
MAP_backButton.backgroundColor = [UIColor clearColor];
[self addSubview:MAP_backButton];
[MAP_backButton release];
[MAP_backButton addTarget:del.switchVC
action:#selector(gotoMapAndListChooser)
forControlEvents:UIControlEventTouchUpInside];
mapScrollView.multipleTouchEnabled = YES;
}
return self;
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
if(exScreenEnabled==1){
return mapImageViewEx;
}else{
return mapImageView;
}
}
- (void)scrollViewDidScroll:(UIScrollView *)inscrollView{
if(touchesNum==0){
CGPoint p = mapScrollView.contentOffset;
mapImageViewEx.frame = CGRectMake((p.x*-1), (p.y*-1), mapImageViewEx.frame.size.width, mapImageViewEx.frame.size.height);
}
}
- (void)dealloc {
[mapScrollView release];
[mapImageView release];
[map_List release];
[super dealloc];
}
#end
As I said below, I can now get either scroll or zooming to work separately, but zooming is all messed up if scrolling is working, because when zooming it thinks it's also scrolling. So I want to avoid it scrolling when zooming, and to do this I want to detect the number of touches, which I must be doing wrong!
Got it working with the image being on the iPad and external screen. I'll probably swap it in with a rectangular area because the image is resource heavy to be both the iPad and external screen.
#import "exGlobal.h"
#import "mapVC.h"
#import "switchVC.h"
#import "switchExVC.h"
#import "mainMenuAppDelegate.h"
#import <MobileCoreServices/MobileCoreServices.h>
#implementation MapVC
UIScrollView *mapScrollView;
UIImageView *mapImageView;
UIImageView *mapImageViewEx;
CGFloat lastScale = 0;
NSMutableArray *map_List;
static int toggleScroll = 1;
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
mainMenuAppDelegate *del = (mainMenuAppDelegate *)[[UIApplication sharedApplication] delegate];
map_List = [[NSMutableArray alloc] init];
[map_List addObject:#"Pacific_Map.png"];
[map_List addObject:#"Atlantic_Map.png"];
CGRect mapScrollViewFrame = CGRectMake(0, 0, 1024, 768);
mapScrollView = [[UIScrollView alloc] initWithFrame:mapScrollViewFrame];
mapScrollView.backgroundColor = [UIColor blackColor];
[mapScrollView setDelegate:(id<UIScrollViewDelegate>)self];
mapScrollView.contentSize = CGSizeMake(2437, 1536);
mapScrollView.bounces = NO;
mapScrollView.bouncesZoom = NO;
mapScrollView.minimumZoomScale = .5;
mapScrollView.maximumZoomScale = 1.5;
[mapScrollView setZoomScale:mapScrollView.minimumZoomScale];
UIImage *mapImage = [UIImage imageNamed:[map_List objectAtIndex:mapNum]];
mapImageView = [[UIImageView alloc] initWithImage: mapImage];
[mapImage release];
if(exScreenEnabled==1){
UIImage *mapImageEx = [UIImage imageNamed:[map_List objectAtIndex:mapNum]];
mapImageViewEx = [[UIImageView alloc] initWithImage: mapImageEx];
[mapImageEx release];
UIView *containerExViewP = (UIView*)[del.switchExVC.view viewWithTag:9000];
[containerExViewP addSubview:mapImageViewEx];
[mapScrollView addSubview:mapImageView]; // see if this works ok on iPad. Map on TV AND iPad.
}else{
[mapScrollView addSubview:mapImageView];
}
[self addSubview:mapScrollView];
mapImageView.userInteractionEnabled = YES;
UIImage *footerMapIMG = [UIImage imageNamed:#"footer_map_alternate.png"];
UIImageView *footerMapView = [[UIImageView alloc] initWithImage:(UIImage *)footerMapIMG];
CGRect footerMapFrame = CGRectMake(0, 686, 213, 82);
footerMapView.frame = footerMapFrame;
[self addSubview:footerMapView];
footerMapView.image = footerMapIMG;
[footerMapView release];
CGRect backBTNFrame = CGRectMake(20, 714, 140, 52);
UIButton *MAP_backButton = [[UIButton alloc] init];
MAP_backButton.frame = backBTNFrame;
UIImage *MAP_backButtonIMG = [UIImage imageNamed:#"button_back.png"];
[MAP_backButton setImage:MAP_backButtonIMG forState:UIControlStateNormal];
MAP_backButton.backgroundColor = [UIColor clearColor];
[self addSubview:MAP_backButton];
[MAP_backButton release];
[MAP_backButton addTarget:del.switchVC
action:#selector(gotoMapAndListChooser)
forControlEvents:UIControlEventTouchUpInside];
mapScrollView.multipleTouchEnabled = YES;
}
return self;
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
return mapImageView;
}
-(void)scrollViewDidZoom:(UIScrollView *)scrollView {
if(exScreenEnabled==1){
CGPoint p = mapScrollView.contentOffset;
mapImageViewEx.frame = CGRectMake((p.x*-1), (p.y*-1), mapImageView.frame.size.width, mapImageView.frame.size.height);
}
}
- (void)scrollViewDidScroll:(UIScrollView *)inscrollView{
if(exScreenEnabled==1 && toggleScroll==1){
CGPoint p = mapScrollView.contentOffset;
mapImageViewEx.frame = CGRectMake((p.x*-1), (p.y*-1), mapImageView.frame.size.width, mapImageView.frame.size.height);
}
}
- (void)scrollViewWillBeginZooming:(UIScrollView *)theScrollView withView:(UIView *)view{
NSLog(#"BEGIN ZOOMING");
toggleScroll=0;
}
- (void)scrollViewDidEndZooming:(UIScrollView *)theScrollView withView:(UIView *)view atScale:(float)scale{
NSLog(#"END ZOOMING");
toggleScroll=1;
}
- (void)dealloc {
[mapScrollView release];
[mapImageView release];
[map_List release];
[super dealloc];
}
#end
I pressed the space bar (4) times for code, and NOPE doesn't work stack overflow still broken. :)

Resources