calling a method in IBAction method - objective-c

Im trying to create a program that when i tap the screen, alert will popup..
So I change the UIView to UIControl, and create an IBAction method When tap the screen, Then i found a method on the internet the print the tap location.
this is my code:
-(IBAction) Touch:(id)sender{
[self touchesBegan];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *myTouch = [[touches allObjects] objectAtIndex: 0];
CGPoint currentPos = [myTouch locationInView: self];
NSLog(#"Point in myView: (%f,%f)", currentPos.x, currentPos.y);
}
and its give's me an error...
What to do?!?!

remove [self touchesBegan] from your "Touch" method
you are
1. calling this method without the necessary parameters, so you are
probably getting unrecognized selector sent to instance,
2. the uiview calls this method on its own, you just need to override it

Related

Is there any way to the get object that was tapped on in Objective C?

I've read the apple docs on the responder chain and needed to know: How is it do i NSLog the object that was tapped on?
Let's say I have a very complex view controller with multiple views object, when ever i tap on an object (UIButton or what ever..) is there a way to know that particular object that was tapped on?
The docs gave a good overview, but wasnt to clear in methods to overwrite.
EDIT:
The situation is in testing different apps i have not written. I need a quick way to determine the Object that was tapped on (as many apps have custom controls/object that looks like one thing, but is really another). I was hoping there was some way to intercept the touch event right as it was being sent to UIAppication, and then NSLog it.
You can override -[UIApplication sendAction:to:from:forEvent] to do what you want:
#implementation MyApplicationSubclass
- (BOOL)sendAction:(SEL)action to:(id)target from:(id)sender forEvent:(UIEvent *)event
{
NSLog(#"Sending action %# from sender %# to target %# for event %#", NSStringFromSelector(action), sender, target, event);
return [super sendAction:action to:target from:sender forEvent:event];
}
#end
Put that in a custom subclass of UIApplication. Then, in main.m, change the call to UIApplicationMain() so that your custom subclass is used:
int main(int argc, char *argv[])
{
#autoreleasepool {
return UIApplicationMain(argc, argv, NSStringFromClass([MyApplicationSubclass class]), NSStringFromClass([AppDelegate class]));
}
}
Note that this only works for UIControl subclasses, which send their actions to their targets using this mechanism. If you want to see all touch events going through an app, override -[UIApplication sendEvent:] instead. In that case, it will be up to you to figure out which object is going to receive the touch. You can do that with by calling -hitTest: on your main view/window, though keep in mind that that figures out which view the touch lands on, not necessarily which view handles it (views can forward events to other objects, for example). Something like this:
#implementation MyApplicationSubclass
- (void)sendEvent:(UIEvent *)event
{
UIWindow *window = [self keyWindow];
NSSet *touches = [event touchesForWindow:window];
for (UITouch *touch in touches) {
UIView *touchedView = [window hitTest:[touch locationInView:window] withEvent:event];
NSLog(#"Touch %# received in view %# for event %#", touch, touchedView, event);
}
[super sendEvent:event];
}
#end
For a button the action method normally has that param,
- (void)action:(id)sender {
Here sender represents the button. You can use it as,
UIButton *button = (UIButton *)sender;
button.hidden = YES;//use the properties of button now
You can also check with the UITouch delegate methods.
For eg:-
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *myTouch = [[event allTouches] anyObject];// or UITouch *touch = [touches anyObject];
CGPoint point = [myTouch locationInView:myViewToCheck];
if (CGRectContainsPoint(myViewToCheck.bounds, point) ) {
//Touch detected on myViewToCheck.
}
Have you had a chance to look at https://github.com/domesticcatsoftware/DCIntrospect.
Straight from github: Introspect is small set of tools for iOS that aid in debugging user interfaces built with UIKit.
It has a logging component that may be of use?

Hiding Keyboard in xcode storyboard

New to xcode,i'm creating a simple login form in xcode 4.2 and i would like to hide the keyboard,i have the correct code i think,from the tutorial it says i need to change the class of the view to UIControl but there is no option for this, is there another way when working with storyboards?
- (IBAction)backGroundTouched:(id)sender
{
[emailTextField resignFirstResponder];
[passTextField resignFirstResponder];
}
Assuming you are doing them inside the viewCotroller, invoke
[self.view endEditing:YES];
If your two text fields are subviews of some higher-level view you can also use [higherLevelView endEditing]; and not care which subview is currently active.
Make sure your both text fields is connect with it's IBOutlets.
No need to change UIView to UIControl.
// Connect every textfield's "Did end on exit" event with this method.
-(IBAction)textFieldReturn:(id)sender
{
[sender resignFirstResponder];
}
// Use this method also if you want to hide keyboard when user touch in background
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[emailTextField resignFirstResponder];
[passTextField resignFirstResponder];
}
I followed this tutorial: http://www.techotopia.com/index.php/Writing_iOS_7_Code_to_Hide_the_Keyboard and it's working for me:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
if ([_textField isFirstResponder] && [touch view] != _textField) {
[_textField resignFirstResponder];
}
[super touchesBegan:touches withEvent:event];
}

Can I detect if user has touched anywhere except from Annotation, on the map?

I am building an app and I would like to know when user has touched an annotation or anywhere else on the map. I have a button that I would like to display only if an Annotation has been selected. So, if user after annotation try to touch anywhere on the map (if is not another annotation) then make button invisible.
At the moment, I have tried the touchesEnded method but the problem is that it does not recognises annotations and land.
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
if([touches isMemberOfClass:[BuildingViewController class]])
printf("Building");
else
printf("Land!");
}
Thanks in advance.
touches is object with class NSSet, so you can get object from NSSet and check it`s class membership. For example:
UITouch *touch = [touches anyObject];
You can get UIView from touch
UIView *touchedView = touch.view;
Then check this UIView class and compare it with yours
[touchedView isMemberOfClass:[BuildingView class]]
Also I advice you to check all touches in that NSSet.
BOOL isBuilding = NO;
for(UITouch *touch in touches){
if([touch.view isMemberOfClass:[BuildingView class]]){
isBuilding = YES;
break;
}
}
if(isBuilding){
printf("Building");
}else{
printf("Land!");
}

Why won't my Cocos2d test app fire "touchesBegan" events?

In my app delegate, I made sure I have the line:
[glView setMultipleTouchEnabled: YES];
And I have a simple layer meant only to figure out how multi touch works. The .mm file looks like:
#import "TestLayer.h"
#implementation TestLayer
-(id) init
{
if( (self=[super init])) {
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
}
return self;
}
-(void) draw{
[super draw];
glColor4f(1.0, 0.0, 0.0, 0.35);
glLineWidth(6.0f);
ccDrawCircle(ccp(500,500), 250,CC_DEGREES_TO_RADIANS(360), 60,YES);
}
-(void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"got some touches");
}
-(void) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"some touches moved.");
}
-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
NSLog(#"a touch began");
return FALSE;
}
#end
When I touch the screen, I always see "a touch began", but no matter how I touch it (simulator or actual device), I never see "some touches moved" or "got some touches".
Is there something further I need to do to make multi touch work?
Specifically, I'm just trying to do basic pinch-to-zoom functionality... I heard there is some sort of gesture recognizer for iPhone...does it work for Coco2ds? Would it work even if I can't get simple multi touch events to fire?
UIGestureRecognizers absolutely work for Cocos2D, I personally used them, you just need to add them to the correct view by using:
[[[CCDirector sharedDirector] openGLView] addGestureRecognizer:myGestureRecognizer];
Regarding your touches, I guess you enabled them for the scene you are working in?
scene.isTouchEnabled = YES;
In any case you shouldn't use the addTargetDelegate method, take a look here
add self.isTouchEnabled = YES; to your init
and for the gesture recognizers look at the other answer

touchesBegan not responding

-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#" touches ");
}
The above method is not calling in my apps. My application description is as under.
I have a MainViewController which loads a ContentViewController in it. ContentViewController has a webview which loads a pdf file.
How to listen the tap of MainViewController's View.
Regards.
I may be not 100% accurate here, but if you place -touchesBegan:withEvent: in your view controller (or its main view) then you will get only those touches that have not been handled by some subviews in the view hierarchy. To intercept all touches you should use UIView subclass for your controller view and override hitTest:withEvent: method in it:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
touchedView = [super hitTest:point withEvent:event];
NSSet* touches = [event allTouches];
// handle touches if you need
return touchedView;
}
For more information see Event delivery section in "Event handling guide" for iOS