I have implemented the drag and drop functionality using
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
In the touchesBegan I check if the according image on the screen was hit, I make a copy of it on the same exact place and start resizing it using the following code :
[UIView animateWithDuration:1.0f
animations:^{
CGRect oldFrame = copy.frame;
copy.frame = CGRectMake(oldFrame.origin.x,oldFrame.origin.y, oldFrame.size.width+60, oldFrame.size.height+60);
}
completion:^(BOOL finished){
}];
The problem that I am getting is that the animations are not actually visible until touchesMoved is triggered. In other words if I press the image and there is no move recorded for more then 1s nothing happens during this time, but if I suddenly move the finger I already see the resized image, but if I start moving in less then 1s I see how the image gets resized in the way while I drag it.
How should I change the code such that the image get's resized even if touchesMoved is not triggered?
Edits:
the only code triggered in touchesMoved is :
CGPoint newPoint = [[touches anyObject] locationInView:self.view];
[copy setCenter:newPoint];
This seemed to work for me (in an example that wasn't using touches, however).
CGRect oldFrame = copy.frame;
oldFrame = CGRectMake(oldFrame.origin.x,oldFrame.origin.y, oldFrame.size.width+60, oldFrame.size.height+60);
[copy layoutIfNeeded];
[UIView animateWithDuration:1.0f animations:^{
copy.frame = oldFrame;
}];
The key is to use layoutIfNeeded for animations that don't seem to be animating. If you're using autolayout, this thread might be more useful:
Are NSLayoutConstraints animatable?
My solution was to add a dummy method that is being called at the end of touchesBegan. This removed the problem I was having and the animation was visible before the touchesMoved was triggered.
Related
i have one query. i am try to develop one game like Abacus in iOS. I want to move four images, which are in sequence , from one location to another location horizontally in iOS. Can anyone help me please how i do this in iOS. i refer this link How to move Object from one place to other using Animation in iphone applications
but using this i am able to move only one image horizontally i want to move four image how i do this.
Here's what I've tried:
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch * touch = [touches anyObject];
CGPoint loc = [touch locationInView:self.view];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:2.0];
CGRect rect = CGRectMake(loc.x, _img.frame.origin.y, _img.frame.size.height, _img.frame.size.width);
[_img setFrame:rect];
[UIView commitAnimations];
}
Put all your images in a view (lets say container view) and then move the container view
When creating a new UIView or panning/swiping a view to a new position, whats the proper way of setting the new position and size. Currently, to move views resulting from a pan/swipe action, I'm using ratios based on the original position of the view that I'm moving and its relation to other views and items (navigation bar).
When moving a view due to a swipe I do the following:
CGFloat swipeUpDelta = -1 *(self.view.bounds.size.height - (self.view.bounds.size.height - recordView.frame.origin.y) - (self.navigationController.navigationBar.bounds.size.height + ([UIApplication sharedApplication].statusBarFrame.size.height)));
[UIView animateWithDuration:.1 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
recordView.frame = CGRectOffset(recordView.frame, 0, swipeUpDelta);
} completion:nil];
Or creating a view that renders a sineWave across my viewcontroller:
self.sineWave = [[OSDrawWave alloc] initWithFrame:CGRectMake(-1*self.view.bounds.size.width, (.75*self.view.bounds.size.height), 2*self.view.bounds.size.width, .3125*(2*self.view.bounds.size.width))];
Everything works fine, but I wanted to know if there is a better way of doing these things.
I'm not sure I understand the question. initWithFrame: or myView.frame is considered the correct way of positioning a UIView. Using animateWithDuration: with a new frame size is also pretty standard.
I'm unsure of what you mean as well. When you move a UIView you can move the view a variety of ways, it depends on your code and what you want out of it. The below is a valid example of code to move a CALayer inside of a UIView to follow touch positions. You can use this, you can animate your view, you can use explicit animations when changing the position of the layer or center of the view (By default iOS animates any changed property values of a CALayer... you can ride off of this and enable this feature for UIViews if you please). If you're moving a UIView, it's a good idea to move the view according to the center property. This is pretty much how SpriteKit works and any high functioning animation engine (avoid always resetting the frame... especially if you don't need to).
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *t = [touches anyObject];
CGPoint p = [t locationInView:self];
boxLayer.position = p;
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *t = [touches anyObject];
CGPoint p = [t locationInView:self];
[CATransaction begin];
[CATransaction setDisableActions:YES];
boxLayer.position = p;
[CATransaction commit];
}
As a note, note the comment in the following line of code
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
/*UITouch *t = [touches anyObject];
CGPoint p = [t locationInView:self]; // this causes the animations to appear sluggish as there is a consistant change in destination location. The above code corrects this.
[boxLayer setPosition:p];*/
This is valid, and may provide the results you want... it all depends on what you want.
I'm trying to make an image go full screen on tap, which doesn't sound so complicated.
This it currently doing the work after the tap is detected:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInView:self.view];
if (self.contentView.frame.origin.y >= 0 && CGRectContainsPoint(self.bottleImageView.frame, touchLocation)) {
[UIView animateWithDuration:0.5 delay:0 options:0 animations:^{
[bottleImageView setFrame:[[UIScreen mainScreen] bounds]];
bottleImageView.backgroundColor = [UIColor blackColor];
}completion:^(BOOL finished){}];
...
}
There's a problem though. I need to bring the UIImageView to the front, so that it draws the image in front of the other views. When I add in [self.view bringSubviewToFront:bottleImageView]; to the mix (either before the animation block, in the completion block, or after this code), things change. On the first tap, the UIImageView background changes to black, and on the second tap the view expands to full screen.
I'm sure it's just something small and dumb that I've overlooked.
EDIT: I've added the touch code
EDIT (2): I may have missed some vital information. I thought I'd try auto layout for this project. I'm guessing there's something there that's not letting everything work as intended?
You can use MHFacebookImageViewer
for this purpose. It is very simple to use.
Perhaps you have the wrong view content mode, add this line to where after the image is being set:
bottleImageView.contentMode = UIViewContentModeScaleAspectFit;
OK. The code above is fine for expanding a view.
I found there was a problem with the Autolayout restraints. I couldn't tell you exactly what I changed that fixed the problem - but a few hours debugging restraints solved the issue.
I found a much better solution however - Facebook POP works much better, and looks a lot slicker.
Add
[self.view bringSubviewToFront:bottleImageView]
immediately after you add
[self.view addSubview:bottleImageView]
I am creating a UIButton that follows the UITouch point, I want that when I Keep pressing the touch and the animation boundaries reach my touch point I perform some activity there.
Following is the code.
I am always getting x,y 0 for the UIButton.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[UIView beginAnimations:#"MoveAndStrech" context:nil];
[UIView setAnimationDuration:1];
[UIView setAnimationBeginsFromCurrentState:YES];
if([touches count] == 1) {
UITouch *touch = [touches anyObject];
self.uiButton.center = [touch locationInView:self.view];
}
[UIView commitAnimations];
UITouch *touchTemp = [touches anyObject];
CGPoint pCurrent = [touchTemp locationInView:self.view];
CGRect currentRect = self.uiButton.layer.bounds;
NSLog(#"Current Rect x:%f,Current y:%f",
currentRect.origin.x,
currentRect.origin.y);
NSLog(#"TouchPoint x:%f,TouchPoint y:%f",
pCurrent.x,
pCurrent.y);
if(CGRectContainsPoint(currentRect, pCurrent)) {
NSLog(#"Touched....in rect");
}
}
Regards
Sara
Replace
CGRect currentRect = self.uiButton.layer.bounds;
with
CGRect currentRect = self.uiButton.frame;
If that doesn't work, then
CGRect currentRect = self.uiButton.presentationLayer.frame;
Also, why aren't you using UIView animation blocks? It'd make your life much easier and your code much cleaner.
Several things. At first I thought you were missing the call to commitAnimations.
DO NOT PUT MULTIPLE STATEMENTS ON THE SAME LINE!!!! That is a very nasty coding habit that makes your code all but impossible to read.
Next, the old style beginAnimations/commitAnimations calls are outdated, and should not be used in iOS 4 or later. To quote the docs of beginAnimations:context:
Use of this method is discouraged in iOS 4.0 and later. You should use
the block-based animation methods to specify your animations instead.
You should be using the new block-based animation calls (of the form (animateWithDuration:animations:)
Next, UIView animations cause the object being animated to move to it's final location instantly. They only LOOK LIKE they are moving to their final location over time. They also disable user interaction during animations by default.
If you want to figure out where the view appears on the screen at any given moment then you need to check the view's layer's animationLayer. I have a sample project on Github (link) that includes a UIView animation of an image where you can tap on the image and the animation stops. This sample project shows how to use the view's layer's animation layer to figure out where the animation is located at the instant the user taps the screen.
If you want code that does something when the animated view gets to a certain point it would be more tricky. You might need to attach a CADisplayLink to your view (which will be called on each screen refresh) and use that to check the position of your animation and compare it to the current touch location.
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.