How to get the id of button & implementing touchesMoved Simultaneously? - iphone

I have a situation i have a UIButton Class in which upon selecting a button i am getting the id of the buttton based upon it i am changing the color of the button by using [self addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
And by using touchesBegan, touchesMoved, touchesEnded method i can drag drop the button object to any part of screen.
Now the problem is if i uses touchesBegan, touchesMoved, touchesEnded method then i am not getting id of button so i am not able to change the color.
So how can i able to get both the problem solved?

one of the parameters for touchesBegan is a set of UITouch objects. UITouch has property "view", which is the view that you tapped on. So something like
-(void)touchesBegan:touches withEvent:e
{
id* myButton = [touches anyObject].view;
}

If you call the following method on your parent view (containing all the buttons) in touchesBegan: it should return you the button you are touching....
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
Hope this helps.

Related

Disable touch events on certain areas of iPhone screen

I want to disable touches on all areas of the screen apart from a specific few points (e.g buttons). I.e. I don't want 'touchesBegan' to trigger at all when I tap anything other than a button. Calling
self.view.userInteractionEnabled = NO;
has the desired effect for not registering touches, but then of course I can't tap any buttons. I basically want the button to still work, even if there are 5 points touching the screen, i.e. all touch inputs have been used up, and the button represents the 6th.
Is this possible?
I've tried inserting a view with userInteraction disabled below my buttons, but it still registers touches when the user taps the screen. It seems the only way to disable touch registering is to do so on the entire screen (on the parent UIView).
UPDATE:
I've tried using gesture recognizers to handle all touch events, and ignore those that don't qualify. Here is my code:
#interface ViewController : UIViewController <UIGestureRecognizerDelegate>
...
- (void)viewDidLoad
{
[super viewDidLoad];
UIGestureRecognizer *allRecognizer = [[UIGestureRecognizer alloc] initWithTarget:self action:nil];
allRecognizer.delegate = self;
[self.view addGestureRecognizer:allRecognizer];
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
CGPoint coords = [touch locationInView:self.view];
NSLog(#"Coords: %g, %g", coords.x, coords.y);
if (coords.y < 200) {
[self ignoreTouch:touch forEvent:nil];
return TRUE;
}
return FALSE;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(#"%i touch(es)", [touches count]);
}
However the screen still 'reads' the touches, so if I place 5 fingers down, the 6th one won't trigger a button press...
You need to set up an invisible UIButton and lay it between the view that should not register touches and the UIButtons that should still be active.
Now you need to set the invisible button's 'userInteractionEnabled':
//userInteractionEnabled == NO => self.view registeres touches
//userInteractionEnabled == YES => self.view doesn't register touches
[_invisibleButton setUserInteractionEnabled:NO];
What really matters in this solution is that both - the invisible and the visible buttons are direct subviews of the VC's view.
You can download an example project from my dropbox:
https://dl.dropboxusercontent.com/u/99449487/DontTapThat.zip
However this example just prevents the handling of certain touches. Completly ignoring input isn't technically possible: Third party apps are not responsible for for detecting input. They are just responsible for handling input. The detection of touch input is done iOS.
The only way to build up a case like you describe it in the comments is to hope that iOS won't interpret the input of your case as a "finger" because it's most likely going to cover an area that's way bigger than a finger.
So in conclusion the best way would be to change the material of the case you're about to build or at least give it a non conductive coating. From a third party developers point of view there is no way to achieve your goals with software if there is a need for 5 fingers as described in the comments.
There is couple of methods in UIView that you can override:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event; // recursively calls -pointInside:withEvent:. point is in the receiver's coordinate system
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event; // default returns YES if point is in bounds
This should prevent to call touchBegin and other methods.
Regards.
I have a nice solution for this. What ever the area you want to hide the interaction place a transparent button on top of the area.
touchesBegan is a default method so it must call all the time when touch happens on view so there is no way-out, But you can still do one thing set
self.buttonPlayMusic.userInteractionEnabled = FALSE;
for the object you don't need touch may be this could be help you with your desired output.
Have you tried using a UIScrollView as the background ? i.e the area where you do not want touch events to be fired.
UIScrollView does not call the touch methods.
You can add UIImageView Control on that area where you want to disable touch event.you can add UIImageView object as top of self.view subViews.
Example
//area -- is that area where you want to disable touch on self.view
UIImageView *imageView=[[UIImageView alloc]initWithFrame:area];
[self.view addSubView:imageView];
You touchDelegate will always call in this way, but if you are doing some task on touch then you can do your task like this way.
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
UIButton *touchObject=(UIButton*)[touch view];
if ([touchObject isKindOfClass:[UIButton class]])
{
//Do what ever you want on button touch
}
else{
return;
}
}

Tapping on Buttons over MapView is zooming the Map..?

I have a MapView, Over which i have added a UIView (0, 216, 320, 200) contain 10 UIButtons. This UIView is to work like a menu, and Shows and Hides on a certain button action.
The problem here is, While the Menu is showing, when i tap a button single ime, it works perfectly, but tapping it very quickly multiple times makes the MapView Zoom(Which is under the UIView which contain the button). It means the touch event is passing to MapView.
Detail: Tapping on the button very quickly cause in MapView Zoom, and the Button Action performs when you stop tapping.
How can i prevent that?
What you could do is disable user interaction for the duration of your button's handler. So in the selector do:
-(void)buttonSelector:(id)sender {
_mapView.userInteractionEnabled = NO;
// ... do what your button needs to do
_mapView.view.userInteractionEnabled = YES;
}
Of course, this assumes your button gets the event before the map view... which I think it should because it's on top of the map view.
To handle the rapid tapping, you could create a subclass of UIButton and use the following code:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
_mapView.userInteractionEnabled = NO;
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
_mapView.userInteractionEnabled = YES;
}
In the builder change the class of the UIButton to your subclass. If you debug the touch in the set passed to the touchesEnd method and look at the tapCount, you'll see all your taps have been caught here.
Yes, so the problem was, I was adding UIView as subview over MapView.. I fixed it by adding the UIView as subview on self.view

How to perform some Action on imageview clicked?

I'm working on a photo Collage application. I want to perform an action on image view so any one can help me to solve my problem. when i pick image from photo library and shown on image view after when double click on image view i want to push or present a new view to crop this image .....so anyone tell me what i do to solve my problem...
Use a UIButton of type custom and put an image inside it. And you are done.
Add the Gesture for ImageView
UITapGestureRecognizer *sg=[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(HandleEvent)];
sg.numberOfTapsRequired=2;
[BottomBar addGestureRecognizer:sg];
[sg release];
and do your task here:
-(void)HandleEvent
{
// your task
}
Thanks
You should use a UIButton instead of an UIImageView. You can set its style to custom and then asign it an image. UIButton provides all the methods for double tap already built in.
If you are using UIImageView, make sure you use setUserInteractionEnabled:YES. Then you need to check your touches in touchesBegan, ended, (canceled).
You are set on using UIImageView, you will have to subclass UIImageView and override the touch methods you want to intercept. For example:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
// Call super to make sure you don't lose any functionality
[super touchesBegan:touches withEvent:event];
// Perform the actions you want to perform with the tap.
}
Using UIButtons as replacements for your UIImageViews is a great idea you can just drag a connection from each button to an outlet in your view controller and handle the action. You can set the background image on the buttons as you are doing currently with the UIImageViews. Set your button type to custom and you'll be good to g
If you are using UIImageView class ,first set setUserInteractionEnabled:YES . Then set UITapGestureRecognizer event to image view.
try this
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint locationPoint = [[touches anyObject] locationInView:self.view];
CGPoint viewPoint = [imageView convertPoint:locationPoint fromView:self.view];
if ([imageView pointInside:viewPoint withEvent:event]) {
//do something
}
}
Make a button, and clear its color. On the back of button, put your image view, so that your imageview seems to be visible and the button doesn't. Now attach event to the button.

How to drag and drop a UIButton

I have four UIButtons in my interface file. I have outlets attached to each button. I want to be able to drag and drop them across the screen. What is the best way to do this? How can I do this? please help!!!
try this u can drag and drop your button what ever you want
implement this code in ViewDidLoad
[self.shoeimageOutlet addTarget:self action:#selector(imageMoved:withEvent:) forControlEvents:UIControlEventTouchDragInside];
[self.shoeimageOutlet addTarget:self action:#selector(imageMoved:withEvent:) forControlEvents:UIControlEventTouchDragOutside];
it will call the method written below
- (IBAction) imageMoved:(id) sender withEvent:(UIEvent *) event
{
CGPoint point = [[[event allTouches] anyObject] locationInView:self.view];
UIControl *control = sender;
control.center = point;
}
There are 3 possibilities nowadays on how to enable items – that is UIViews and UIControls – to be draggable.
override touchesMoved
add a target/selector for dragging control events
add a pan gesture recognizer
The complete tutorial found here !!!

How do I handle event when user touch up outside the UIView?

I have a custom popup menu in my iOS application. It is UIView with buttons on it. How do I handle event when user touch up outside this view? I want to hide menu at this moment.
You should create a custom UIButton that takes up the whole screen. Then add your subview on top of that button. Then when the user taps outside of the subview they will be tapping the button.
For example, make the button like this:
UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self action:#selector(yourhidemethod:) forControlEvents:UIControlEventTouchUpInside];
[button setTitle:#"" forState:UIControlStateNormal];
button.frame = self.view.frame;
[self.view addSubview:button];
(where yourhidemethod: is the name of the method that removes your subview.) Then add your subview on top of it.
Update: It looks like you're wanting to know how to detect where touches are in a view. Here's what you do:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint touchPoint = [touch locationInView:self]; //location is relative to the current view
// do something with the touched point
}
Put it in full-screen transparent view and handle touches for it.
One idea is to have an invisible view(uicontrol) that is as big as the screen which then holds this custom popup.
It sounds like you'd be better served by deriving your menu from UIControl rather than UIView. That would simplify the touch handling, and all you'd have to do in this case would be to set a target and action for UIControlEventTouchUpOutside. The target could be the menu itself, and the action would hide or dismiss the menu.