Upvote:2

class ViewController: UIViewController {
    
    let viewA: UIView = {
        let v = UIView()
        v.backgroundColor = .systemYellow
        return v
    }()
    
    let viewARedView: UIView = {
        let v = UIView()
        v.backgroundColor = .systemRed
        return v
    }()
    
    let viewABlueView: UIView = {
        let v = UIView()
        v.backgroundColor = .systemBlue
        return v
    }()
    
    let viewB: UIView = {
        let v = UIView()
        v.backgroundColor = .systemYellow
        return v
    }()

    let viewBRedView: UIView = {
        let v = UIView()
        v.backgroundColor = .systemRed
        return v
    }()
    
    let viewBBlueView: UIView = {
        let v = UIView()
        v.backgroundColor = .systemBlue
        return v
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        navigationController?.setNavigationBarHidden(true, animated: false)
        
        view.addSubview(viewA)
        view.addSubview(viewB)
        
        viewA.frame = CGRect(x: 20, y: 60, width: 200, height: 200)
        viewB.frame = CGRect(x: 20, y: viewA.frame.maxY + 20, width: 600, height: 600)

        viewA.addSubview(viewARedView)
        viewA.addSubview(viewABlueView)

        let origRect: CGRect = CGRect(x: 30, y: 20, width: 50, height: 25)
        
        // set frames of red and blue rect to the same rectangles
        // so blue is on top of red
        //  we're going to transform the blue rect
        viewARedView.frame = origRect
        viewABlueView.frame = origRect

        // scale values
        let scX: CGFloat = 2.25
        let scY: CGFloat = 1.75
        // translate values
        let trX: CGFloat = 30.0
        let trY: CGFloat = 100.0
        // rotation value
        let rot: CGFloat = .pi * -0.15
        
        var tx: CGAffineTransform = .identity
        // scale it
        tx = tx.concatenating(CGAffineTransform(scaleX: scX, y: scY))
        // move it
        tx = tx.concatenating(CGAffineTransform(translationX: trX, y: trY))
        // rotate it
        tx = tx.concatenating(CGAffineTransform(rotationAngle: rot))

        // apply the transform
        viewABlueView.transform = tx
        
        viewB.addSubview(viewBRedView)
        viewB.addSubview(viewBBlueView)
        
        // get the scale factor...
        //  in this case,
        //      viewA width is 200
        //      viewB width is 700
        //  so viewB is 3.5 times bigger (700 / 200)
        let scaleFactor: CGFloat = viewB.frame.width / viewA.frame.width
        
        // make the original rect origin and size
        //  "scaleFactor bigger"
        let newRect: CGRect = CGRect(x: origRect.origin.x * scaleFactor,
                                     y: origRect.origin.y * scaleFactor,
                                     width: origRect.width * scaleFactor,
                                     height: origRect.height * scaleFactor)
        
        // set frames of red and blue rect to the same rectangles
        // so blue is on top of red
        //  we're going to transform the blue rect
        viewBRedView.frame = newRect
        viewBBlueView.frame = newRect
        
        // scale the translation values
        let trXb: CGFloat = trX * scaleFactor
        let trYb: CGFloat = trY * scaleFactor

        var txb: CGAffineTransform = .identity
        // we've already changed the initial size of the rectangle,
        //  so use same scaling values
        txb = txb.concatenating(CGAffineTransform(scaleX: scX, y: scY))
        
        // we need to use scaled translation values
        txb = txb.concatenating(CGAffineTransform(translationX: trXb, y: trYb))
        
        // rotation doesn't change based on scale
        txb = txb.concatenating(CGAffineTransform(rotationAngle: rot))

        // apply the transform
        viewBBlueView.transform = txb
        
    }
}

Credit Goes to: stackoverflow.com

Related question with same questions but different answers