I'm having some images from which the user should choose one. Now I don't want to just offer an flat scrolling area with a boring grid. Instead, I'd like to show up a wheel that contains those images. At the top would be a marker indicating the selection. Something similar to the Pickers.
The problem is not the rotation stuff; I'd use some geometric functions for that. But I have no idea how to actually get the scrolling gestures on that wheel. Where must I start?
BTW: With circular I don't mean something like the Pickers. I mean a real wheel that has a center axis and can be rolled. Like the very old telephones, like a bike wheel. Or a Picker turned by 90°, facing with the axis to you (Z-coordinate).
If you're talking about capturing gestures then here is the example they give in the docs.
Though I could have sworn I heard Alan Cannistraro say in one of the first CS193P lectures that you don't have to do this, that you can just trap the swipe event but I can't find that.
Could someone that actually knows what they are doing please correct me and I'll remove this post but for now I know this will work:
#define HORIZ_SWIPE_DRAG_MIN 12
#define VERT_SWIPE_DRAG_MAX 4
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
startTouchPosition = [touch locationInView:self];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint currentTouchPosition = [touch locationInView:self];
// If the swipe tracks correctly.
if (fabsf(startTouchPosition.x - currentTouchPosition.x) >= HORIZ_SWIPE_DRAG_MIN &&
fabsf(startTouchPosition.y - currentTouchPosition.y) <= VERT_SWIPE_DRAG_MAX)
{
// It appears to be a swipe.
if (startTouchPosition.x < currentTouchPosition.x)
[self myProcessRightSwipe:touches withEvent:event];
else
[self myProcessLeftSwipe:touches withEvent:event];
}
else
{
// Process a non-swipe event.
}
}
Just how similar to a picker view are you thinking? You can load up a picker view with your own custom subviews, which could be image views. That'd get you an actual picker view with your images, which might or might not be what you're actually aiming for.
Related
How to determine the property or perhaps the object underneath the object i am hovering or dragging?
To put my question clearly, lets take I am hovering a uiview, I want to find out what (object or view) is underneath the view I am hovering.
in custom view you can override touchesEnded method.This sample code may help your custom view hit test problem.
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if ([touches count] == 1) {
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:custom_view];
if (CGRectContainsPoint(custom_view.bounds, point)) {
//if touch hit to custom_view
};
}
[super touchesEnded:touches withEvent:event];
}
For one, if you know the frames of both objects you can use CGRectIntersectsRect.
if (CGRectIntersectsRect(topObjectsRect, bottomObjectsRect)) {
//
}
Additionally, you could get the point that was touched and then use the following to check if that point is in a certain rectangle.
if (CGRectContainsPoint(CGRectMake(someX, someY, someWidth, someHeight), pointOfTouch))
{
//
}
In my app, I allow the user to annotate a photo by adding arrows (custom ArrowView). There can be many arrows added, with various zoom & rotation.
I am trying implement selecting of arrow by touch. Currently, I am iterating & using
CGRectContainsPoint(arrowView.frame, touchPoint)
to decide which arrow to select based on a touch gesture.
But, this does not work well when some of the arrows are big & rotated to 45 degrees (since the frame becomes big).
Question:
I would like to use bounds of the arrow translated to parent co-ordinates instead of frame. How can I get this when scaling & rotation is applied?
Alternatively, is there a better method to solve this selection problem?
This code find the arrow under touchPoint:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint touchPoint = [touch locationInView:self.view];
UIView *arrow = [self.view hitTest:touchPoint withEvent:event];
}
I'm having a problem with a jumping movement with using CGAffineTransformMakeRotation. It seems to work fine until I get to the top of quadrants 1 and 2. Below is the code I am using and youtube link that shows what happens. Any insight would be really appreciated.
My goal is to rotate a UIWebView with an svg inside. Since I can't easily detect touch on the UIWebView alone, I'm putting a blank UIImageView over it. This allows me to detect the touch and prevent the copy dialog from popping up.
http://www.youtube.com/watch?v=x_OmS0MPdEE&feature=youtu.be
- (void)touchesMoved: (NSSet *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
NSArray *allTouches = [touches allObjects];
CGPoint location = [[allTouches objectAtIndex:0] locationInView:self.view];
if(selected == 1) {
CGFloat rads = atan2f(location.y - (grid1.frame.size.height/2),location.x - (grid1.frame.size.width/2));
grid1.transform = grid1Btn.transform = CGAffineTransformMakeRotation(rads);
}
}
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
NSArray *allTouches = [touches allObjects];
CGPoint location = [[allTouches objectAtIndex:0] locationInView:self.view];
if(CGRectContainsPoint(grid1Btn.frame, location))
{
selected = 1;
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
selected = -1;
}
You use some frame.size.* in your computations. Note, that those values (unlike bounds.size.*) are affected by transform. Use grid1.center instead. It is also more logical (you rotate around center).
The next thing you need to fix is that it should not jump to new position when touches start :)
The jerkiness is caused by the inherent inaccuracy of touch event locations.
Touch events that are located sufficiently close to the center of the frame have a high likelihood of straying to the diagonally opposite quadrant of the frame whilst a circle is being traced about the center of the frame.
This will result in a sudden jump of 90 degrees as observed in your video.
One way to avoid the problem is to introduce a dead zone about the center of the frame. Any touch that is located within a given radius of the center of the frame would not trigger the rotation to be recalculated.
Hope this helps.
I am trying to make a simple landscape "split screen" app where two players can play at once (each player gets one half of the screen), but I am having trouble tracking both touches at the same time. This is the code I am trying to use:
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
CGPoint point = [touch locationInView:self.view];
if (point.x < 240) {
[player1 updatePoint:point];
} else {
[player2 updatePoint:point];
}
}
}
But I am obviously doing something wrong. Although this code works fine, it will only track one finger and move the player on the side of the screen the finger is on. What is my code lacking? Is this task more difficult to pull off then I think it is?
Did you set UIView's multipleTouchEnabled to YES?
multipleTouchEnabled should be set to YES for the UIView.
Im using the following code:
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
self.location = [touch locationInView:self.view];
NSLog(#"%#", NSStringFromCGPoint(location));
}
In order to try and find where the user might touch the screen, and i thought that [touches anyobject] would allow it to detect where the user has touched the screen even if another object has been selected. However when I select a button it seems that it is not the case. Could anyone help me out?
Thanks!
UIButtons by default "absorb" the touch, so you have to manually pass it along.
Check out this thread for more info:
Is there a way to pass touches through on the iPhone?