I have a scroll view with a fixed number of thumbnail images added as subview. I want to move these images along touch to the rectangle in another view. I am able to move the image along scrollview (ie, along the same view) but not able to move across another view.
Now am changing the center of image depending on touch position. When touch point increases beyond the frame of scrollview the image disappears. This is my problem
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView: self];
NSLog(#"%f,%f",location.x,location.y);
touch.view.center = location;
}
Any solution to this problem will be a great help for me !!!
Please refer image for further details
Here is what I'd do :
Add a panGestureRecognizer to each image, with the following handlePan: method as its action. You still have to figure out how to get the correct imageView (myImageView), but this will make your image follow your finger.
- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer {
// Find the correct image you're dragging
// UIImageView *myImageview = ...
CGPoint translation = [recognizer translationInView:self.view];
if (recognizer.state == UIGestureRecognizerStateEnded) {
// What to do when you start the gesture
// You may also define myImageView here
// (if so, make sure you put it in #interface,
// because this method will be called multiple times,
// but you will enter this "if" only when you start the touch)
}
// Keep your image in the screen
if (myImageView.frame.origin.x + translation.x >= 0.0f &&
myImageView.frame.origin.x + myImageView.frame.size.width + translation.x <= 320.0f &&
myImageView.frame.origin.y + translation.y >= 0.0f &&
myImageView.frame.origin.y + myImageView.frame.size.height + translation.y <= 480.0f) {
myImageView.center = CGPointMake(myImageView.center.x + translation.x,
myImageView.center.y + translation.y);
}
if (recognizer.state == UIGestureRecognizerStateEnded) {
// What to do when you remove your finger from the screen
}
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
}
Related
At the moment, I have a puzzle game, with some objects that are movable using the ccTouchesBegan && ccTouchesMoved method
Called in ccTouchesBegan:
if (CGRectContainsPoint(newBoundingBox, touchLocation))
{
//Set the selectedSprite to the sprite with newBoundingBox
}
Then in ccTouchesMoved i do:
CGPoint translation = ccpSub(touchLocation, oldTouchLocation);
newPos = ccpAdd(selSprite.position, translation);
selectedSprite.position = newPos;
Now this all works fine and dandy, HOWEVER, some of the objects that I am moving are about 140x40px (on the 320x480 iPhone), and sometimes the ccTouchesBegan method won't acknowledge the boundingBox containing the touchLocation.
My question is, Can I increase the size of the boundingBox of the object so that if the user "misses" with there touch a little bit, it will help them out? It's a little frustrating requiring you to be so precise on a touch screen to move an obstacle.
EDIT: for iPhonic:
How I get touchLocation, this is in ccTouchesBegan:
NSSet *touchSet = [event allTouches];
int numberOfTouches = [touchSet count];
CGPoint touchLocation = [self convertTouchToNodeSpace:[touches anyObject]];
allTouches is passed automatically when the a touch begins.
-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
CGPoint location = [self convertTouchToNodeSpace: touch];
for (CCSprite *tempSprite in sprites )
{
//Increase the size of bounding box..
CGRect rect=tempSprite.boundingBox;
rect.size.height=rect.size.height + 20;
rect.size.width=rect.size.width + 20;
if (CGRectContainsPoint(rect, location))
{
//Your stuffs
}
}
}
Okay, I have been all over the internet trying to find the answer to this, I am trying to create a custom UIScrollView scroller.
Here is a link to a picture of the scroller
http://postimage.org/image/cg2jvde9z/
http://postimage.org/image/ko0mp3kdj/
(that white box is just for me to test the scrollview)
I have gotten the scroller to work, although I need help figuring out how many pixels the scrollview should move every time the scroller is pushed
here is some code
-(IBAction)scroller_bar:(id)sender withEvent:(UIEvent *)event{
UIButton *button_sent = (UIButton *)sender;
UITouch *touch = [[event touchesForView:button_sent] anyObject];
CGPoint previousLocation = [touch previousLocationInView:button_sent];
CGPoint location = [touch locationInView:button_sent];
CGFloat delta_x = location.x - previousLocation.x;
float left_side = button_sent.center.x + delta_x;
float right_side = button_sent.center.x + delta_x;
if (right_side > button_sent.center.x) {
scroll_right = YES;
}
else{
scroll_right = NO;
}
if (left_side <= 13 + 50.5 || right_side >= 307 - 50.5) {
}
else{
button_sent.center = CGPointMake(button_sent.center.x + delta_x,
button_sent.center.y);
if (scroll_right) {
[selection_scroll setContentOffset:CGPointMake(selection_scroll.contentOffset.x - (Help HERE!), selection_scroll.contentOffset.y) animated:YES];
}
else{
[selection_scroll setContentOffset:CGPointMake(selection_scroll.contentOffset.x + (Help HERE!), selection_scroll.contentOffset.y) animated:YES];
}
}
}
In the above code you should see a '(Help HERE!)',
that is where i am trying to figure out how many pixels i should move the scroll view. This is a bit of a confusing question, hope you understand.
Thanks :)
I don't know whether APPLE will approve this or not but the code written below can change the scollView 's scroller images
for (UIImageView *img in yourscrollView.subviews) {
[img setImage:[UIImage imageNamed:#"your custom scroller image"]];
}
In my iPhone App I want to implemented functionality as shown below
user can pick a shape(an image) from one view and put in other view
How can I achieve this?
Easiest way is to use a UIPanGestureRecognizer. That will give you messages when the view is moved and when it is dropped. When it is moved, update its center. When it is dropped, check if its position is within the bounds of the view you want to drop in. (You might need to convert coordinates to the target view's coordinate system.) If it is, do the appropriate action.
Try below link drag and drop image around the screen
also try this
You can refer to the previous post which will definitely help you to achieve this functionality...
Basic Drag and Drop in iOS
Building drag and drop interface on iphone
iPhone drag/drop
For all of above link, You have to keep in mind that You need to first get TouchesBegin event for any Control and then you have to get the TouchesMoved event for same control.
In TouchesMoved event, you just have to get the center point (CGPoint) of the Control. And when you release the control will be set at that CGPoint. If this creates problem then you can take that CGPoint in variable and set that Point in TouchesEnded event.
For your case, i think you must have to maintain the Hierarchy of the Views...Else while dragging you view may not be visible...
FOR MORE CODING PART :
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(#"%f,%f", self.center.x, self.center.y);
CGPoint newLoc = CGPointZero;
newLoc = [self.mainView convertPoint:[[touches anyObject] locationInView:self.superview] toView:self.superview];
float newX = newLoc.x + self.superview.frame.origin.x + (self.frame.size.width /2) + [[touches anyObject] locationInView:self].x ;
float newY = newLoc.y - (((UIScrollView *)self.superview).contentOffset.y *2) ;
NSLog(#"content offset %f", ((UIScrollView *)self.superview).contentOffset.y);
self.scrollParent.scrollEnabled = NO;
NSLog(#"%f,%f", self.center.x, self.center.y);
newLoc = CGPointMake(newX, newY);
[self.superview touchesCancelled:touches withEvent:event];
[self removeFromSuperview];
NSLog(#"%f,%f", self.center.x, self.center.y);
self.center = CGPointMake(newLoc.x, newLoc.y);
[self.mainView addSubview:self];
NSLog(#"%f,%f", self.center.x, self.center.y);
[self.mainView bringSubviewToFront:self];
isInScrollview = NO;
}
-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[UIView beginAnimations:#"stalk" context:nil];
[UIView setAnimationDuration:.001];
[UIView setAnimationBeginsFromCurrentState:YES];
UITouch *touch = [touches anyObject];
self.center = [touch locationInView: self.superview];
[UIView commitAnimations];
if ((self.center.x + (self.frame.size.width / 2)) > 150 && hasExitedDrawer && !self.scrollParent.dragging ) {
self.scrollParent.scrollEnabled = NO;
[self.delegate moveItemsDownFromIndex: ((self.center.y + (self.scrollParent.contentOffset.y)) / 44) + 1 ];
//NSLog(#"%i", ((self.center.y + (self.scrollParent.contentOffset.y *2)) / 44) + 1);
}
if (self.center.x + (self.frame.size.width / 2) < 150) {
hasExitedDrawer = YES;
}
}
-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if ((self.center.x + (self.frame.size.width / 2)) > 150 && hasExitedDrawer && !self.scrollParent.dragging ) {
CGPoint newLoc = CGPointZero;
newLoc = [self.scrollParent convertPoint:[[touches anyObject] locationInView:self.superview] toView:self.superview];
float newY = newLoc.y + (self.scrollParent.contentOffset.y *2);
[self.scrollParent insertSubview:self atIndex:((self.center.y + (self.scrollParent.contentOffset.y)) / 44) ];
self.frame = CGRectMake(0, newY, self.frame.size.width, self.frame.size.height);
isInScrollview = YES;
hasExitedDrawer = NO;
}
}
This code may cantains some irrelevant but gives you more idea...
You can use below open source libraries:
Library 1 OBDragDrop
Library 2 AJWDraggableDroppable
Library 3 iOS-DragAndDrop
Library 4 ios-drag-and-drop
Adding drag and drop component to iOS app the Question
i thing you are going to Build a feature like Add to cart in Most of the Shopping Apps like Amazon, Flip kart and etc..
Three step solution
1) u'll have to implement/listen for touch events
2) implement dragging and touch events
3) and then manage movetosuperview method.
Currently i am following this Link to perform Single finger rotation on an image and its working fine.But i am wondering after performing rotation, how to perform translation operation if i want to move the image from one postion of screen to any other position.
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
// We can look at any touch object since we know we
// have only 1. If there were more than 1 then
// touchesBegan:withEvent: would have failed the recognizer.
UITouch *touch = [touches anyObject];
// A tap can have slight movement, but we're not interested
// in a tap. We want more movement. So if a tap is detected
// fail the recognizer.
if ([self state] == UIGestureRecognizerStatePossible) {
[self setState:UIGestureRecognizerStateBegan];
} else {
[self setState:UIGestureRecognizerStateChanged];
}
// To rotate with one finger, we simulate a second finger.
// The second figure is on the opposite side of the virtual
// circle that represents the rotation gesture.
UIView *view = [self view];
CGPoint center = CGPointMake(CGRectGetMidX([view bounds]), CGRectGetMidY([view bounds]));
CGPoint currentTouchPoint = [touch locationInView:view];
CGPoint previousTouchPoint = [touch previousLocationInView:view];
// use the movement of the touch to decide
// how much to rotate the carousel
CGPoint line2Start = currentTouchPoint;
CGPoint line1Start = previousTouchPoint;
CGPoint line2End = CGPointMake(center.x + (center.x - line2Start.x), center.y + (center.y - line2Start.y));
CGPoint line1End = CGPointMake(center.x + (center.x - line1Start.x), center.y + (center.y - line1Start.y));
//////
// Calculate the angle in radians.
// (From: http://iphonedevelopment.blogspot.com/2009/12/better-two-finger-rotate-gesture.html )
CGFloat a = line1End.x - line1Start.x;
CGFloat b = line1End.y - line1Start.y;
CGFloat c = line2End.x - line2Start.x;
CGFloat d = line2End.y - line2Start.y;
CGFloat line1Slope = (line1End.y - line1Start.y) / (line1End.x - line1Start.x);
CGFloat line2Slope = (line2End.y - line2Start.y) / (line2End.x - line2Start.x);
CGFloat degs = acosf(((a*c) + (b*d)) / ((sqrt(a*a + b*b)) * (sqrt(c*c + d*d))));
CGFloat angleInRadians = (line2Slope > line1Slope) ? degs : -degs;
//////
[self setRotation:angleInRadians];
}
I am not sure that my answer will help you, but I fear that you cannot do "one-touch" rotation and "one-touch" translation at the same time. Indeed, your code always interprets a single touch as for rotation, by "simulating" the presence of a second finger touching the display.
What you could do is trying and differentiate two single-finger gestures so to associate one with rotation and the other with translation. For example, the gesture for translation could be a "long touch" (i.e., you touch and keep touching for some time, then you move the object).
Hope this helps, anyway...
I am attempting to make a UIView/UIControl that people can drag up and reveal a text box, and then drag down to hide it. However, I have yet to find a method to make this "fluid" - it always seems to stop at random places and doesn't allow any more movement. At the moment I am using a UIView for the top part of the view and here is the current code:
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
if ([touch view] == topMenuView) {
CGPoint location = [touch locationInView:self.superview];
CGPoint locationInsideBox = [touch locationInView:self];
CGPoint newLocation = location;
newLocation.x = self.center.x;
newLocation.y = newLocation.y + (self.frame.size.height - locationInsideBox.y) / 2;
if ((self.superview.frame.size.height - newLocation.y) < (self.frame.size.height / 2) && (self.superview.frame.size.height - newLocation.y) > -32)
{
self.center = newLocation;
}
return;
}
}
Any help would be much appreciated!
I would use a pan gesture recognizer. The following code will simply move the view up and down along with the user's finger. If you want to limit how far up it moves, have it snap to place or have momentum you'll need to add to it.
UIView * view; // The view you're moving
CGRect originalFrame; // The frame of the view when the touch began
- (void) pan:(UIPanGestureRecognizer *)pan {
switch (pan.state) {
case UIGestureRecognizerStateBegan: {
originalFrame = view.frame;
} break;
case UIGestureRecognizerStateChanged:
case UIGestureRecognizerStateEnded: {
CGPoint translation = [pan translationInView:view];
CGRect frame = originalFrame;
frame.origin.y += translation.y;
view.frame = frame;
} break;
}
}
Removing this line may well help you:
newLocation.y = newLocation.y + (self.frame.size.height - locationInsideBox.y) / 2;
What you're trying to accomplish is really nothing more than a scrollable view, so I would recommend using a UIScrollView.
Put your UIView in a UIScrollView with transparent background, and place the UIScrollView on top of your textbox. Set the correct contentSize and you're good to go.
use a uiview animation block to update the frame of the sliding view corresponding with the touch point recieved. set the animation blocks duration to something really short like .01 or lower.
I'd recommend splitting the issue in two:
Implement the view which has the text box at the bottom - You will just have to implement your own custom view/view controller.
Add your view as a subview of a UIScrollView.
This is a good tutorial which demonstrates proper initialization of UIScrollView and embedding content in it.
Custom views/controllers are a bit of a broader subject :)