iosDevSan
iosDevSan

Reputation: 65

How to add a scaled, panned and rotated image from one view controller to another in exact same way as its scaled, panned and rotated, in Swift?

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

Upvotes: 0

Views: 79

Answers (1)

SamB
SamB

Reputation: 1710

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

enter image description here

Upvotes: 0

Related Questions