I currently have two buttons on my screen , one on the left and one on the right , I wanted to know if there is a way in the iOS Simulator to simulate both buttons being pressed at the same time. I tried pressing ⌥ Alt on the simulator as a result two circles appear. I can position one circle to the first button on the left however I am not sure how to position the next circle on the right button.
Once you have the two circles (using the Alt key), move the circles together, then hold the shift key: this will allow you to move the two circles anywhere on the simulator screen.
Then let go the key and click.
I just tried it with this code:
-(void)tapTwo:(UITapGestureRecognizer*)recognizer
{
CGPoint p1 = [recognizer locationOfTouch:0 inView:self.view];
CGPoint p2 = [recognizer locationOfTouch:1 inView:self.view];
NSLog(#"Points: %# and %#",NSStringFromCGPoint(p1),NSStringFromCGPoint(p2));
}
- (void)viewDidLoad {
[super viewDidLoad];
UITapGestureRecognizer* r = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapTwo:)];
r.numberOfTouchesRequired = 2;
[self.view addGestureRecognizer:r];
}
and it worked as expected.
For the two Circles, all you need to do is click windows + alt button together and to move those two circles to desired position you need to press shift button and drag your cursor to that position.
(The solution is for windows keyboard)
Related
I have a UIImageView placed with frame (0,0,320,200).
i have added touch drag to it using simple gesture.
- (void)touchesMoved:(NSSet *)set withEvent:(UIEvent *)event {
CGPoint p = [[set anyObject] locationInView:self.superview];
self.center = p;
}
It works fine, however as soon as i drag it to bottom of screen let's say and remove my finger and then try to touch it, it stops detecting touch on the view and start detecting touch on the views on the screen. Now this imageView is placed on top of all views so i am not sure even its dragged why it doesn't get touches ,
Now if somehow using any button make it move ot its original position it starts detecting touch again.
So whats going on here?
Set up a gestureRecognizer within your viewDidLoad method for example.
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(wasDragged:)];
[YourImageView addGestureRecognizer:panRecognizer];
Once your ImageView has been moved the gestureRecognizer object will fire the target method you created wasDragged: and from within here you can update the view's position.
- (void)wasDragged:(UIPanGestureRecognizer *)recognizer {
UIImagewView *imageView = (UIImagewView *)recognizer.view;
CGPoint translation = [recognizer translationInView:imageView];
imageView.center = CGPointMake(imageView.center.x + translation.x, imageView.center.y + translation.y);
[recognizer setTranslation:CGPointZero inView:imageView];
}
After this has been dragged to the bottom of the screen as you say, you should be able to drag it again from the position you last left it in.
I hope this helps.
I have the following gesture recognizer in my app. I've looked at xCode7 UI and see that it has swipe up/down/left/right, but no pan or edge pan gestures.
How can one test or initiate screen edge pan gesture for UITesting purposes?
UIScreenEdgePanGestureRecognizer *leftEdgeGesture = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:#selector(show)];
leftEdgeGesture.edges = UIRectEdgeLeft;
leftEdgeGesture.delegate = self;
[self.view addGestureRecognizer:leftEdgeGesture];
I spent a while trying to figure this out, navigating around the element hierarchy. Lots and lots of googling and finding nothing.
I gave up twice, then figured it out.
We just need two coords on the main app screen, and drag one to the other.
Works a treat!
XCUIApplication *app = [[XCUIApplication alloc] init];
[app launch];
// Set a coordinate near the left-edge, we have to use normalized coords
// so you set using percentages, 1% in on the left, 15% down from the top
XCUICoordinate *coord1 = [app coordinateWithNormalizedOffset:CGVectorMake(0.01, 0.15)];
// Then second coordinate 40 points to the right
XCUICoordinate *coord2 = [coord1 coordinateWithOffset:CGVectorMake(40, 0)];
// Perform a drag from coord1 to coord2
// Simulating swipe in from left edge
[coord1 pressForDuration:0.5f thenDragToCoordinate:coord2];
Hopefully this will help everyone else who has been struggling to simulate an edge swipe.
Piggybacking on Chris' awesome answer, here's the swift version:
func pressCoordinate(x xCoordinate: Double, y yCoordinate: Double, app2call: XCUIApplication=XCUIApplication())
{
let normalized = app2call.coordinate(withNormalizedOffset: CGVector(dx: 0.01, dy: 0.5))
let coordinate = normalized.withOffset(CGVector(dx: xCoordinate, dy: yCoordinate))
normalized.press(forDuration: 0.5, thenDragTo: coordinate)
}
In iPad when you put your finger outside top or bottom edge of screen and then drag it on screen a menu is revealed. How can I implement that?
There is specifically a Gesture Recogniser class for this, introduced in iOS 7. It's the UIScreenEdgePanGestureRecognizer. The documentation for it is here. Check it out.
To test this in the simulator, just start the drag from near the edge (~15 points).
Also, you will have to create a gestureRecognizer for each edge. You can't OR edges together, so UIRectEdgeAll won't work.
There is a simple example here. Hope this helps!
Well you can do something like this, this example is the case where you want you pan gesture to work only when the user swipes 20px inside from the right hand side of the screen
First of all add the gesture to your window
- (void)addGestures {
if (!_panGesture) {
_panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePanGesture:)];
[_panGesture setDelegate:self];
[self.view addGestureRecognizer:_panGesture];
}
}
After adding the check whether the touch you recieved is a pan gesture and then perform your action accordingly
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
CGPoint point = [touch locationInView:self.view];
if (gestureRecognizer == _panGesture) {
return [self slideMenuForGestureRecognizer:gestureRecognizer withTouchPoint:point];
}
return YES;
}
Here is how you can check whether your touch is contained in the region where you want it to be
-(BOOL)isPointContainedWithinBezelRect:(CGPoint)point {
CGRect leftBezelRect;
CGRect tempRect;
//this will be the width between CGRectMaxXEdge and the screen offset, thus identifying teh region
CGFloat bezelWidth =20.0;
CGRectDivide(self.view.bounds, &leftBezelRect, &tempRect, bezelWidth, CGRectMaxXEdge);
return CGRectContainsPoint(leftBezelRect, point);
}
I'm having trouble getting a repeatable background to work in my game menu.
The user can slide a finger across the screen to select a character to play.
I have a parallax effect working with various backgrounds as the characters slide into view.
Sample below.
- (void)didMoveToView:(SKView *)view
{
self.pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:#selector(dragScene:)];
self.pan.minimumNumberOfTouches = 1;
self.pan.delegate = self;
[self.view addGestureRecognizer:self.pan];
}
- (void)dragScene:(UIPanGestureRecognizer *)gesture
{
CGPoint trans = [gesture translationInView:self.view];
SKAction *moveSky = [SKAction moveByX:trans.x*0.03 y:0 duration:0];
[_skyBackground runAction:moveSky];
}
I would like to repeat the backgrounds. I know how to do this with automatically scrolling backgrounds but I can't seem to get it to work here. It needs to repeat in both directions, left and right.
Thanks for any help!
You can create two more background nodes - one to the left of your current background node and one to the right. Move them aswell any time you move your existing _skyBackground node.
Then, in the update method, check if any of the three nodes needs to be "shifted" - either to behind the other two or in front. You're basically swapping the three nodes' positions if needed.
-(void)update:(NSTimeInterval)currentTime {
//get the left background node (or if using an ivar just use _leftNode)
SKSpriteNode *leftNode = (SKSpriteNode*)[self childNodeWithName:#"leftNode"];
//my positioning might be off but you'll get the idea
if (leftNode.position.x < -leftNode.size.width*2)
{
leftNode.position = CGPointMake(leftNode.size.width, leftNode.position.y);
}
if (leftNode.position.x > leftNode.size.width*2)
{
leftNode.position = CGPointMake(-leftNode.size.width, leftNode.position.y);
}
//repeat the same for _skyBackground and _rightNode
}
You may need more than 3 images if there's a slight gap between images as they're shifted.
I have an application that allows a user to pan and zoom in on an image. I think that, without too much trouble, the user can get themselves into a state where they are zoomed in to one portion of the image, and would want to reset everything back to the 'ground state' (ie, bring all the translation and rescaling back to 0 and 1, respectively).
I'm doing translation by:
- (void)panGestureRecognized:(UIPanGestureRecognizer *)recognizer
{
CGPoint translation = [recognizer translationInView:self.view];
recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x,
recognizer.view.center.y + translation.y);
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
}
And this works fine, I can translate the image.
If I press the button, I want to be able to change the translation back to 0,0. One way to do this would seem to be to store the gesturerecognizer and set that back to zero, as in:
mPanRecognizer.view.center = CGPointMake(mPanRecognizer.view.center.x,
mPanRecognizer.view.center.y);
[mPanRecognizer setTranslation:CGPointMake(0,0) inView:self.view];
Where mPanRecognizer is a member variable storing the recognizer. However, doing this produces the following log information, with no actual behavioral change:
Ignoring call to [UIPanGestureRecognizer setTranslation:inView:] since gesture recognizer is not active.
So how can I reset the gesture to be translating to 0,0 by pressing a button?
This can be done without using gesture recognizers. To set the scaling, use
[self.view setBound:CGRectMake(0,0,width,height)];
where width and height are the dimensions of your device.
To set the translation, use
[self.view setCenter:CGPointMake(width/2.0,height/2.0)];
To set your width and height easily, contain your view in a separate UIView. Have that UIView anchored properly and in the proper z-order, then you can modify the above lines to be
[imageView setBounds:CGRectMake(0,0,imageView.superview.bounds.size.width,imageView.superview.bounds.size.height)];
[imageView setCenter:CGPointMake(imageView.superview.center.x, imageView.superview.center.y)];
thereby avoiding the need for storying of any points or magic numbers specific to a particular device.