0

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.stack.imgur.com/1c6cX.png

iosDevSan
  • 65
  • 1
  • 13
  • rotationGesture.view and pinchGesture.view, are they UIImageViews? – SamB Sep 05 '21 at 12:16
  • @SamB Yes they are. – iosDevSan Sep 05 '21 at 12:24
  • I did few changes and now I am fetching the UIImageView() on viewControllerB (it has panned, scaled and rotated values with it). I added its frame value to VC-B Image view, but i am not able to understand what constraints should i add to keep the image at same position (to View1) on VC-A. Because its moving my image to diff positions depending on the constraints added on VC-B. How do i fetch same constraints from VC- A to VC- B. Can i get it in pan gesture? – iosDevSan Sep 05 '21 at 12:29
  • It will be much easier to offer help if you add your controller code. See [mre]. – DonMag Sep 05 '21 at 13:23
  • Edited the code in question. Added screenshot to understand what i tried. – iosDevSan Sep 05 '21 at 17:12

1 Answers1

0

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

SamB
  • 1,560
  • 1
  • 13
  • 19
  • Yes, I added it this way but the ImageView does not appear with same constraints or position as it is on the previous view controller. How do I get that same position in View Controller B? Can I get that from Pan Gesture? – iosDevSan Sep 05 '21 at 15:21
  • If you create a imageView2 with the same initial frame as imageView1(before any transforms applied to imageView1) then apply the transforms of imageView1 to imageViews2(by imageView2.transform = imageView1.transform, then they should be in the same shape and place of their respective viewControllers. If you have this flow and still it doesn't work, could you try removing auto layout constraints from UIImageView and setting a fixed frame initially. I am not entirely sure, but i think auto layout could have an unwantwd impact in this case. – SamB Sep 05 '21 at 16:10
  • I have added the same frame like imageView1.frame = imageView2.frame , I also tried adding transforms with and without adding the frame as you mentioned. Nothing is working. Now i am adding the width and height from the imageView1.frame to the constraints for imageView2. I am not able to place imageView2 at same place considering X, Y positions. [Tried with centerXAnchor, centerYAnchor, with constants as imageView1.frame.origin.x and imageView1.frame.origin.y] I don't know what is wrong here. Also, there are no auto layout constraints both imageViews – iosDevSan Sep 05 '21 at 16:18
  • Well, If you could post more code so I could reproduce this, i might be able to help you. – SamB Sep 05 '21 at 16:27
  • I have edited the code in question and also added an image for your reference to check what i tried. – iosDevSan Sep 05 '21 at 17:05
  • Added this code to ViewControllerB -(as per your above comment) let image_View: UIImageView = { let imageV = UIImageView() imageV.frame = fetchImageViewToTest.frame imageV.translatesAutoresizingMaskIntoConstraints = false imageV.image = image imageV.contentMode = .scaleAspectFill imageV.clipsToBounds = true imageV.transform = fetchImageViewToTest.transform return imageV }() View1.addSubview(image_View) – iosDevSan Sep 05 '21 at 17:31
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/236794/discussion-between-samb-and-sanchita). – SamB Sep 06 '21 at 02:51
  • yes sure i tried your solution and i still face some issues.Want to discuss it over chat. – iosDevSan Sep 06 '21 at 09:01