Image moving while rotating - ios

I just move sticker after rotate, but the direction of the moved sticker is changed as much as the rotation angle and moves
please help me, i don't know why this happen
panGesture:
UIView *gestureView = gesture.view;
CGPoint point = [gesture translationInView:gestureView];
// react native 단에서 쓰레기 위치를 바텀 기준 10%로 잡음
// height은 top 기준
double trashBottomPosition = round(self.bounds.size.height * 0.90);
double trashCenterPosition = round(self.bounds.size.width / 2);
double nextXPosition = gestureView.center.x + (_currentTextScale * point.x);
double nextYPosition = gestureView.center.y + (_currentTextScale * point.y);
bool isXTrashArea = trashCenterPosition - 40 < nextXPosition && trashCenterPosition + 40 > nextXPosition;
bool isYTrashArea = trashBottomPosition - 40 < nextYPosition && trashBottomPosition + 40 > nextYPosition;
switch (gesture.state) {
case UIGestureRecognizerStateBegan:
break;
case UIGestureRecognizerStateChanged:
{
if (isXTrashArea && isYTrashArea) {
_openTrash = true;
if (!_isScaleDown && _isTrashMode) {
_prevScale = gestureView.transform.a;
gestureView.transform = CGAffineTransformMakeScale(0.5, 0.5);
_isScaleDown = true;
}
} else {
_openTrash = false;
if (_isScaleDown && _isTrashMode) {
gestureView.transform = CGAffineTransformMakeScale(_prevScale, _prevScale);
_isScaleDown = false;
}
}
gestureView.center = CGPointMake(nextXPosition, nextYPosition);
[gesture setTranslation:CGPointZero inView:gestureView];
break;
}
case UIGestureRecognizerStateEnded: {
if (_openTrash && _isTrashMode) {
[gestureView removeFromSuperview];
}
_openTrash = false;
break;
}
default:
break;
}
rotate:
UIView *gestureView = gesture.view;
if (_isActiveText) return;
switch (gesture.state) {
case UIGestureRecognizerStateBegan: {
gestureView.layer.anchorPoint = CGPointMake(0.5, 0.5);
break;
}
case UIGestureRecognizerStateChanged:
{
// CGPoint point = [gesture locationInView:self];
gestureView.transform = CGAffineTransformRotate(gestureView.transform, gesture.rotation);
_currentTextRotate = gesture.rotation;
gesture.rotation = 0;
break;
}
case UIGestureRecognizerStateEnded: {
break;
}
default:
break;
}
add image:
bool isNetwork = [RCTConvert BOOL:[sticker objectForKey:#"isNetwork"]];
bool isAsset = [RCTConvert BOOL:[sticker objectForKey:#"isAsset"]];
NSString *uri = [sticker objectForKey:#"uri"];
NSString *type = [sticker objectForKey:#"type"];
NSURL *url = isNetwork || isAsset
? [NSURL URLWithString:uri]
: [[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:uri ofType:type]];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [UIImage imageWithData:data];
UIImageView *imgView = [[UIImageView alloc] initWithImage: img];
imgView.frame = CGRectMake(150, 150, 130, 130);
imgView.userInteractionEnabled = true;
imgView.multipleTouchEnabled = true;
// rotation
UIRotationGestureRecognizer *stickerRotationGestureRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(stickerRotationGesture:)];
stickerRotationGestureRecognizer.delegate = self;
[imgView addGestureRecognizer:stickerRotationGestureRecognizer];
// pan gesture
UIPanGestureRecognizer *stickerPanGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(stickerPanGesture:)];
[stickerPanGestureRecognizer setMinimumNumberOfTouches:1];
[stickerPanGestureRecognizer setMaximumNumberOfTouches:1];
stickerPanGestureRecognizer.delegate = self;
[imgView addGestureRecognizer:stickerPanGestureRecognizer];
// pinch
UIPinchGestureRecognizer *stickerPinchGestureRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(stickerPinchGesture:)];
stickerPinchGestureRecognizer.delegate = self;
[imgView addGestureRecognizer:stickerPinchGestureRecognizer];
// longpress stickerLongPressGesture
UILongPressGestureRecognizer *stickerLongPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(stickerLongPressGesture:)];
stickerLongPressGestureRecognizer.delegate = self;
stickerLongPressGestureRecognizer.minimumPressDuration = 0.02;
[imgView addGestureRecognizer:stickerLongPressGestureRecognizer];
[self addSubview:imgView];

Related

Apply filter to current image index in UIScrollView GPUImage

Im currently deploying a ImageScroller by UIScrollView, and it contain a filter toolbar at the bottom as you can see on the image.
But im facing a problem is that when i press the button, the filters is only apply to the last image as example below:
Gif Example
So please anyone can help me to solve this one, my expected output is the filter is applied to the current displaying image, not only the last one. Here i would attach my code for your reference and thank you so much.
#interface EditImageVC ()
#end
#implementation EditImageVC
UIImageView *img;
- (void)viewDidLoad {
[super viewDidLoad];
int x=0;
for (int i = 0; i < _scrollViewImageArray.count ; i++) {
_picture = [_scrollViewImageArray objectAtIndex:i];
img =[[UIImageView alloc]initWithFrame:CGRectMake(x,20,[[UIScreen mainScreen] bounds].size.width,
self.imgScrollView.frame.size.height)];
img.image =_picture;
x=x+[[UIScreen mainScreen] bounds].size.width;
[_imgScrollView addSubview:img];
}
_imgScrollView.backgroundColor = [UIColor blackColor];
_imgScrollView.contentSize=CGSizeMake(x,
_imgScrollView.frame.size.height);
_imgScrollView.contentOffset=CGPointMake(0, 0);
img.contentMode = UIViewContentModeScaleAspectFit;
}
-(void)viewDidLayoutSubviews{
self.automaticallyAdjustsScrollViewInsets = NO;
}
- (IBAction)filterAction:(UIButton *)sender {
for (int i = 0; i < _scrollViewImageArray.count ; i++) {
UIImage *picture = [_scrollViewImageArray objectAtIndex:i];
GPUImageFilter *selectedFilter;
switch (sender.tag) {
case 0:
selectedFilter = [[GPUImageSepiaFilter alloc] init];
break;
case 1:
selectedFilter = [[GPUImageToonFilter alloc] init];
break;
default:
break;
}
UIImage *filteredImage = [selectedFilter imageByFilteringImage:picture];
[img setImage:filteredImage];
}
}
Just filter the last shown image and when filter image when scrollview scrolled to another image.
remember to add UIScrollViewDelegate
#interface EditImageVC : UIViewController <UIScrollViewDelegate> {
}
#end
- (void)viewDidLoad {
[super viewDidLoad];
imageViewsArray = [[NSMutableArray alloc] init];
int x=0;
for (int i = 0; i < _scrollViewImageArray.count ; i++) {
_picture = [_scrollViewImageArray objectAtIndex:i];
img =[[UIImageView alloc]initWithFrame:CGRectMake(x,20,[[UIScreen mainScreen] bounds].size.width,
self.imgScrollView.frame.size.height)];
img.image =_picture;
[imageViewsArray addObject:img];
x=x+[[UIScreen mainScreen] bounds].size.width;
[self.imgScrollView addSubview:img];
}
self.imgScrollView.backgroundColor = [UIColor blackColor];
self.imgScrollView.contentSize=CGSizeMake(x,
self.imgScrollView.frame.size.height);
self.imgScrollView.contentOffset=CGPointMake(0, 0);
img.contentMode = UIViewContentModeScaleAspectFit;
self.imgScrollView.delegate = self;
}
GPUImageFilter *selectedFilter = nil;
NSInteger currentShownIndex = 0;
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
NSInteger indexAfterScrolled = scrollView.contentOffset.x / scrollView.frame.size.width;
if(indexAfterScrolled==currentShownIndex) return;
currentShownIndex = indexAfterScrolled;
if(selectedFilter!=nil) {
UIImage *filteredImage = [selectedFilter imageByFilteringImage:[_scrollViewImageArray objectAtIndex:currentShownIndex]];
[[imageViewsArray objectAtIndex:currentShownIndex] setImage:filteredImage];
}
}
- (IBAction)filterAction:(UIButton *)sender {
switch (sender.tag) {
case 0:
selectedFilter = [[GPUImageSepiaFilter alloc] init];
break;
case 1:
selectedFilter = [[GPUImageToonFilter alloc] init];
break;
default:
break;
}
UIImage *picture = [_scrollViewImageArray objectAtIndex:currentShownIndex];
UIImage *filteredImage = [selectedFilter imageByFilteringImage:picture];
[[imageViewsArray objectAtIndex:currentShownIndex] setImage:filteredImage];
}
Updated
If you want to filter current shown image, not need to apply UIScrollViewDelegate:
- (void)viewDidLoad {
[super viewDidLoad];
imageViewsArray = [[NSMutableArray alloc] init];
int x=0;
for (int i = 0; i < _scrollViewImageArray.count ; i++) {
_picture = [_scrollViewImageArray objectAtIndex:i];
img =[[UIImageView alloc]initWithFrame:CGRectMake(x,20,[[UIScreen mainScreen] bounds].size.width,
self.imgScrollView.frame.size.height)];
img.image =_picture;
[imageViewsArray addObject:img];
x=x+[[UIScreen mainScreen] bounds].size.width;
[self.imgScrollView addSubview:img];
}
self.imgScrollView.backgroundColor = [UIColor blackColor];
self.imgScrollView.contentSize=CGSizeMake(x,
self.imgScrollView.frame.size.height);
self.imgScrollView.contentOffset=CGPointMake(0, 0);
img.contentMode = UIViewContentModeScaleAspectFit;
self.imgScrollView.delegate = self;
}
- (IBAction)filterAction:(UIButton *)sender {
NSInteger objectAtIndex:currentShownIndex = scrollView.contentOffset.x / scrollView.frame.size.width;
GPUImageFilter *selectedFilter = nil;
switch (sender.tag) {
case 0:
selectedFilter = [[GPUImageSepiaFilter alloc] init];
break;
case 1:
selectedFilter = [[GPUImageToonFilter alloc] init];
break;
default:
break;
}
UIImage *picture = [_scrollViewImageArray objectAtIndex:currentShownIndex];
UIImage *filteredImage = [selectedFilter imageByFilteringImage:picture];
[[imageViewsArray objectAtIndex:currentShownIndex] setImage:filteredImage];
}

Crash EXC_BAD_ACCESS on touch method

I am currently working on a game which, seems to crash when accessing a certain part of the code which involves touching an item.
Here is the part of the code that crashes;
drawOn = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, currentDrawingImage.size.width/2, currentDrawingImage.size.height/2)];
The full method is here;
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
BOOL foundExtra = NO;
UITouch *touch = [[event allTouches] anyObject];
for(int i = 0; i < [extrasArray count]; i++)
{
if([[[extrasArray objectAtIndex:i] objectForKey:#"tag"] intValue] == [touch view].tag)
{
touchedExtra = YES;
lastTouchedExtra = (int)[touch view].tag;
foundExtra = YES;
}
}
if(foundExtra == NO)
{
if(movingStopped == NO)
{
drawOn = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, currentDrawingImage.size.width/2, currentDrawingImage.size.height/2)];
drawOn.image = currentDrawingImage;
drawOn.tag = lastTag + 1;
lastTag++;
CGPoint touchPoint = [[touches anyObject] locationInView:self.view];
drawOn.center = CGPointMake(touchPoint.x, touchPoint.y);
[bigView addSubview:drawOn];
lastTouchedPoint = touchPoint;
}
}
}
- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
if(touchedExtra == YES)
{
CGPoint touchPoint = [[touches anyObject] locationInView:self.view];
UITouch *touch = [touches anyObject];
int indexIngr = 0;
for(int i = 0; i < [extrasArray count]; i++)
{
if([[[extrasArray objectAtIndex:i] objectForKey:#"tag"] intValue] == [touch view].tag)
{
indexIngr = i;
[touch view].center = touchPoint;
}
}
NSMutableDictionary *md = [[NSMutableDictionary alloc] init];
[md setObject:[[extrasArray objectAtIndex:indexIngr] objectForKey:#"pic"] forKey:#"pic"];
[md setObject:NSStringFromCGRect([touch view].frame) forKey:#"frame"];
[md setObject:[NSString stringWithFormat:#"%d", (int)[touch view].tag] forKey:#"tag"];
[extrasArray replaceObjectAtIndex:indexIngr withObject:md];
// if([touch view].tag > 0)
// {
// [touch view].center = touchPoint;
//
// int tagLabel = [touch view].tag;
// NSMutableDictionary *md = [[NSMutableDictionary alloc] init];
// [md setObject:[[ingredients objectAtIndex:tagLabel - 1] objectForKey:#"pic"] forKey:#"pic"];
// [md setObject:NSStringFromCGRect([touch view].frame) forKey:#"frame"];
//
// [ingredients replaceObjectAtIndex:tagLabel - 1 withObject:md];
// }
}
else if(lastDecoration == 1)//draw on apple
{
if(movingStopped == NO)
{
CGPoint touchPoint = [[touches anyObject] locationInView:self.view];
if([self isFarEnoughFrom:touchPoint])
{
drawOn = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, currentDrawingImage.size.width/2, currentDrawingImage.size.height/2)];
drawOn.image = currentDrawingImage;
drawOn.tag = lastTag;
drawOn.center = CGPointMake(touchPoint.x, touchPoint.y);
[bigView addSubview:drawOn];
//[self.view insertSubview:drawOn belowSubview:backButton];
lastTouchedPoint = touchPoint;
}
}
}
}
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
{
touchedExtra = NO;
//movingStopped = YES;
lastTouchedExtra = -1;
}
The drawOnChosen method is used also;
- (void)drawOnChosen:(UIButton*)sender
{
[(AppDelegate*)[[UIApplication sharedApplication] delegate] playSoundEffect:1];
currentDrawingImage = [UIImage imageNamed:[NSString stringWithFormat:#"drawon%d.png", (int)sender.tag]];
movingStopped = NO;
lastDecoration = 1;
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^
{
decorationsView.frame = CGRectMake(0, -[[UIScreen mainScreen] bounds].size.height, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height);
} completion:^(BOOL finished)
{
[decorationsView removeFromSuperview];
}];
}

Why is my SKAction not functioning properly?

Okay, so in my SpriteKit game, I have an SKAction that waits and then calls a method. I have this action repeating forever. The methods spawns sprites. When I press a button (another sprite) the game pauses, and stops the action by removing it. When either resume or restart (also sprites) is pressed the action starts again and the sprites spawn.
However, when returning from the background (after the app is left) and the pause menu method automatically gets called, when I press the resume or restart button, the action does not run for some reason. Here's my code:
In GameScene.m:
-(void)createSceneContents {
self.isPaused = NO;
self.world = [SKNode node];
[self createUI];
[self createPauseMenu];
self.spawningSpeed = 1.5;
self.enemyData = [[Enemy alloc]init];
SKAction *wait = [SKAction waitForDuration:self.spawningSpeed];
SKAction *run = [SKAction performSelector:#selector(spawningEnemy) onTarget:self];
self.spawnAction = [SKAction repeatActionForever:[SKAction sequence:#[wait,run]]];
[self.world runAction:self.spawnAction withKey:#"spawn"];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(wentToForeground) name:UIApplicationWillEnterForegroundNotification object:nil];
[self addChild:self.world];
[self.world addChild:bottom];
[self.world addChild:self.player];
[self addChild:left];
[self addChild:right];
[self addChild:self.pause];
[self addChild:self.scoreLabelInGame];
[self addChild:self.actualScore];
}
-(void)createUI {
self.pause = [SKSpriteNode spriteNodeWithImageNamed:#"pausebutton.png"];
self.pause.size = CGSizeMake(self.customUnit,self.customUnit);
self.pause.name = #"pauseButton";
self.pause.position = CGPointMake(30, self.frame.size.height - 30);
self.scoreLabelInGame = [SKLabelNode labelNodeWithFontNamed:#"Futura"];
self.scoreLabelInGame.text = #"";
self.scoreLabelInGame.fontSize = 25;
self.scoreLabelInGame.position = CGPointMake(self.frame.size.width - 100, self.frame.size.height - 40);
self.actualScore = [SKLabelNode labelNodeWithFontNamed:#"Futura"];
self.actualScore.text = #"SCORE: 0";
self.actualScore.fontSize = 25;
self.actualScore.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeRight;
self.actualScore.position = CGPointMake(self.frame.size.width - 20, self.frame.size.height - 40);
self.deathImage = [SKSpriteNode spriteNodeWithImageNamed:#"youdied.png"];
self.deathImage.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)*1.5);
}
-(void)createPauseMenu {
self.pausedImage = [SKSpriteNode spriteNodeWithImageNamed:#"paused.png"];
self.pausedImage.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)*1.5);
self.restart = [SKLabelNode labelNodeWithFontNamed:#"Futura"];
self.restart.text = #"RESTART";
self.restart.fontSize = 25;
self.restart.position = CGPointMake(CGRectGetMidX(self.frame), self.pausedImage.position.y - self.pausedImage.position.y/5);
self.resume = [SKLabelNode labelNodeWithFontNamed:#"Futura"];
self.resume.text = #"RESUME";
self.resume.fontSize = 25;
self.resume.position = CGPointMake(self.restart.position.x, self.restart.position.y - self.customUnit);
}
-(void)spawningEnemy {
NSLog(#"spawned");
SKSpriteNode *aNewEnemy = [self.enemyData createEnemyWithSize:self.customUnit andWidth:self.frame.size.width andHeight:self.frame.size.height + self.player.position.y];
aNewEnemy.physicsBody.allowsRotation = NO;
aNewEnemy.physicsBody.categoryBitMask = self.enemyCategory;
aNewEnemy.physicsBody.collisionBitMask = self.enemyCategory | self.playerCategory | self.edgeCategory | self.bottomCategory;
aNewEnemy.physicsBody.contactTestBitMask = self.enemyCategory | self.playerCategory | self.edgeCategory | self.bottomCategory;
[self.world addChild:aNewEnemy];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
if([self.pause containsPoint:location] && self.isPaused == NO){
[self pauseGame];
}else if([self.resume containsPoint:location] && self.isPaused == YES) {
[self resumeGame];
}else if ([self.restart containsPoint:location] && self.isPaused == YES){
[self restartGame];
}else if (self.isTouchingGround == YES && self.isPaused == NO) {
[self.playerData jump:self.player];
NSLog(#"GOD YES");
self.isTouchingGround = NO;
}
}
-(void)pauseGame {
[self createPauseMenu];
NSLog(#"Pausing...");
[self removeActionForKey:#"spawn"];
self.world.paused = YES;
[self addChild:self.pausedImage];
[self addChild:self.restart];
[self addChild:self.resume];
NSString *path = [NSString stringWithFormat:#"%#/menu_music.mp3", [[NSBundle mainBundle]resourcePath]];
NSURL *pauseMusicURL = [NSURL fileURLWithPath:path];
self.pauseMusicPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:pauseMusicURL error:nil];
self.pauseMusicPlayer.numberOfLoops = -1;
[self.pauseMusicPlayer play];
[self.pause removeFromParent];
self.scoreLabelInGame.position = CGPointMake(self.restart.position.x, self.resume.position.y - self.customUnit);
self.actualScore.position = CGPointMake(self.restart.position.x, self.scoreLabelInGame.position.y - self.customUnit);
self.isPaused = YES;
[self.mainMusicPlayer pause];
}
-(void)restartGame {
[self removeAllChildren];
[self removeAllActions];
self.enemyData = nil;
self.isPaused = NO;
[self.pauseMusicPlayer stop];
[self createSceneContents];
[self runAction:self.spawnAction withKey:#"spawn"];
}
-(void)resumeGame {
self.isPaused = NO;
[self.pauseMusicPlayer stop];
[self runAction:self.spawnAction withKey:#"spawn"];
self.scoreLabelInGame.position = CGPointMake(self.frame.size.width - 100, self.frame.size.height - 40);
self.actualScore.position = CGPointMake(self.frame.size.width - 20, self.frame.size.height - 40);
[self.mainMusicPlayer play];
[self.restart removeFromParent];
[self.resume removeFromParent];
[self.pausedImage removeFromParent];
[self addChild:self.pause];
}
-(void)gameOver {
NSLog(#"Game Over");
GameDataHelper *gameData = [[GameDataHelper alloc]init];
[self removeActionForKey:#"spawn"];
[self addChild:self.restart];
[self addChild:self.deathImage];
SKAction *gameOverSound = [SKAction playSoundFileNamed:#"gameover_tune.mp3" waitForCompletion:NO];
[self runAction:gameOverSound];
NSString *path = [NSString stringWithFormat:#"%#/menu_music.mp3", [[NSBundle mainBundle]resourcePath]];
NSURL *pauseMusicURL = [NSURL fileURLWithPath:path];
self.pauseMusicPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:pauseMusicURL error:nil];
self.pauseMusicPlayer.numberOfLoops = -1;
[self.pauseMusicPlayer play];
[self.pause removeFromParent];
SKLabelNode *highScore = [SKLabelNode labelNodeWithFontNamed:#"Futura"];
NSString *highScoreText = [NSString stringWithFormat:#"HIGHSCORE: %ld",[GameDataHelper sharedGameData].highScore];
highScore.text = highScoreText;
highScore.fontSize = 25;
highScore.position = CGPointMake(self.frame.size.width/2, self.restart.position.y - (2*self.customUnit));
[self addChild:highScore];
self.scoreLabelInGame.position = CGPointMake(self.restart.position.x, self.resume.position.y - self.customUnit);
self.actualScore.position = CGPointMake(self.restart.position.x, self.scoreLabelInGame.position.y - self.customUnit);
self.isPaused = YES;
[self.mainMusicPlayer pause];
[gameData save];
}
-(void)wentToForeground {
[self pauseGame];
}
In Enemy.m:
-(SKSpriteNode *)createEnemyWithSize:(float)size andWidth:(float)width andHeight:(float)height {
self.enemy = [SKSpriteNode spriteNodeWithImageNamed:#"block.png"];
self.enemy.size = CGSizeMake(size - 5, size - 5);
self.enemy.name = #"fallingEnemy";
self.enemy.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(size - 3, size - 3)];
self.enemy.physicsBody.restitution = 0;
self.enemy.physicsBody.allowsRotation = NO;
int randomSection = arc4random_uniform(7);
switch (randomSection) {
case 0:
self.enemy.position = CGPointMake(2.5 + self.enemy.size.width/2, height-5);
break;
case 1:
self.enemy.position = CGPointMake(width/7 + self.enemy.size.width/2, height-5);
break;
case 2:
self.enemy.position = CGPointMake((width/7*2) + self.enemy.size.width/2, height-5);
break;
case 3:
self.enemy.position = CGPointMake((width/7*3) + self.enemy.size.width/2, height-5);
break;
case 4:
self.enemy.position = CGPointMake((width/7*4) + self.enemy.size.width/2, height-5);
break;
case 5:
self.enemy.position = CGPointMake((width/7*5) + self.enemy.size.width/2, height-5);
break;
case 6:
self.enemy.position = CGPointMake((width/7*6) + self.enemy.size.width/2, height-5);
break;
default:
break;
}
return self.enemy;
}
Even though you might have found the answer already i see some problems with your code:
Note: self.spawnAction needs to be a Strong property so maintain the reference when it's removed.
You are running the action on self.world, but removing it on self.
[self.world runAction:self.spawnAction withKey:#"spawn"];
[self removeActionForKey:#"spawn"];
self.world.paused = YES;
If you set the paused property of self.world to YES you do not need to remove the action as pause will immediately pause all actions.
You do not set the paused property to NO again on -(void)resumeGame
And you run it on self instead of self.world on resume.
Overall I would try to avoid using paused properties which might behave different and not give the results you want.
Also, keep in mind that removing nodes and actions don't happen instantly so if you pause nodes afterwards you might not get expected results.
Also, there is a limited amount of time you have on didEnterBackground to do your stuff before the it actually goes to background.
Hope it helps.

iOS background view not updated using NSTimer while scanning the bluetooth DEVICE

I am trying to work on getting the bluetooth scanning page to pair the BLE device using bluetooth.
I have found the NSUInteger [ _ble.scannedPeripheral count ] do change while scanning. However, when it comes to the execution, the background view images and pages cannot even change. Would you please tell me other wayout make the page change if the variable showing available BLE devices changes from 0 to 1,2 or 3 ?
The below is my code : (Only relevant)
- (void)viewDidAppear:(BOOL)animated
{
if (_ble)
{
_ble.delegate = (id) self;
_ble.btStatus = BT_IDLE;
[_ble startScanning];
}
[NSTimer scheduledTimerWithTimeInterval:0.2f target:self selector:#selector(reloadData) userInfo:nil repeats:YES];
}
-(void) reloadData {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// time consuming workout
dispatch_async(dispatch_get_main_queue(), ^{
// UI update workout for bluetooth scanning
if( [ _ble.scannedPeripheral count ] > 0 ){
[self stopAnimatingImages];
[self setTapDemo : [UIImage imageNamed:#"pairing_d.png"] : #"Pairing" : #"#C4CCCF"] ;
}else{
[self setTapDemo : [self loadingImage] : #"Pairing" : #"#C4CCCF"] ;
[self animateImages];
}
});
});
}
- (void) setTapDemo: (UIImage *) cover : (NSString *) title : (NSString *) colorHex{
image = [UIImage imageNamed:#"shaded_cal.png"];
imageA = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
_container = [[UIView alloc] initWithFrame:[self.view bounds]];
[imageA setImage:cover];
imageA.userInteractionEnabled = YES;
UITapGestureRecognizer *myGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(touchesBegan:)];
myGesture.numberOfTapsRequired = 1;
myGesture.delegate=self;
[imageA addGestureRecognizer:myGesture];
[imageA setContentMode:UIViewContentModeScaleAspectFill];
myLabelQ = [self constructLabelT:title:0.27:0.08: colorHex:25];
myLabelBack =[self constructLabelT:#"BACK":0.04:0.01:#"#C4CCCF":18] ;
if( bleCount > 0){
for(NSUInteger i = 0 ; i < [ _ble.scannedPeripheral count ] ; i ++){
DevicePeriperal *device;
NSString *uuid = [_ble.scannedPeripheralKey objectAtIndex:i];
NSLog (#"device uuid = %#", uuid);
if (uuid)
{
device = [_ble.scannedPeripheral objectForKey:uuid];
NSData * ssx = device.advertdata ;
device.rowIndex = i;
NSLog (#"device advert = %#", ssx);
if([ssx length] > 0){
NSData *macD = [ssx subdataWithRange:NSMakeRange(0, 6)];
NSData *pairD = [ssx subdataWithRange:NSMakeRange(6, 1)];
NSString* newStr = [self hexRepresentationWithSpaces:pairD : NO];
NSString* newMAC = [self hexRepresentationWithSpaces:macD : YES];
NSLog (#"newStr = %#", newStr );
NSLog (#"newMAC = %#", newMAC );
_checkSumByte = [self calculateChecksum:newMAC];
}
NSLog (#"device = %#", device.uuid);
if (device )
{
UIImage *dImage = [UIImage imageNamed:#"device_u.png"];
float change = 0.15*i;
float yPosition = 0.25 + change ;
[imageA addSubview:[self deviceGet:dImage:device.deviceName: 0.40 : yPosition : #"#C4CCCF"]];
}
}
}
//UIImage *dImage = [UIImage imageNamed:#"device_u.png"];
//[imageA addSubview:[self deviceGet:dImage:#"x": 0.40 : 0.25 : #"#C4CCCF"]];
//[imageA addSubview:[self deviceGet:dImage:#"x": 0.40 : 0.40 : #"#C4CCCF"]];
//[imageA addSubview:[self deviceGet:dImage:#"x": 0.40 : 0.55 : #"#C4CCCF"]];
//[imageA addSubview:myLabelS3];
myLabelS1 = [self constructLabelT:#"SPOTTED":0.27:0.723: colorHex:25];
myLabelS2 =[self constructLabelT:#"(choose the one you want to connect)":0.55:0.76:#"#C4CCCF":10] ;
myLabelS3 = [self constructLabelT:#"devices":0.30:0.76: colorHex:25];
}else{
myLabelS1 = [self constructLabelT:#"SCANNING":0.27:0.723: colorHex:25];
myLabelS2 =[self constructLabelT:#"devices":0.51:0.76:#"#C4CCCF":25] ;
myLabelS3 = [self constructLabelT:#"for":0.30:0.76: colorHex:25];
}
[imageA addSubview:myLabelQ];
[imageA addSubview:myLabelBack];
[imageA addSubview:myLabelS1];
[imageA addSubview:myLabelS2];
[imageA addSubview:myLabelS3];
[_container addSubview:imageA];
[self.view addSubview:_container];
[self.view sendSubviewToBack:_container];
}
Each time you call setTapDemo :::, you will create a new _container view and it will be added to self.view . Because you never remove the old one from super view before initialise it again, self.view contains more and more subviews by timer repeats which will finally consume all memory then your app will crash.
Further, [self.view sendSubviewToBack:_container] was called each time while timer was fired, and you never remove your old _container, so any new _container would be hidden behind as result.
In conclusion, I guess you did create updated _container while [ _ble.scannedPeripheral count ] was changed but it was staying behind other subviews. So your may try to modify the code like this:
- (void) setTapDemo: (UIImage *) cover : (NSString *) title : (NSString *) colorHex{
// remove any old _container view
if (_container) [_container removeFromSuperView];
image = [UIImage imageNamed:#"shaded_cal.png"];
imageA = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
_container = [[UIView alloc] initWithFrame:[self.view bounds]];
[imageA setImage:cover];
imageA.userInteractionEnabled = YES;
UITapGestureRecognizer *myGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(touchesBegan:)];
myGesture.numberOfTapsRequired = 1;
myGesture.delegate=self;
[imageA addGestureRecognizer:myGesture];
[imageA setContentMode:UIViewContentModeScaleAspectFill];
myLabelQ = [self constructLabelT:title:0.27:0.08: colorHex:25];
myLabelBack =[self constructLabelT:#"BACK":0.04:0.01:#"#C4CCCF":18] ;
if( bleCount > 0){
for(NSUInteger i = 0 ; i < [ _ble.scannedPeripheral count ] ; i ++){
DevicePeriperal *device;
NSString *uuid = [_ble.scannedPeripheralKey objectAtIndex:i];
NSLog (#"device uuid = %#", uuid);
if (uuid)
{
device = [_ble.scannedPeripheral objectForKey:uuid];
NSData * ssx = device.advertdata ;
device.rowIndex = i;
NSLog (#"device advert = %#", ssx);
if([ssx length] > 0){
NSData *macD = [ssx subdataWithRange:NSMakeRange(0, 6)];
NSData *pairD = [ssx subdataWithRange:NSMakeRange(6, 1)];
NSString* newStr = [self hexRepresentationWithSpaces:pairD : NO];
NSString* newMAC = [self hexRepresentationWithSpaces:macD : YES];
NSLog (#"newStr = %#", newStr );
NSLog (#"newMAC = %#", newMAC );
_checkSumByte = [self calculateChecksum:newMAC];
}
NSLog (#"device = %#", device.uuid);
if (device )
{
UIImage *dImage = [UIImage imageNamed:#"device_u.png"];
float change = 0.15*i;
float yPosition = 0.25 + change ;
[imageA addSubview:[self deviceGet:dImage:device.deviceName: 0.40 : yPosition : #"#C4CCCF"]];
}
}
}
//UIImage *dImage = [UIImage imageNamed:#"device_u.png"];
//[imageA addSubview:[self deviceGet:dImage:#"x": 0.40 : 0.25 : #"#C4CCCF"]];
//[imageA addSubview:[self deviceGet:dImage:#"x": 0.40 : 0.40 : #"#C4CCCF"]];
//[imageA addSubview:[self deviceGet:dImage:#"x": 0.40 : 0.55 : #"#C4CCCF"]];
//[imageA addSubview:myLabelS3];
myLabelS1 = [self constructLabelT:#"SPOTTED":0.27:0.723: colorHex:25];
myLabelS2 =[self constructLabelT:#"(choose the one you want to connect)":0.55:0.76:#"#C4CCCF":10] ;
myLabelS3 = [self constructLabelT:#"devices":0.30:0.76: colorHex:25];
}else{
myLabelS1 = [self constructLabelT:#"SCANNING":0.27:0.723: colorHex:25];
myLabelS2 =[self constructLabelT:#"devices":0.51:0.76:#"#C4CCCF":25] ;
myLabelS3 = [self constructLabelT:#"for":0.30:0.76: colorHex:25];
}
[imageA addSubview:myLabelQ];
[imageA addSubview:myLabelBack];
[imageA addSubview:myLabelS1];
[imageA addSubview:myLabelS2];
[imageA addSubview:myLabelS3];
[_container addSubview:imageA];
//[self.view addSubview:_container];
//[self.view sendSubviewToBack:_container];
// One line of code can do this trick
[self.view insertSubview:_container atIndex:0];
}

How do I use a for loop to display NSArray of UIImage's

Hey guys,
So.... lets say I have an NSArray of images
NSMutableArray *images = [NSMutableArray new];
[images addObject:[UIImage imageNamed:#"line1.png"]];
[images addObject:[UIImage imageNamed:#"line2.png"]];
[images addObject:[UIImage imageNamed:#"line3.png"]];
[images addObject:[UIImage imageNamed:#"line4.png"]];
Now I would like to load all these at once using a for loop but here is the catch.... I need to be able to set the images as hidden until the user unhides through interaction.
for (UIImage *image in images) {
UIImageView *line = [[UIImageView alloc] initWithImage:image];
line.hidden = YES;
[self.view addSubview:line];
}
But then how to I set the hidden BOOL to NO using another method?
As a secondary question, how would one release *line in the code above?
Thanks,
Darren
One option is to set up your images like:
int nextTag = 1;
for (UIImage *image in images) {
UIImageView *line = [[UIImageView alloc] initWithImage:image];
line.hidden = YES;
line.tag = nextTag;
[self.view addSubview:line];
[line release];
nextTag++;
}
...and then to unhide them you can do:
UIView* imageView = [self.view viewWithTag: lineNumber];
imageView.hidden = NO;
...assuming that your user-interaction handler is able to determine what line in the UI the user is interacting with.
As a secondary question, how would one release *line in the code above?
for (UIImage *image in images) {
UIImageView *line = [[UIImageView alloc] initWithImage:image];
line.hidden = YES;
[self.view addSubview:line]; // this retains the subview.
[line release]; // release line like this.
}
**
-(IBAction)btnReviewStar:(id)sender{
for (int i =([sender tag] ==30); i<36; i++) {
btnReviewStar.selected = NO;
btnReviewStar1.selected = NO;
btnReviewStar2.selected = NO;
btnReviewStar3.selected = NO;
btnReviewStar4.selected = NO;
if([sender tag] == 31) {
btnReviewStar.selected = YES;
break;
} else if([sender tag]==32) {
btnReviewStar.selected = YES;
btnReviewStar1.selected = YES;
break;
} else if([sender tag]==33) {
btnReviewStar.selected = YES;
btnReviewStar1.selected = YES;
btnReviewStar2.selected = YES;
break;
} else if([sender tag]==34) {
btnReviewStar.selected = YES;
btnReviewStar1.selected = YES;
btnReviewStar2.selected = YES;
btnReviewStar3.selected = YES;
break;
} else {
btnReviewStar.selected = YES;
btnReviewStar1.selected = YES;
btnReviewStar2.selected = YES;
btnReviewStar3.selected = YES;
btnReviewStar4.selected = YES;
break;
}
}
}
**

Resources