using the tableview as horizontal scroll and animating the views and also animating the text like marquee - objective-c

//To Drag the image View on the iphone screen
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
point0 = [touch locationInView:self.view];
if ([touch tapCount] == 2) {
dropDownBool = NO;
pushUpBool = NO;
self.imageView.alpha = 0.4;
doublePressed = YES;
}
if(doublePressed)
{
point0 = [touch locationInView:self.view];
if (CGRectContainsPoint([self.imageView frame], [touch locationInView:[touch view]]))
{
self.imageView.center = [touch locationInView:nil];
}
}
}
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
point0 = [touch locationInView:self.imageView];
if(doublePressed)
{
UITouch *touch = [[event allTouches] anyObject];
point0 = [touch locationInView:self.imageView];
//animating the view...
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
CGAffineTransform transform =CGAffineTransformTranslate(CGAffineTransformIdentity,0.0f, 0.0f);
self.imageView.transform = transform;
[UIView commitAnimations];
doublePressed = NO;
self.imageView.alpha = 1.0;
}
}
// To drop down a view as you swipe on top of the screen
-(void)handleSwipeGesture:(UISwipeGestureRecognizer *) sender
{
//Gesture detect - swipe up/down , can be recognized direction
if(sender.direction == UISwipeGestureRecognizerDirectionUp)
{
pushUpBool = YES;
}
else
if(sender.direction == UISwipeGestureRecognizerDirectionDown)
{
dropDownBool = YES;
}
if(dropDownBool && (point0.y < 80.0f))
{
NSLog(#"%f",point0.y);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.25];
self.dropDownView.center = CGPointMake(originalCenter.x,30.0 );
self.dropDownView.alpha = 0.8;
dropDownBool = NO;
}
if(pushUpBool && (point0.y < 80.0f))
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.25];
pushUpBool = NO;
self.dropDownView.center = originalCenter;
self.dropDownView.alpha = 0.0;
}
}
// animates from left to right like Marqee...
-(void) scrollLeft
{
CABasicAnimation *scrollText;
scrollText=[CABasicAnimation animationWithKeyPath:#"position.x"];
scrollText.duration = 6.0;
scrollText.repeatCount = 10000;
scrollText.autoreverses = NO;
scrollText.fromValue = [NSNumber numberWithFloat:500];
scrollText.toValue = [NSNumber numberWithFloat:-120.0];
[[self.detailView layer] addAnimation:scrollText forKey:#"scrollTextKey"];
}
// Making the table View scroll horizontally place this code in viewDidLoad.
CGAffineTransform transform = CGAffineTransformMakeRotation(-1.5707963);
self.horizontalTableView.transform = transform;
// now in tableview method transform the cell back.
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
CGAffineTransform transform = CGAffineTransformMakeRotation(1.5707963);
cell.transform = transform;
}
Using the above Methods one can transform the table view look like a horizontal scroll view. and you can drag the image view by double clicking on the image and moving it across the screen.
if you have any question please feel free.

Related

Implement touch cancel on UIButton

I have a subclassed UIButton that I made into an irregular shape (Parallelogram) where I override the touch events so it will only accept touch events inside the shape
How can I implement a touch event like a normal UIButton where I can cancel a touch event upon tapping and dragging the finger outside the UIButton to cancel a touch. For my current code, If I drag my finger inside the button, it calls the touchesCancelled event. I am using the TouchUpInside event for performing methods in the UIButton. Here is my code:
- (id)initWithFrame:(CGRect)frame withAngle:(AngleType)angle andColor:(UIColor *)color
{
if ((self = [super initWithFrame:frame])){
[self setImage:[Utils imageWithColor:color andSize:frame.size] forState:UIControlStateNormal];
_path = [UIBezierPath new];
self.angleType = angle;
switch (angle) {
case AngleLeft:
{
[_path moveToPoint:CGPointMake(0, elementHeight(self))];
[_path addLineToPoint:CGPointMake(elementWidth(self), elementHeight(self))];
[_path addLineToPoint:CGPointMake(elementWidth(self), 0)];
[_path addLineToPoint:CGPointMake(15, 0)];
[_path addLineToPoint:CGPointMake(0, elementHeight(self))];
}
break;
case AngleRight:
{
[_path moveToPoint:CGPointMake(0, 0)];
[_path addLineToPoint:CGPointMake(0, elementHeight(self))];
[_path addLineToPoint:CGPointMake(elementWidth(self),elementHeight(self))];
[_path addLineToPoint:CGPointMake(elementWidth(self) - 15, 0)];
[_path addLineToPoint:CGPointMake(0, 0)];
}
break;
case AngleBoth:
{
[_path moveToPoint:CGPointMake(15, 0)];
[_path addLineToPoint:CGPointMake(0, elementHeight(self))];
[_path addLineToPoint:CGPointMake(elementWidth(self) - 15, elementHeight(self))];
[_path addLineToPoint:CGPointMake(elementWidth(self), 0)];
[_path addLineToPoint:CGPointMake(15, 0)];
}
break;
default:
break;
}
CAShapeLayer *mask = [CAShapeLayer new];
mask.frame = self.bounds;
mask.path = _path.CGPath;
self.layer.mask = mask;
}
return self;
}
- (void)setText:(NSString *)text withAlignment:(NSTextAlignment)alignment
{
_buttonLabel = [[UILabel alloc] init];
_buttonLabel.font = FONT_Helvetica_Neue(14);
_buttonLabel.textColor = [UIColor whiteColor];
_buttonLabel.text = text;
_buttonLabel.textAlignment = alignment;
if (alignment == NSTextAlignmentLeft) {
_buttonLabel.frame = CGRectMake(15 + 10, 0, elementWidth(self), elementHeight(self));
} else if (alignment == NSTextAlignmentRight) {
_buttonLabel.frame = CGRectMake(0, 0, elementWidth(self) - 15 - 10, elementHeight(self));
} else if (alignment == NSTextAlignmentCenter) {
_buttonLabel.frame = CGRectMake(0, 0, elementWidth(self), elementHeight(self));
}
[self addSubview:_buttonLabel];
}
- (void)setBackgroundColor:(UIColor *)backgroundColor
{
[self setImage:[Utils imageWithColor:backgroundColor andSize:self.frame.size] forState:UIControlStateNormal];
CAShapeLayer *mask = [CAShapeLayer new];
mask.frame = self.bounds;
mask.path = _path.CGPath;
self.layer.mask = mask;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self];
if ([_path containsPoint:touchLocation]) {
NSLog(#"Inside!");
self.highlighted = YES;
//[self sendActionsForControlEvents:UIControlEventTouchUpInside];
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self];
self.highlighted = NO;
if ([_path containsPoint:touchLocation]) {
[self sendActionsForControlEvents:UIControlEventTouchUpInside];
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self];
if ([_path containsPoint:touchLocation]) {
NSLog(#"...");
self.highlighted = YES;
}
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self];
self.highlighted = NO;
if ([_path containsPoint:touchLocation]) {
[self sendActionsForControlEvents:UIControlEventTouchUpInside];
}
}
Instead of trying to implement custom touch events handling, please override the hitTest:withEvent: method. Please refer to this tutorial which I believe describes your case. And this is another example.

"Drag 'n' Drop" game animation

I'm quite new to Objective-C and am looking to create a fairly simple Jigsaw. I'm currently just looking at making a 4-piece puzzle as a way of learning the method.
At the moment I have 4 pieces placed around the screen that when dragged to a specific place on screen, snap to that place.
My problem is trying to animate the touches. I want the image touched to expand a little but i'm having trouble with the syntax. I've looked at the MoveMe example that Apple provide but it's not helping me in this situation. Below is the code. I'd appreciate any help with this. Thanks.
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
//location of current touch
CGPoint location = [touch locationInView:self.view];
if ([touch view] == image1) {
image1.center = location;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
image1.transform = CGAffineTransformMakeScale(1.5, 1.5);
[UIView commitAnimations];
} else if ([touch view] == image2) {
image2.center = location;
animateFirstTouch:image2;
} else if ([touch view] == image3) {
image3.center = location;
image3.transform = CGAffineTransformMakeScale(1.5, 1.5);
} else if ([touch view] == image4) {
image4.center = location;
image4.transform = CGAffineTransformMakeScale(1.5, 1.5);
}
}
-(void) animateFirstTouch:(UIView *)image {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
self.view.transform = CGAffineTransformMakeScale(1.5, 1.5);
[UIView commitAnimations];
}
The code for image1 works, and the image is scaled up over 0.5 seconds.
The code for image2 throws up an error: expression result unused for animateFirstTouch:image2.
The code for image3 and image4 scales up the images without the animation.
Refer to Kuldeep's answer from this link. I think that would work for you:
iPhone/iOS: How to implement Drag and Drop for subviews of a Scrollview?
Also as an alternative refer to iPhone's answer in this link:
iPhone App: implementation of Drag and drop images in UIView
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
//location of current touch
CGPoint location = [touch locationInView:self.view];
if ([touch view] == image1) {
[self animateFirstTouch:image1 withLocation:location];
} else if ([touch view] == image2) {
[self animateFirstTouch:image2 withLocation:location];
} else if ([touch view] == image3) {
[self animateFirstTouch:image3 withLocation:location];
} else if ([touch view] == image4) {
[self animateFirstTouch:image4 withLocation:location];
}
}
-(void) animateFirstTouch:(UIImageView *)image withLocation:(CGPoint)location {
image.center = location;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
image.transform = CGAffineTransformMakeScale(1.5, 1.5);
[UIView commitAnimations];
}
Hope this helps you.
Contact me if you need more help.

Differentiate between two ImageViews

I have two imageViews imageView1 and imageView2. I have given gestureRecognizer to move these both images. Now the problem is when i move first imageView near second imageView only second image view is displayed. But when i put first imageView on another image the first imageView should be displayed on the second imageView which is not happening.Can any body please tell me how can the first imageView gets view on the top of another imageView.
You can use the UIView method bringSubviewToFront:, and pass in the UIImageView that you want displayed on top.
Why dont you use something similar like this to drag your UIImageViews?
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = [UIColor yellowColor];
test1 = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
test1.backgroundColor = [UIColor whiteColor];
test1.userInteractionEnabled = YES;
test1.clipToBounds = YES;
[self.view addSubview:test1];
test2 = [[UIImageView alloc] initWithFrame:CGRectMake(400, 400, 100, 100)];
test2.backgroundColor = [UIColor whiteColor];
test2.userInteractionEnabled = YES;
test2.clipToBounds = YES;
[self.view addSubview:test2];
}
CGPoint startLocation;
float diffX;
float diffY;
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
if( [touch view] == test1)
{
startLocation = [touch locationInView:self.view];
[self.view bringSubviewToFront:test1];
}
if( [touch view] == test2)
{
startLocation = [touch locationInView:self.view];
[self.view bringSubviewToFront:test2];
}
}
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [[event allTouches] anyObject];
if( [touch view] == test1)
{
CGPoint location = [touch locationInView:self.view];
diffX = location.x - startLocation.x;
diffY = location.y - startLocation.y;
test1.frame = CGRectMake(test1.frame.origin.x + diffX, test1.frame.origin.y + diffY, test1.frame.size.width, test1.frame.size.height);
startLocation = test1.frame.origin;
}
if( [touch view] == test2)
{
CGPoint location = [touch locationInView:self.view];
diffX = location.x - startLocation.x;
diffY = location.y - startLocation.y;
test2.frame = CGRectMake(test2.frame.origin.x + diffX, test2.frame.origin.y + diffY, test2.frame.size.width, test2.frame.size.height);
startLocation = test2.frame.origin;
}
}
//---EDIT---//
Added: cliptobounds in viewdidload

How to drag only one image with iPhone SDK

I want to create a little app that takes two images and i want to make only the image over draggable.
After research, i found this solution:
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[ event allTouches] anyObject];
image.alpha = 0.7;
if([touch view] == image){
CGPoint location = [touch locationInView:self.view];
image.center = location;
}
It works but the problem is that the image is draggable from its center and I don't want that.
So I found another solution:
- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
// Retrieve the touch point
CGPoint pt = [[touches anyObject] locationInView:self.view];
startLocation = pt;
[[self view] bringSubviewToFront:self.view];
}
- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {
// Move relative to the original touch point
CGPoint pt = [[touches anyObject] locationInView:self.view];
frame = [self.view frame];
frame.origin.x += pt.x - startLocation.x;
frame.origin.y += pt.y - startLocation.y;
[self.view setFrame:frame];
}
It works very well but when I add another image, all the images of the view are draggable at the same time. I'm a beginner with the iPhone development and I have no idea of how I can only make the image over draggable.
You can use if condition in the touchesBegan: method, See this-
-(void)ViewDidLoad
{
//Your First Image View
UIImageView *imageView1 = [UIImageView alloc]initWithFrame:CGRectMake(150.0, 100.0, 30.0, 30.0)];
[imageView1 setImage:[UIImage imageNamed:#"anyImage.png"]];
[imageView1 setUserInteractionEnabled:YES];
[self.view addSubview:imageView1];
//Your Second Image View
UIImageView *imageView2 = [UIImageView alloc]initWithFrame:CGRectMake(150.0, 200.0, 30.0, 30.0)];
[imageView2 setImage:[UIImage imageNamed:#"anyImage.png"]];
[imageView2 setUserInteractionEnabled:YES];
[self.view addSubview:imageView2];
}
//Now Use Touch begin methods with condition like this
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches]anyObject];
if([touch view] == imageView1)
{
CGPoint pt = [[touches anyObject] locationInView:imageView1];
startLocation = pt;
}
if([touch view] == imageView2)
{
CGPoint pt = [[touches anyObject] locationInView:imageView2];
startLocation = pt;
}
}
//Use same thing with touch move methods...
- (void) touchesMoved:(NSSet *)touches withEvent: (UIEvent *)event
{
UITouch *touch = [[event allTouches]anyObject];
if([touch view] == imageView1)
{
CGPoint pt = [[touches anyObject] previousLocationInView:imageView1];
CGFloat dx = pt.x - startLocation.x;
CGFloat dy = pt.y - startLocation.y;
CGPoint newCenter = CGPointMake(imageView1.center.x + dx, imageView1.center.y + dy);
imageView1.center = newCenter;
}
if([touch view] == imageView2)
{
CGPoint pt = [[touches anyObject] previousLocationInView:imageView2];
CGFloat dx = pt.x - startLocation.x;
CGFloat dy = pt.y - startLocation.y;
CGPoint newCenter = CGPointMake(imageView2.center.x + dx, imageView2.center.y + dy);
imageView2.center = newCenter;
}
}
These two images will move only when you touch on it and move it. I hope my tutorials will help you.
Simply use these two methods
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:touch.view];
myImage.center = location;
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[self touchesBegan:touches withEvent:event];
}
Let's break it down. You should have a main containerView (object of UIView) in your view controller. Within that, you should have DragableImageView objects.
DragableImageView inherits UIImageView and within that, you add your touches code. (Right now you are doing self.frame = position which is wrong - and obviously it will move all images at once - because if I understand correctly, you are adding these touches in your view controller).
Create only DragableImageView first, test it. Then add two DragableImageView instances. test them in different configurations.. you might want to hit test in the containerView to see which DragableImageView should be dragged (e.g. if you have jigsaw pieces, you might want to pick the one that is at the back rather than the front one).

Rotate view using CGAfffineTransformRotate

I have a circular image which I am trying to rotate, so that the yellow and black striped circle stays under the user's finger and rotates in both directions. I have this so far:
- (void)handleJogShuttle:(UIPanGestureRecognizer *)recognizer {
UIView *shuttle = [recognizer view];
if ([recognizer state] == UIGestureRecognizerStateBegan ||
[recognizer state] == UIGestureRecognizerStateChanged) {
[recognizer view].transform = CGAffineTransformRotate([[recognizer view] transform],M_PI / 20.0f);
[recognizer setTranslation:CGPointZero inView:[shuttle superview]];
}
}
Also, currently, the slightest movement can cause the view to rotate in a full circle, which is obviously not desired.
#import "RotationTestViewController.h"
#interface RotationTestViewController()
-(void)transformSpinnerwithTouches:(UITouch *)touchLocation;
-(CGPoint)vectorFromPoint:(CGPoint)firstPoint toPoint:(CGPoint)secondPoint;
-(void)animateView:(UIView *)theView toPosition:(CGAffineTransform) newTransform;
#end
#implementation RotationTestViewController
- (void)viewDidLoad {
[super viewDidLoad];}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
for (UITouch *touch in touches)
{
// Send to the dispatch method, which will make sure the appropriate subview is acted upon
// currentTouch=touch;
}
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
for (UITouch *touch in touches){
// Sends to the dispatch method, which will make sure the appropriate subview is acted upon
}
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch=[[event allTouches]anyObject];
if (touch.view==Spinner)
{
[self transformSpinnerwithTouches:touch];
}
}
-(void)transformSpinnerwithTouches:(UITouch *)touchLocation
{
CGPoint touchLocationpoint = [touchLocation locationInView:self.view];
CGPoint PrevioustouchLocationpoint = [touchLocation previousLocationInView:self.view];
//origin is the respective piont from that i gonna measure the angle of the current position with respective to previous position ....
CGPoint origin;
origin.x=Spinner.center.x;
origin.y=Spinner.center.y;
CGPoint previousDifference = [self vectorFromPoint:origin toPoint:PrevioustouchLocationpoint];
CGAffineTransform newTransform =CGAffineTransformScale(Spinner.transform, 1, 1);
CGFloat previousRotation = atan2(previousDifference.y, previousDifference.x);
CGPoint currentDifference = [self vectorFromPoint:origin toPoint:touchLocationpoint];
CGFloat currentRotation = atan2(currentDifference.y, currentDifference.x);
CGFloat newAngle = currentRotation- previousRotation;
temp1=temp1+newAngle;
NSLog(#"Angle:%F\n",(temp1*180)/M_PI);
newTransform = CGAffineTransformRotate(newTransform, newAngle);
[self animateView:Spinner toPosition:newTransform];
}
-(void)animateView:(UIView *)theView toPosition:(CGAffineTransform) newTransform
{
[UIView setAnimationsEnabled:YES];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.0750];
Spinner.transform = newTransform;
[UIView commitAnimations];
}
//-(CGFloat)distanceFromPoint:(CGPoint)fromPoint toPoint:(CGPoint)toPoint
//
//{
//float x = toPoint.x - fromPoint.x;
//float y = toPoint.y - fromPoint.y;
//return hypot(x, y);
//}
-(CGPoint)vectorFromPoint:(CGPoint)firstPoint toPoint:(CGPoint)secondPoint
{
CGFloat x = secondPoint.x - firstPoint.x;
CGFloat y = secondPoint.y - firstPoint.y;
CGPoint result = CGPointMake(x, y);
//NSLog(#"%f %f",x,y);
return result;
}
-(void) dealloc
{
[Spinner release];
[super dealloc];
}
I suspect this method gets called A LOT. Try using NSLog and check how many time it does.
Anyway, you are not calculating the angle properly, you could try using
-(CGPoint)translationInView:(UIView *)view
from the recognizer to calculate the correct angle to rotate.