Click Event on UIImageView programmatically - objective-c

I'am displaying a collection of images from code,
This is my code:
UIImageView *addview;
myimgeview *addimageview =[[myimgeview alloc]initWithImage:[UIImage imageNamed:[NSString stringWithFormat:#"%#%d",PhotoName,i]] text:[textArray objectAtIndex:i]];
I want to handle the touch event on the addimageView programmatically.

I would suggest different approach. Add tap gesture recognizer to the imageview. That is probably easiest solutions. If you have addImageView method that adds image view to view then, go on like this,
- (void)addImageView
{
UIImageView * imageView = [[UIImageView alloc] initWithFrame:CGRectMake(10,10,100,100);
imageView.userInteractionEnabled = YES;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self selector:#selector(tapped:)];
[imageView addGestureRecognizer:tap];
}
- (void)tapped:(UITapGestureRecognizer*)tap
{
NSLog(#"%#", tap.view);
}

You have to subclass it and override -touchesBegan: method or you can add gesture recognizer to this object. Here is documentation about that:
Event Handling Guide for iOS
Good way is to subclass this class and add gesture recognizer inside the class.

Related

UIPanGestureRecognizer beyondBounds

I have this code that retrieves the coordinates of an object when it is panned:
UITapGestureRecognizer *moveBuildingTap = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(moveobject:)];
Method moveobject contents:
CGPoint tapPoint=[recognizer locationOfTouch:0 inView:self.view];
I use this to change the frame of - move it -an imageview using these coordinates.
However, upon dragging the image around - triggering the uipangesturerecognizer action, I found that when I drag it to the absolute bottom, I get an error that -[UIPanGestureRecognizer locationOfTouch:inView:]: index (0) beyond bounds (0).
How can I solve this exception and prevent the user from dragging past this point?
Thanks
It's weird that your moveobject: method gets called even though the private touches array of the gesture recognizer seems to be empty.
Anyway, in general, if you don't handle multitouch gestures within gesture recognizer, I would suggest to use [recognizer locationInView:] rather then locationOfTouch:inView:.
Btw:
Your talking about a UIPanGestureRecognizer while in the code you're using a UITapGestureRecognizer.
The code I would recommend to handle dragging of a particular view looks like this:
//...
UIPanGestureRecognizer *panGR = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePan:)];
[someView addGestureRecognizer:panGR];
//...
- (void)handlePan:(UIPanGestureRecognizer *)gr
{
CGPoint translation = [gr translationInView:gr.view];
gr.view.frame = CGRectOffset(gr.view.frame, translation.x, translation.y);
[gr setTranslation:CGPointZero inView:gr.view];
}
You should check the numberOfTouches in your UIGestureRecognizer like:
if (recognizer.numberOfTouches) {
CGPoint tapPoint = [recognizer locationOfTouch:0 inView:self.view];
}

click on the texture area

I'd like to create a function that will be called by clicking on texture object. I've just figured out how the button action is processed. Could you tell me plz how it works. Maybe some special controls have to be correspond to texture object?
thanks in advance )))
I assume this is for iOS and by click you mean tap. The following code will add a gesture recognizer to any UIView:
myView.userInteractionEnabled = YES;
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTap:)];
recognizer.numberOfTapsRequired = 1;
recognizer.numberOfTouchesRequired = 1;
[myView addGestureRecognizer:recognizer];
And implement your handler like this:
- (void)handleTap:(UITapGestureRecognizer *)sender {
if (sender.state == UIGestureRecognizerStateEnded) {
//your code
}
}
The handleTap: method will be called every time your view receives a tap.

Clickable UISlider

I'd like to make my UISlider clickable - to change the value on click to "blank space", e.g. It's set to zero, I click in the middle of the slider and it will "jump" to the middle. Is there any way how to do this?
I want to propose something similar as jrtc27, but without subclassing: add a UI(Tap)GestureRecognizer to the slider.
UISlider *slider = [[[UISlider alloc] init] autorelease];
//configure slider
UITapGestureRecognizer *tapGestureRecognizer = [[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(sliderTapped:)] autorelease];
[slider addGestureRecognizer:tapGestureRecognizer];
- (void)sliderTapped:(UIGestureRecognizer *)gestureRecognizer {
UISlider *slider = (UISlider *) gestureRecognizer.view;
//setValue
}
Subclass it and then alter the -touchesBegan method. If the touch is sufficiently far away, call -setValue:, else call the super implementation (if you want it to always jump, you can just always call -setValue:).

Detecting background tap

I'm busy with an app you need to touch a button, but when u touch outside the button (on the background of the app screen) i want to display an alert.
Does anyone know how to detect an tap on the background
Button:
MyButton = [UIButton buttonWithType:UIButtonTypeCustom];
MyButton.frame = CGRectMake(0, 0, 100, 100);
[MyButton setImage:[UIImage imageNamed:#"tap.png"] forState:nil];
[self.view addSubview:MyButton];
[MyButton addTarget:self action:#selector(buttonPressed) forControlEvents:UIControlEventTouchUpInside];
You could add a gesture recogniser to the view.
E.g.
// in viewDidLoad:
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(backgroundTapped:)];
tapRecognizer.numberOfTapsRequired = 1;
[self.view addGestureRecognizer:tapRecognizer];
- (void)backgroundTapped:(UITapGestureRecognizer*)recognizer {
// display alert
}
What you could also try is having a full size UIView behind the button that has a gesture recogniser on it:
// in viewDidLoad:
UIView *backgroundView = [[UIView alloc] initWithFrame:self.view.bounds];
backgroundView.backgroundColor = [UIColor clearColor];
backgroundView.opaque = NO;
[self.view addSubview:backgroundView];
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(backgroundTapped:)];
tapRecognizer.numberOfTapsRequired = 1;
[backgroundView addGestureRecognizer:tapRecognizer];
- (void)backgroundTapped:(UITapGestureRecognizer*)recognizer {
// display alert
}
This might work better than adding the gesture recogniser to self.view.
You can create a custom subclass of a UIView, make it transparent but with touch handlers, and place a full size instance of that new view subclass underneath your button. You can then have that subview send a message to your main view controller (via delegation) whenever it see a touch down event. Since the button is on top of this subview, the subview won't do anything if the button is tapped.
I looked at the solution in the first answer and tested it. It did not work for me. The gesture recognizer captured my button & other UI element touches (I'm loading from nib)
A window delivers touch events to a gesture recognizer before it delivers
them to the hit-tested view attached to the gesture recognizer. Generally,
if a gesture recognizer analyzes the stream of touches in a multi-touch
sequence and does not recognize its gesture, the view receives the full
complement of touches
I used a slightly different solution:
UIButton *invisibleBtn = [[UIButton alloc] initWithFrame:self.view.bounds];
invisibleBtn.titleLabel.text = #"";
invisibleBtn.backgroundColor = [UIColor clearColor]; // no tap events if this is not set, bizarre
[invisibleBtn addTarget:self action:#selector(backgroundTapped:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:invisibleBtn];
[self.view sendSubviewToBack:invisibleBtn];

Capture dynamic button tap ios

I have button created programmatically in the UIImageView. This view was also created programmatically. When image in this view is tapped the button is created, now I want to capture when this button is tapped but I'm unable to here is my relevant code :
- (void)imageTapped:(UIGestureRecognizer *)sender{
MyImageView *myView = (MyImageView *)sender.view;
NSLog(#"Image tapped is => %#", myView.currentImageName);
//add button to view
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self
action:#selector(pressedPlay:)
forControlEvents:UIControlEventTouchDown];
//button image
UIImage *backgroundImage = [UIImage imageNamed:[NSString stringWithFormat:#"playbutton.png"]];
button.frame = CGRectMake(85.0, 175.0, backgroundImage.size.width, backgroundImage.size.height);
myView.userInteractionEnabled = YES;
button.userInteractionEnabled = YES;
[button setImage:backgroundImage forState:(UIControlStateNormal)];
[myView addSubview:button];
}
Now this code should handle the tap but for some reason it doesn't :
- (void)pressedPlay:(UIGestureRecognizer *)sender{
//MyImageView *senderView = (MyImageView *) sender.view;
NSLog(#"%#", #"I Presed button");
}
Any reason why this is not working?
Your code suggests that you are using a UIGestureRecognizer (most likely a UITapGestureRecognizer) to detect the initial tap. The problem is that UIGestureRecognizer is being greedy and stopping the UIButton from receiving the touch.
You will need to do some shifting to disable the gesture recognizer after the initial detection and then reenable it after the play has been tapped.
UIGestureRecognizer has the property
#property(nonatomic, getter=isEnabled) BOOL enabled
or you can choose to implement UIGestureRecognizerDelegate and provide an implementation of
gestureRecognizer:shouldReceiveTouch:
a very simple attempt could look like:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;
{
return ![touch.view isKindOfClass:[UIButton class]];
}
and don't forget to set the delegate on the gesture recognizer
myGesture.delegate = self;
set the button frame from:
button.frame = CGRectMake(85.0, 175.0, backgroundImage.size.width, backgroundImage.size.height);
to:
button.frame = CGRectMake(0,0, backgroundImage.size.width, backgroundImage.size.height);
it looks like you are setting button frame outside the imageview's frame and hence the button is not actually getting any interaction.
The Button frame is likely setting the button outside the bounds of the UIImageView, frames are always relative to the superviews coordinate in this case the UIImageView.
[button setExclusiveTouch:YES];