I have looked at UIButton can't be touched while animated with UIView animateWithDuration and the answer doesn't help me.
for (UIButton *button in self.buttonsOutletCollection)
This part is the one that is confusing. My button isn't part of a IBOutletCollection so this doesn't work. I use this to move the button:
- (void) squareOneMover {
CGRect oldFrame = _squareOne.frame;
[UIView animateWithDuration:2
delay:0.0
options:UIViewAnimationOptionAllowUserInteraction
animations:^{
CGRect newFrame = CGRectMake(oldFrame.origin.x , oldFrame.origin.y + 500, oldFrame.size.width, oldFrame.size.height);
_squareOne.frame = newFrame;
}
completion:nil
];
}
I don't want to have to move the Button in small amounts because I need five buttons and it would be inefficient.
Can someone provide me with an answer similar to the question above that is for UIButtons not include in any array?
Edit:
The UIButton is defined in the interface file and connected to Interface Builder, and is strong and nonamatic
Edit 2: I am now using animateWithDuration:delay:options:animations:completion: but it still doesn't work.
I use this code to detect if the button is being pressed.
- (void)squareOnePressed:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInView:self.view];
if ([self.squareOne.layer.presentationLayer hitTest:touchLocation])
{
NSLog(#"YO");
}
}
But when the button is pressed nothing still happens... So how do I program that ^^^^
Try calling animateWithDuration:delay:options:animations:completion: with UIViewAnimationOptionAllowUserInteraction in the options parameter.
Add an IBAction to your view controller and connect your button to that. Put your NSLog in the IBAction method. (Do you know how to do this?)
Why is your method named squareOneTouched:? Is your IBAction triggering that?
If you're subclassing a UIViewController, you should just override the touchesBegan: method.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInView:self.view];
if ([self.squareOne.layer.presentationLayer hitTest:touchLocation])
{
// This button was hit whilst moving - do something with it here
NSLog(#"YO");
}
}
I found the problem. The constraints are preventing me from interacting with the button. When I remove the programmatically written constraints from the button, it works fine.
Related
I have subclass of UIView
#interface TBL_CardView : UIView
It it internally have UIImageView for card image.
I need to handle touching of card in following way:
When I touch (and still hold) TBL_CardView I need to set orange borderColor.
If I am stil on top of TBL_CardView I need to set red borderColor.
If I am not on top of TBL_CardView, I have moved my finger, because I want to cancel touch, then borderColor is removed.
I know how to handle setting of borderColor:
self.layer.borderColor = [UIColor redColor].CGColor;
self.layer.borderWidth = 3.0f;
But I do not know what is the easiest way to implement thin button like behavior ?
Should I make it just as button, or use UIResponder or something else ?
What are pros and cons for each case ?
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"%s", __PRETTY_FUNCTION__);
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInView: self];
BOOL isInside = [self pointInside: touchLocation withEvent: event];
if (isInside)
{
//if logic
NSLog(#"INSIDE");
}
else
{
//else logic
NSLog(#"OUTSIDE");
}
}
You could check out this post for information on how to implement button-like behaviour and respond to touches on a UIView or a subclass.
Touch Event on UIView
What I usually do myself, however, is put a transparent (clear color and no title, not alpha = 0.0) UIButton on top of my UIView matching it s size and responding to the events I need instead. Check if it fits your needs.
I'm working on an iOS app.
I have a UIView that is being animated. It keeps moving from left to right.
This view has several UIView children. They move within their parent when this is being animated.
When I try to capture user touches on the children (by using a UITapGestureRecognizer), it doens't work as expected. It sort of detect some touches on the children, but not in the position where they currently are.
I've been struggling with this for a while now. Any ideas about how to solve this? I really need to detect which children the user is touching.
Thanks!
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInView:self];
// Check every child subview
for (UIView *tickerItem in self.subviews)
{
// Check collision
if ([tickerItem.layer.presentationLayer hitTest:touchLocation])
{
MKTickerItemView *v = (MKTickerItemView*)tickerItem;
NSLog(#"Selected: %#", v.title);
// This button was hit whilst moving - do something with it here
break;
}
}
}
There is a UIViewAnimationOptions value...
UIViewAnimationOptionAllowUserInteraction
You can use this in the [UIView animateWithDuration... code.
This will enable the touch.
I am using the code below to try and get the location of a touch but it only works outside of the button. Eg. it prints the console line if the touch is outside the button but if not, it doesn't work. What is solution to this?
Here is the code:
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint touchPoint = [touch locationInView:self.appleClickedButton];
NSLog(#"%f",touchPoint);
NSLog(#"%f",touchPoint);
}
Thanks
Here's how you can get touch location when a UIButton is tapped. (just make sure you link TouchUpInside event with the IBAction)
- (IBAction)buttonTapped:(id)sender forEvent:(UIEvent*)event
{
UIView *button = (UIView *)sender;
UITouch *touch = [[event touchesForView:button] someObject];
CGPoint touchPointInButton = [touch locationInView:button];
NSLog(#"Location in button: %f, %f", touchPointInButton.x, touchPointInButton.y);
}
Once you get the touch point inside the button, you can calculate what the touch point would be in the super view.
When you touch inside the button. the event has been handled by the button. The view which contains the button will not get the touch event.
You can create a custom class inherit from the UIButton and override the method, but please make sure to call the the method in the super class or some actions such as TouchUpInside will not work correctly.
You could try UIButtons addTarget:action:forControlEvents: with a control event mask including UIControlEventTouchUpInside.
Just like the title ,when I touch the UIView I want the touch point to be glow, I came up with a idea that to show a glow image on the touch point ,but if by code?any example or idea?thanks for sharing!!
You can try touchesBegan event below Code:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if([touch view] ==self.my_view)//Check click your uiview or not
{
CGRect frame = [your_image_view frame];
CGPoint touchLocation = [touch locationInView:touch.view];
frame.origin.x=touchLocation.x;
frame.origin.y=touchLocation.y;
[your_image_view setFrame:frame];
[self.my_view addSubview:your_image_view];
}
}
Thanks..!
Well the first step would be to detect the touch on your UIView for that I would recommend using the high level API UIGestureRecognizer andd add to your view. Then you can use the call back to do whatever you want, perhaps some sort of animation?. If so you can use an animation block to animate your changes.
I'm not quite sure how to start explaining this, but I'll try.
I started reading iOS books awhile ago, and I'm trying to get a handle on Objective-C. I think I have an ok understanding of it.
What I'm doing in iOS is making a simple game that involves dragging numbers into a box, which the app then grabs the number that was dragged into the box. However, I have no idea how I do this.
I was wondering if you guys have any links/articles on something like this, if I should use a certain framework for this, or maybe even some example code.
Thanks for any answers.
do a search on 'cocos2d drag' ... also, here is an article that might help you get started.
This is a pretty general question with huge scope, but a simple approach could be to create a custom UIView subclass for each draggable number that handles the drawing. In a view controller you can create all of these custom UIViews and create a UILongPressGestureRecognizer for each one, with the allowableMovement property set to CGFLOAT_MAX, or some large number. Attach the recognizer to each draggable view with the action method some callback in the view controller.
Then, in the view controller gesture recognizer action method, you can just update the views center property to the gesture recognizers location in the view controllers view. Something like:
- (void)handleLongPressGesture:(UIGestureRecognizer *)recognizer
{
if ([recognizer state] == UIGestureRecognizerStateChanged)
{
[[recognizer view] setCenter:[recognizer locationInView:self.view]];
}
}
Cocos2D is fine, and I like it, but you don't really need to go to that level just to do some basic UITouch handling. If all you want to do is handle some touches, here is an example:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
// Only move the placard view if the touch was in the placard view
if ([touch view] != placardView) {
// On double tap outside placard view, update placard's display string
if ([touch tapCount] == 2) {
[placardView setupNextDisplayString];
}
return;
}
// "Pulse" the placard view by scaling up then down
// Use UIView's built-in animation
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
CGAffineTransform transform = CGAffineTransformMakeScale(1.2, 1.2);
placardView.transform = transform;
[UIView commitAnimations];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
transform = CGAffineTransformMakeScale(1.1, 1.1);
placardView.transform = transform;
[UIView commitAnimations];
// Move the placardView to under the touch
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.25];
placardView.center = [self convertPoint:[touch locationInView:self] fromView:placardView];
[UIView commitAnimations];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
// If the touch was in the placardView, move the placardView to its location
if ([touch view] == placardView) {
CGPoint location = [touch locationInView:self];
location = [self convertPoint:location fromView:placardView];
placardView.center = location;
return;
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
// If the touch was in the placardView, bounce it back to the center
if ([touch view] == placardView) {
CGPoint location = [touch locationInView:self];
location = [self convertPoint:location fromView:placardView];
UIView* dropZone; // assume this exists
CGRect dz = [dropZone frame];
if (CGRectContainsPoint(dz,location)) {
[self doDropMagic];
}
}
}
For more, check out the event handling guide which is where I got this hacked up code from.
I actually would point you to using Cocos2d. It's a nice framework on top of opengl and is pretty fast. It's so easy to create objects(in terms of Cocos2d it's a CCSprite) and put them on your view(CCLayer) and interact with them.
A drag and drop would actually consists of three phase (pseudo-code) using the touch handler methods (similar to UIKit's touch methods):
Pick up a number in ccTouchesBegan
move the number in ccTouchesMoves: update the numbers position with the touch position
Drop the number with ccTouchesEnded
The TouchesTest target in the repository shows a decent example on drag and drop. It implements a simple Pong like game:
Touch handling basics of cocos2d
There are tons of examples in the repository of cocos2d to understand the different parts better.
A decent book on cocos2d is the Learning Cocos2D.