Animating a zoomScale on UIScrollView with Swift - ios

Relatively new to iOS apps, and swift, so I'm a little lost on how to proceed.
Basically, I have a UIImageView, and i'm able to pinch to zoom/scroll, as my UIImageView is in a UIScrollView, but I'd like to add a double tap on the UIImage to zoom in as well.
I'm able to zoom in (just set the zoomScale to 3.0 for now), but I'd like to have a smooth transition. I did see the zoom(to:, animated:) method, but I wasn't quite sure on how to zoom into the center of the view.
Anyways, here's what I have thus far.
I've created the tapGestureRecognizer, and assigned it to the UIImageView
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapImageViewGesture))
self.Image1.isUserInteractionEnabled = true
self.Image1.addGestureRecognizer(tapGesture)
and below is the function to perform the zoom
func tapImageViewGesture(sender: UITapGestureRecognizer) {
print("Touched")
self.pinchZoomScroll1.zoomScale = 3.0
}
Is there a simple way I can have some sort of a smooth animation of zooming in?, or should I go with using the zoom function instead, as it already supports animation?
Thank you!!

Either you can set set animation true by using this :
self.pinchZoomScroll1.setZoomScale(3.0, animated: true)
or you can also use scrollView delegate func by setting scrollViewminimumScale and max scale:
pinchZoomScroll1.minimumZoomScale = 1.0
pinchZoomScroll1.maximumZoomScale = 6.0
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return Image1
}

Related

PDFview scrollview zoom

I am working in pdf editing project, in that I have to add signature in pdfview and after that need to resize and delete that signature. Now for this I am adding one scrollview with UIView on top of pdfview with transparent alpha and add image view to that UIView but I had an issue with zooming. How can I get how much zoom pdfview zooming when user pinch zoom. I want to find pdfview's zoom contentInset, so I can set my own scrollview's contentInset.
try to get pdfview scale factor when pdfview zoom with :
#objc func pdfViewScaleChange(notification:NSNotification){
print(self.pdfView.scaleFactor)
}
But Still I can't find How can I zoom and set my UIScrollview as pdfview zoom.
Your PDFView has a property called scaleFactorForSizeToFit, which is the scale factor that PDFKits autoScales would use for scaling the current document and layout.
What this means is that if you use the autoScales property when you set your pdf you will be able to calculate an amount to scale your UIScrollview by.
Here is an example of what I mean for some more context:
//wherever you set your pdf (doesn't have to be viewDidAppear)
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
pdfView.document = PDFDocument(data: data)
pdfView.autoScales = true
//Add the observer here to detect when your pdf is zoomed in or out
NotificationCenter.default.addObserver(self,
selector: #selector(pdfPageWasZoomed),
name: Notification.Name.PDFViewPageChanged,
object: nil)
}
//wherever you want to zoom use this
func getScrollViewScaleFactor() -> CGFloat {
return (pdfView.scaleFactor / pdfView.scaleFactorForSizeToFit)
}
//Objc function which is called everytime the zoom changes
#objc private func pdfPageWasZoomed() {
//Here use the function getScrollViewScaleFactor() to get a factor to scale in or out by
}
Something like this should solve your problem.

Is there a way to pinch and zoom a programmatically added image?

I am trying to figure out how to add pinch/zoom capabilities to an imageView,
but specifically to one that I added to the scrollView programmatically. I was able to find some great examples on SO to pinch and zoom an image using a scrollview with viewForZooming, but in that instance I had to return the image view being pinched and zoomed, which doesn't work if I am returning it programatically.
My ultimate goal is to have an array of images where the user can scroll left and right to see all the images AND be able to zoom in on them, basically just as if they were flipping through their photoStream. I found an ok tutorial for adding the images dynamically for scrolling here https://www.codementor.io/taiwoadedotun/ios-swift-implementing-photos-app-image-scrolling-with-scroll-views-bkbcmrgz5#comments-bkbcmrgz5 but I am not clear how to add the viewForZooming since the image views are being .addSubview dynamically in a loop.
I created a little example with a collection view of 0-n images associated to a post. Once the collectionViewCell with the image is tapped a hidden scrollView appears with a new dynamic UIImageView added as a subView. All works great but I don't know how to add the pinch/zoom now.
#objc func imageTapped(_ sender: UITapGestureRecognizer) {
print("BlipeFile Image Tapped")
let imageView = sender.view as! UIImageView
let newImageView = UIImageView(image: imageView.image)
//newImageView.frame = UIScreen.main.bounds
newImageView.contentMode = .scaleAspectFit
newImageView.clipsToBounds = true
newImageView.layer.borderColor = UIColor.gray.cgColor
newImageView.layer.borderWidth = 3.0
newImageView.frame = self.view.frame
newImageView.backgroundColor = .black
newImageView.isUserInteractionEnabled = true
newImageView.image = imageView.image
let tap = UITapGestureRecognizer(target: self, action: #selector(dismissFullscreenImage))
newImageView.addGestureRecognizer(tap)
scroller.isHidden = false
scroller.addSubview(newImageView)
}
#objc func dismissFullscreenImage(_ sender: UITapGestureRecognizer) {
scroller.isHidden = true
self.navigationController?.isNavigationBarHidden = false
self.tabBarController?.tabBar.isHidden = false
sender.view?.removeFromSuperview()
}
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return image //Can't return dynamically created newImageView?
}
My ultimate goal is to have an array of images where the user can scroll left and right to see all the images AND be able to zoom in on them
Apple has explained many times, in WWDC videos and in sample code that you can download, how this is done. Basically it’s just a scroll view in a scroll view. The outer scroll view permits scrolling horizontally. The inner scroll view contains an image view and permits zooming.
So instead of adding an image view, add a scroll view containing an image view.

Block size image when I enlarge the view

I have a view and within an image that works as a button. I would like to know if there is a way to lock the size of the button so that when I zoom in, the view remains small and does not enlarge with the view..
I thought it was hard to manager in the beginning. But finally, if you put the imageView in a UIScrollView, It's not hard to achieve.
The idea is move the buttonView outside of imageView during zooming and when zoom is over, put it back to imageView to pretend nothing happened. I know it's too verbose in programming but actually it works perfectly for your case.
var originalCenter : CGPoint! // The center of ButtonView in imageView.
//All functions are from the UIScrollViewDelegate.
func viewForZooming(in scrollView: UIScrollView) -> UIView?{
originalCenter = buttonView.center // remember the original position.
return imageView
}
func scrollViewWillBeginZooming(_ scrollView: UIScrollView, with view: UIView?) {
buttonView.frame = imageView.convert(buttonView.frame, to: scrollView)
scrollView.addSubview(buttonView)//add to superView of imageImage.
}
func scrollViewDidZoom(_ scrollView: UIScrollView){
buttonView.center = imageView.convert(originalCenter, to: scrollView) //During Zooming, update the buttonView in ScrollView.
}
func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat){
buttonView.frame = imageView.convert(buttonView.frame, from: scrollView)
imageView.addSubview(buttonView) //put it back.
}
I know it's better to use a parameter to control such operation. But I have-not found one according to public APIs. Maybe there is a better way, hope this one is your answer too.
Because you called transform for superView. It will make all subViews inside transform together.
You need to remake you views:
SuperView:
- Content view (the image view)
- Border view
- Button close
When you want to zoom the image, you only need to reset the superview frame.
You found a git SPUserResizableView.

UIScrollView - zoom all subviews inside (not only one)

Good Evening!
I am trying to zoom UIScrollView, more specific all sub-views placed inside.
As far I understand, I need to implement UIScrollViewDelegate method:
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
return subView // <--- subview inside my scroll view
}
In my test projects zoom simply won't work until I do this. But, with this technique I can only zoom (1) single view. My scroll-view have dozens of sub-views which I want to be zoomed too. I can solve this by placing one UIView inside UIScrollView and then other sub-views inside this container view, but I will like to ask is there better solution?
I have used both automatic mechanism of pinch-to-zoom of scrollview and later played with my own pinch gesture recogniser:
override func viewDidLoad() {
super.viewDidLoad()
...
let pinchGesture = UIPinchGestureRecognizer(target: self, action: "pinchHandler:")
scrollView.addGestureRecognizer(pinchGesture)
.
.
.
func pinchHandler(recognizer: UIPinchGestureRecognizer)
{
if recognizer.state == UIGestureRecognizerState.Began
{
if recognizer.scale < 1.0 {
scrollView.setZoomScale(1, animated: true)
} else {
scrollView.setZoomScale(2, animated: true)
}
}
}
In both cases, only 1 view is zoomed (one passed as result of viewForZoomingInScrollView function)
Thank you.

Best way to implement view like map

I'm making view that represent something like map, with pan and pinch gestures.
At current moment it's implemented via overriden drawRect that called in handlePan with setNeedsDisplay.
So, the resulting performance a little bit awkward. Is there any more appropriate approaches?
So, more appropriate solution here is UIScrollView.
To get it work:
Set up scrollView delegate, like
scrollView.delegate = self
Implement
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView?
{
return fieldView
}
Optionally, you can set
scrollView.minimumZoomScale = scrollView.frame.width /
fieldView.frame.width
scrollView.maximumZoomScale = 2
Where fieldView is target custom view:
fieldView = FieldView(frame: frameRect)
scrollView.addSubview(fieldView)
scrollView.contentSize = frameRect.size

Resources