I have 2 view controllers,in which both have UIView added and UIImageView added programatically.In ViewControllerA-The image is scaled, panned and rotated. I want to show the same image with same scaled, panned and rotated value in ViewControllerB.I tried adding CGAffineTransform to ViewControllerB, but the image is getting more zoomed.Please help me achieve the image in exact same scaled, panned and rotated value on View controller B.Thanks.
ViewControllerA -
class ViewControllerA: UIViewController {
var imageViewToTest = UIImageView()
override func viewDidLoad() {
super.viewDidLoad()
createCanvas()
}
@IBAction func backBtnCanvas(_ sender: UIButton) {
let VC = self.storyboard?.instantiateViewController(withIdentifier: "ViewControllerB") as! ViewControllerB
VC.fetchImageViewToTest = imageViewToTest
let window = UIApplication.shared.windows.first
window?.rootViewController = VC
}
func createCanvas() {
let View1: UIView = {
let viewView = UIView()
viewView.translatesAutoresizingMaskIntoConstraints = false
viewView.contentMode = .scaleAspectFit
viewView.backgroundColor = .white
viewView.clipsToBounds = true
return viewView
}()
self.view.addSubview(View1)
View1.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0).isActive = true
View1.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 0).isActive = true
View1.widthAnchor.constraint(equalTo: view..widthAnchor, constant: 0).isActive = true
View1.heightAnchor.constraint(equalTo: view..widthAnchor, multiplier: 1.0).isActive = true
let image_View1: UIImageView = {
let image_View1= UIImageView()
image_View1.image = image. // Add any image you have
image_View1.contentMode = .scaleAspectFill
image_View1.translatesAutoresizingMaskIntoConstraints = false
image_View1.clipsToBounds = true
return image_View1
}()
View1.addSubview(image_View1)
image_View1.topAnchor.constraint(equalTo: View1.topAnchor, constant: 0).isActive = true
image_View1.bottomAnchor.constraint(equalTo: View1.bottomAnchor, constant: 0).isActive = true
image_View1.leadingAnchor.constraint(equalTo: View1.leadingAnchor, constant: 0).isActive = true
image_View1.trailingAnchor.constraint(equalTo: View1.trailingAnchor, constant: 0).isActive = true
self.imageViewToTest = image_View
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped(tapGestureRecognizer:)))
image_View1.isUserInteractionEnabled = true
image_View1.addGestureRecognizer(tapGestureRecognizer)
let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(pinchAction))
image_View1.addGestureRecognizer(pinchGesture)
let rotate = UIRotationGestureRecognizer(target: self, action: #selector(rotateAction))
image_View1.addGestureRecognizer(rotate)
if UserDefaults.standard.bool(forKey: "tapRecognizedForImage") == true {
createPanGestureRecognizer(targetView: image_View1)
}
}
@objc func imageTapped(tapGestureRecognizer: UITapGestureRecognizer) {
UserDefaults.standard.set(true, forKey: "tapRecognizedForImage")
}
//Pan Gesture for Image
func createPanGestureRecognizer(targetView: UIImageView) {
let panGesture = UIPanGestureRecognizer(target: self, action:#selector(handlePanGesture))
targetView.addGestureRecognizer(panGesture)
}
@objc func handlePanGesture(panGesture: UIPanGestureRecognizer) {
let imageView = panGesture.view as! UIImageView
let translation = panGesture.translation(in: view)
panGesture.setTranslation(CGPoint.zero, in: view)
self.translationX = translation.x
self.translationY = translation.y
imageView.center = CGPoint(x: imageView.center.x+translation.x, y: imageView.center.y+translation.y)
imageView.isMultipleTouchEnabled = true
imageView.isUserInteractionEnabled = true
switch panGesture.state {
case .began,.ended: break
case .changed:
self.positionX = imageView.center.x
self.positionY = imageView.center.y
break
default:
break
}
}
ViewControllerB -
class ViewControllerB: UIViewController {
var fetchImageViewToTest = UIImageView()
override func viewDidLoad() {
super.viewDidLoad()
createCanvas()
}
func createCanvas() {
let View1: UIView = {
let viewView = UIView()
viewView.translatesAutoresizingMaskIntoConstraints = false
viewView.contentMode = .scaleAspectFit
viewView.backgroundColor = .white
viewView.clipsToBounds = true
return viewView
}()
self.view.addSubview(View1)
View1.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0).isActive = true
View1.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 0).isActive = true
View1.widthAnchor.constraint(equalTo: view..widthAnchor, constant: 0).isActive = true
View1.heightAnchor.constraint(equalTo: view..widthAnchor, multiplier: 1.0).isActive = true
let image_View1: UIImageView = {
let image_View1= UIImageView()
image_View1.image = image. // Add any image you have
image_View1.contentMode = .scaleAspectFill
image_View1.translatesAutoresizingMaskIntoConstraints = false
image_View1.clipsToBounds = true
return image_View1
}()
View1.addSubview(image_View1)
image_View1.topAnchor.constraint(equalTo: View1.topAnchor, constant: 0).isActive = true
image_View1.bottomAnchor.constraint(equalTo: View1.bottomAnchor, constant: 0).isActive = true
image_View1.leadingAnchor.constraint(equalTo: View1.leadingAnchor, constant: 0).isActive = true
image_View1.trailingAnchor.constraint(equalTo: View1.trailingAnchor, constant: 0).isActive = true }
[![Screenshot of what I tried in my code for ViweControllerB][1]][1] [1]: https://i.sstatic.net/1c6cX.png
When you create the new UIImageView
in your secondViewController set it's transform
equals to firstImageView.transform
, which is already rotated/scaled etc. You don't have to apply CGAffineTransforms
to any other view in secondViewController
since you originally add the transforms to UIImageView
only. firstImageView.transform
has all the transformations you applied to it.
let image_View: UIImageView = {
let imageV = UIImageView()
imageV.image = image
imageV.translatesAutoresizingMaskIntoConstraints = false
imageV.contentMode = .scaleAspectFill
imageV.clipsToBounds = true
imageV.transform = firstImageView.transform
return imageV
}()
I have added a sample Swift Playground code with the idea
import UIKit
import PlaygroundSupport
let containerView = UIView(frame: CGRect(x: 0, y: 0, width: 500, height: 600))
let view1 = UIView(frame: CGRect(x: 0, y: 0, width: 500, height: 300))
view1.backgroundColor = .systemYellow
let image_view1: UIImageView = {
let image_View1 = UIImageView()
image_View1.frame = CGRect(x: 100, y: 100, width: 100, height: 100)
image_View1.image = UIImage(systemName: "trash.fill")
image_View1.contentMode = .scaleAspectFill
image_View1.clipsToBounds = true
return image_View1
}()
//add transforms to the image_view1 (from panGestures, rotationGesture etc)
image_view1.transform = image_view1.transform.concatenating(CGAffineTransform(scaleX: 1.2, y: 1.2)).concatenating(CGAffineTransform(rotationAngle: 0.5))
.concatenating(CGAffineTransform(translationX: 50, y: 50))
view1.addSubview(image_view1)
//create view2
let view2 = UIView(frame: CGRect(x: 0, y: 300, width: 500, height: 300))
view2.backgroundColor = .green
let image_view2: UIImageView = {
let image_view2 = UIImageView()
image_view2.frame = CGRect(x: 100, y: 100, width: 100, height: 100)
image_view2.image = UIImage(systemName: "trash.fill")
//copy transforms from image_view1
image_view2.transform = image_view1.transform
image_view2.contentMode = .scaleAspectFill
image_view2.clipsToBounds = true
return image_view2
}()
view2.addSubview(image_view2)
containerView.addSubview(view1)
containerView.addSubview(view2)
PlaygroundPage.current.liveView = containerView
Below is how it looks like in Playground when you run this. The yellow view has the image_view1
with transformations and green view creates a new image_view2
and use the transforms from the image_view1