Shake gesture and firstResponder - objective-c

I'm trying to get shake gesture to work. Here is some code
In my implementation file
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
if(event.type == UIEventSubtypeMotionShake)
{
NSLog(#"Shake gesture detected");
}
}
- (BOOL)canBecomeFirstResponder
{
return YES;
}
I read that in order to make shake gesture to work UIView should be the firstResponder. This is why I added that code in implementation
if(self.view.isFirstResponder)
{
NSLog(#"first");
}
else
{
NSLog(#"no");
}
- (void)viewDidAppear {
[self becomeFirstResponder];
}
When I run the app the output of NSLog is NO. What I miss ? And how to get shake gesture to work

I guess you're doing this in your UIViewController? That's not correct … You have to subclass UIView like this:
ShakeView.h:
//
// ShakeView.h
//
#import <UIKit/UIKit.h>
#interface ShakeView : UIView {
}
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event;
- (BOOL)canBecomeFirstResponder;
#end
ShakeView.m:
//
// ShakeView.m
//
#import "ShakeView.h"
#implementation ShakeView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
}
return self;
}
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
if ( event.subtype == UIEventSubtypeMotionShake ) {
}
if ( [super respondsToSelector:#selector(motionEnded:withEvent:)] ) {
[super motionEnded:motion withEvent:event];
}
}
- (BOOL)canBecomeFirstResponder
{
return YES;
}
#end
Then use ShakeView instead of your "normal" UIView and implement this in your UIViewController:
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
NSLog(#"Shake happend …");
}
- (void)viewDidAppear:(BOOL)animated
{
[self.view becomeFirstResponder];
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[self.view resignFirstResponder];
[super viewWillDisappear:animated];
}
That's it. Hope it helps :)

Related

Perform SpriteKit Physics Body Collision/ Contact on touch End

I am having some physics body nodes. Sprite Kit immediately calls didbegincontact method. I want that method should be called when i release the touch so that it may perform actions when click was released instead of calling method immediately causing some action setting problems for me.
- (void)didBeginContact:(SKPhysicsContact *)contact
{ NSLog(#"%hhd", _touching);
if(_touching == NO)
return;
something here
}
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
_touching = YES;
NSLog(#"%hhd", _touching);
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
_touching = NO;
NSLog(#"%hhd", _touching);
something here
}
Set the global Variable, ie
BOOL _touching;
When you touch / release (touches ended and began) you set that var to YES / NO;
In the didbegincontact, use something like
if(_touching == YES) {
// what I want to happen when I am touching
}
else {
// i must not be touching so do this
}
Here is the basic set up - however I think its the game logic thats the issue, maybe think of a different way to solve your problem
#interface XBLMyScene()
#property (strong, nonatomic) SKNode *world;
#property (strong, nonatomic) SKSpriteNode *ball;
#property BOOL touching;
#end
#implementation XBLMyScene
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
self.world = [SKNode node];
[self addChild:self.world];
self.backgroundColor = [SKColor colorWithRed:0.15 green:0.15 blue:0.3 alpha:1.0];
self.physicsBody = [SKPhysicsBody bodyWithEdgeFromPoint:CGPointZero toPoint:CGPointMake(500, 0)];
self.ball = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(40, 40)];
self.ball.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(40, 40)];
self.ball.position = CGPointMake(200, 300);
[self.world addChild:self.ball];
self.touching = NO;
}
return self;
}
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
self.touching = YES;
}
-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
self.touching = NO;
}
- (void) didSimulatePhysics
{
if (self.touching) {
NSLog(#"I am touching");
}
else {
NSLog(#"I am not touching");
}
}

Removing UIImageView On Touch

I'm working on a project where images are spawned and you basically touch them and they are removed. How would I removed the object that I touched? I've thought of making a mutablearray to hold all the objects but i can't seem to figure anything out.
GameViewController.m
#import "GameViewController.h"
#import "Cig.h"
#interface GameViewController ()
#end
#implementation GameViewController
#synthesize scoreLbl, timeLbl;
//CLASS ONLY VARS
BOOL isGameOver;
int timeInt;
int scoreInt;
int cigsOnScreen;
NSMutableArray *spawnedCigs;
//CLASS ONLY VARS
//TIMER
-(void)count {
timeInt--;
timeLbl.text = [NSString stringWithFormat:#"Time: %i", timeInt];
if(timeInt == 0){
isGameOver = YES;
NSLog(#"Your Score For This Round: %i", scoreInt);
}
if(isGameOver == NO){
[self performSelector:#selector(count) withObject:nil afterDelay:1];
}
}
//TIMER
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
-(void)spawnCigs {
for(int i =0 ; i < 5; i++){
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(arc4random()%760, arc4random()%430, 100, 23)];
UIImage *image = [UIImage imageNamed:#"Cig.png"];
[imageView setImage:image];
Cig *cig = [[Cig alloc] init];
[cig setTag:arc4random()%666];
[cig setImage:imageView];
[spawnedCigs addObject:cig];
[self.view addSubview:imageView];
}
[self performSelector:#selector(spawnCigs) withObject:nil afterDelay:5];
}
-(void)reset {
scoreLbl.text = #"Score:";
timeLbl.text = #"Time:";
isGameOver = NO;
timeInt = 60;
scoreInt = 0;
cigsOnScreen = 0;
spawnedCigs = [NSMutableArray arrayWithObjects:nil, nil];
[self performSelector:#selector(count) withObject:nil afterDelay:1];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self reset];
[self spawnCigs];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Code is pretty messy so please don't judge me on that.
Thanks for any help that is provided
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch=[[event allTouches]anyObject];
CGPoint touchPoint = [touch locationInView:touch.view];;
for (UIView *view in [self.view subviews])
{
if([view isMemberOfClass:[UIImageView class]])
{
if (CGRectContainsPoint(view.frame,touchPoint))
{
[view removeFromSuperview];
}
}
}
}
this helps you
use
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
for (UIImageView *view in [self.view subviews])
{
if (view.tag==1)
{
[view removeFromSuperview];
}
if (view.tag==2)
{
[view removeFromSuperview];
}
}
}
try this your issue will be resolved. Don't forget to pass tab to your imageviews...
By using
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
method you will get the image view of selected image. simply remove the object from superview.

SubClassing UIButton but I can't get "addTarget:action:forControlEvents:" to execute?

I have subclassed UIButton to draw graphics, but the "addTarget" won't work.
- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents
I did not do anything with making adjustments to that method.
The Button graphics work ok on the "touches".
If I use a standard UIButton then the "addTarget" works fine.
Not sure what I am missing??
thx
#import <UIKit/UIKit.h>
#interface CButton : UIButton
{
CGContextRef c;
int myState;
}
#end
#import "CButton.h"
#implementation CButton
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
//NSLog(#"init state: %d", self.state);
return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
// myState = 1;
myState = !myState;
// NSLog(#"BeginState: %d", self.state);
[self setNeedsDisplay];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
// myState = 0;
// NSLog(#"EndState: %d", self.state);
// [self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
#end
You have to call super from your event handlers when you're all done handling events. How else will the button know of the touches to call your action?
e.g.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
// myState = 1;
myState = !myState;
// NSLog(#"BeginState: %d", self.state);
[self setNeedsDisplay];
[super touchesBegan:touches withEvent:event]; // you need this
}
That being said, the comments on your original post are right, subclassing UIButton can get tricky. But it looks as if you have things under control (mostly). Good luck!

NSView mouseExited

I have an NSView and basically, even when my mouse doesn't leave the defined frame, just moves within it, mouseExited function is called. Is this how is it suppose to be or am I doing something wrong? There are several subviews of this NSView and it's custom and here's the code for it:
- (id)initWithDelegate:(id)del {
if (self = [super init]) {
[del retain];
delegate = del;
}
return self;
}
- (void)dealloc {
[delegate release];
[super dealloc];
}
- (void)viewDidMoveToWindow {
[self addTrackingRect:[self bounds]
owner:self
userData:nil
assumeInside:NO];
}
- (void)mouseEntered:(NSEvent *)theEvent {
[delegate mouseEntered];
}
- (void)mouseExited:(NSEvent *)theEvent {
NSLog(#"mouse exited");
[delegate mouseExited];
}
- (void)mouseDown:(NSEvent *)theEvent {
[delegate mouseDown];
}
- (NSView *)hitTest:(NSPoint)aPoint {
return self;
}
Thanks.
I figuered it out. After adding a tracking area, i was changing the frame of my view so I needed to recalculate the tracking area. Found this method that will automatically be called whenever tracking area needs to be updated:
- (void)updateTrackingAreas {
Just simply recalculate your tracking area here.

Objective C: Detecting a shake

I'm using the shake api like this:
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
if (event.subtype == UIEventSubtypeMotionShake)
{
[img stopAnimating];
}
}
How do I detect that the shaking has stopped?
You are on the right track, however, there are still more things you need to add to detect shaking:
You can test this by adding an NSLog to the motionBegan or motionEnded methods, and in the Simulator, press CONTROL + COMMAND + Z
#pragma mark - Shake Functions
-(BOOL)canBecomeFirstResponder {
return YES;
}
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:NO];
[self becomeFirstResponder];
}
-(void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:NO];
}
-(void)viewDidDisappear:(BOOL)animated {
[self resignFirstResponder];
[super viewDidDisappear:NO];
}
-(void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
if (motion == UIEventSubtypeMotionShake )
{
// shaking has began.
}
}
-(void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
if (motion == UIEventSubtypeMotionShake )
{
// shaking has ended
}
}