All,
I have studied Gesture Recognisers and I have placed one in Interface builder and I am going to wire it all up. I have also enabled 'User Interaction Enabled' in IB on the UIImage.
How can I make the UIImage larger according to how far the finger is swiped down on the screen.
How can I make the UIImage larger in the UIView that it sites in ?
This code works for me, I'm using UIPinchGestureRecognizer, which is use as a default if you want to scale the view:
#IBAction func handlePinch(recognizer : UIPinchGestureRecognizer) {
recognizer.view!.transform = CGAffineTransformScale(recognizer.view!.transform, recognizer.scale, recognizer.scale)
// Reset recognizer scale
recognizer.scale = 1
}
If you want to use swipe gesture, you need to calculate swipe difference between start point and current swipe point and convert it to scale value you required.
Related
If I am using the default camera control in SceneKit, is there a way to disable the two fingered pan function and leave the others as they are?
I want users to be able to rotate and zoom an object, but not move it at all.
The sceneView already has a UIPanGestureRecognizer attached.
If you modify its maximumNumberOfTouches to be 1, you can disable the pan gesture.
for reco in sceneView.gestureRecognizers! {
if let panReco = reco as? UIPanGestureRecognizer {
panReco.maximumNumberOfTouches = 1
}
}
No. You'll have to make your own camera and use gesture recognizers.
I have a horizontal scrollview with an image which I need to rotate as the user scrolls left or right. It needs to rotate as the user moves the scroll across the screen. So if the user scrolls half way and stops the image should rotate halfway etc. I have looked at few examples but nothing seems to be giving me the correct result. Can some one please help.
Thanks in advance
Vertical scrolling and Swift 5:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let topOffset = scrollView.contentOffset.y
let angle = -topOffset * 2 * CGFloat(Double.pi / 180)
self.myImageView.transform = CGAffineTransform(rotationAngle: angle)
}
Don't forget to do this in viewDidLoad:
self.scrollView.delegate = self
You'll need to implement the scrollViewDidScroll method and then apply a rotation matrix to the image. To rotate a UIIMage you can do what they outline here. How to Rotate a UIImage 90 degrees?
However, this would be better accomplished in a pan gesture recognizer. The pan gesture will give you information about how far the user panned, and then you can rotate the image based on that distance.
To rotate image is not good for performance. You'd better set image view's rotate transform as user scrolls. Like this:
imageView.transform = CGAffineTransformMakeRotation(CGFloat(M_PI_2))
This is what I currently have:
func handlePinching(recognizer : UIPinchGestureRecognizer) {
self.layer.transform = CATransform3DMakeAffineTransform(CGAffineTransformScale(self.transform, recognizer.scale, recognizer.scale));
recognizer.scale = 1.0;
}
Using self.view.transform for that also makes it bigger. I want to make it zoom "internally" (I really don't know how to explain it).
So I'm not 100% sure to understand the question but I guess I get it.
For example you want to zoom on an image without zooming the other element of the UI (NavBar, Buttons, ...) right?
So I guess in you're example you're in a viewController, which means, when you change the scale of self.view you'll zoom everything. You have to apply the scale on the specific view that you want to zoom in.
In the example below, to zoom on the image, the image is inside of an UIImageView, and this imageView is subView of self.view. And you will just apply a transform on this imageView.
Moreover I think you get a little bit confused on how to zoom, considering the view you want to zoom is imageView you just need to do
imageView.transform = CGAffineTransformMakeScale(recognizer.scale,recognizer.scale)
I hope this answer your question, let me know if something is not clear.
I have a UIView in my ViewController that users can move around the screen, rotate and zoom in and out. All with UIGestureRecognizers.
The problem I have is that the UIView contains a UILabel and after zooming the label is very blurry.
Here is the code for the zoom:
#IBAction func handlePinch(recognizer : UIPinchGestureRecognizer) {
recognizer.view!.transform = CGAffineTransformScale(recognizer.view!.transform, recognizer.scale, recognizer.scale)
recognizer.scale = 1
}
Also, when the user leaves the screen I am saving the new location and transformation of the UIView like this:
func saveViewValues() {
var userDefaults:NSUserDefaults = NSUserDefaults.standardUserDefaults()
userDefaults.setObject(NSStringFromCGPoint(self.theView.center), forKey:kViewCenter)
userDefaults.setObject(NSStringFromCGAffineTransform(self.theView.transform), forKey:kViewTransform)
userDefaults.synchronize()
}
This way when I reload the page I can use these values to reset the UIView to how the user last had it.
All works fine however the UILabel is very blurry if the user zooms in on the view.
Is there a way I can make the text crisp, even when zoomed? And how do I save this value like the others so that it can be put back afterwards and be crisp straight away?
Hope this makes sense.
I need to crop an image to match a specific dimension. I have three layers in my view starting from the bottom:
I have the raw image in a UIImage. This image comes from the camera. (called cameraImage)
I have a UIView holding this image. When user clicks "crop", the UIView's bounds are used to crop the raw image inside it.
Above all of this I have a guide image which shows the user the dimensions they need to pan, rotate, and pinch their image to fit into.
I want to add the pan gesture to the top guide image and have it control the raw image at the bottom. So the guide image never moves but it is listening for the pan gesture.
I can't figure out how to reset the recognizer without it making my raw image jump back to zero. Maybe someone could help?
- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer {
CGPoint translation = [recognizer translationInView:recognizer.view];
recognizer.view.center = CGPointMake(recognizer.view.center.x+translation.x, recognizer.view.center.y+ translation.y);
[recognizer setTranslation:CGPointMake(0, 0) inView:recognizer.view];
}
The above code works great in my gesture is attached to the bottom image. The problem is when the user goes outside the view's bounds, the image stops panning and is basically stuck. You can't touch it anymore so it sits there. So I thought if i attached the gesture to the top it would solve this problem.
- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer {
CGPoint translation = [recognizer translationInView:recognizer.view];
cameraImage.center = CGPointMake(recognizer.view.center.x+translation.x, recognizer.view.center.y+ translation.y);
}
This almost works. I set the cameraImage's center and removed the third line which resets the recognizer. If I don't remove it, the cameraImage jumps back into the same position every time I try and pan. It almost works because when you click the image again it doesn't start from the pixel you touched. It moves the image back to the original position and then lets you pan.
First option:
when the recognizer enter the UIGestureRecognizerStateEndedstate
if(recofnizer.state == UIGestureRecognizerStateEnded )
{
...
}
You store the translation at that point in time in an instance varibale (#property) of your class.
And then you always add the saved translation to the new translation.
In code this would look like this:
- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer {
CGPoint translation = [recognizer translationInView:recognizer.view];
CGPoint updatedTranslation = CGPointMake(translation.x+self.savedTranslation.x,translation.y+self.savedTranslation.y);
cameraImage.center = CGPointMake(recognizer.view.center.x+updatedTranslation.x, recognizer.view.center.y+ updatedTranslation.y);
if(recofnizer.state == UIGestureRecognizerStateEnded )
{
self.savedTranslation = updatedTranslation;
}
}
Dont forget to add #property (nonatomic, assign) CGPoint savedTranslation; to your interface.
Also make sure the savedTranslation variable is initialized in the init method of your class to self.savedTranslation = CGPointMake(0,0);
Second option:
You should think about doing all that what you want in an scrollview with the imageview as the viewForZooming of the scrollview. This allows very smooth interaction, like users are used to!
Above this scrollview you can then put your mask/guide, but make sure to disable the userInteraction of the mask/guide view to make your user touch the scrollview below!