ios - CGAffineTransform:同时应用平移和缩放

标签 ios swift xcode cgaffinetransform uianimation

我有两个UILabel s。屏幕左侧较大,右侧较小。

我正在尝试使用CGAffineTransform以动画方式将较小的标签移动到较大标签的位置并将其缩放到相同大小,然后将较大的标签移出屏幕。

我实际上并没有移动标签,动画完成后,我更改了标签上的文本属性,并将它们的转换设置为 identity .

我的问题是我不知道如何计算必须翻译较小标签的确切 x 和 y 值。我认为我得到的值不准确,因为我在翻译标签的同时缩放标签,并且 txty值是根据较小标签的非缩放尺寸计算的。

我目前所做的事情: tx :较大标签的宽度+它与较小标签之间的距离,ty :y轴上两个标签中心之间的距离

最佳答案

有多种方法可以做到这一点 - 这是一种......

首先计算平移值和比例值,然后将它们连接起来:

    let translation = CGAffineTransform(translationX: xMove, y: yMove)
    let scaling = CGAffineTransform(scaleX: xScale, y: yScale)
    
    let fullTransform = scaling.concatenating(translation)
    

这是一个完整的示例...我们添加了两个具有不同字体大小、位置和背景颜色的标签(以使其易于查看)。点击任意位置即可运行变换动画:

class ViewController: UIViewController {

    let labelA = UILabel()
    let labelB = UILabel()
    
    var aTop: NSLayoutConstraint!
    var aLeading: NSLayoutConstraint!

    var bTop: NSLayoutConstraint!
    var bLeading: NSLayoutConstraint!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        [labelA, labelB].forEach { v in
            v.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview(v)
        }
        
        labelA.text = "Label A"
        labelB.text = "Label B"
        
        labelA.backgroundColor = .green
        labelB.backgroundColor = .cyan
        
        labelA.font = .systemFont(ofSize: 40.0)
        labelB.font = .systemFont(ofSize: 20.0)

        // respect safe area
        let g = view.safeAreaLayoutGuide
        
        aTop = labelA.topAnchor.constraint(equalTo: g.topAnchor, constant: 100.0)
        aLeading = labelA.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 40.0)
        
        bTop = labelB.topAnchor.constraint(equalTo: g.topAnchor, constant: 300.0)
        bLeading = labelB.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 240.0)
        
        NSLayoutConstraint.activate([
            aTop, aLeading,
            bTop, bLeading,
        ])
        
        let t = UITapGestureRecognizer(target: self, action: #selector(self.doAnim(_:)))
        view.addGestureRecognizer(t)
        
    }
    
    @objc func doAnim(_ g: UITapGestureRecognizer?) -> Void {
        
        let targetPoint = labelA.center
        let originPoint = labelB.center
        
        let xMove = targetPoint.x - originPoint.x
        let yMove = targetPoint.y - originPoint.y

        let xScale = labelA.frame.width / labelB.frame.width
        let yScale = labelA.frame.height / labelB.frame.height
        
        let translation = CGAffineTransform(translationX: xMove, y: yMove)
        let scaling = CGAffineTransform(scaleX: xScale, y: yScale)
        
        let fullTransform = scaling.concatenating(translation)
        
        UIView.animate(withDuration: 1.0, animations: {
            self.labelB.transform = fullTransform
        }) { [weak self] b in
            guard let self = self else { return }
            self.labelB.transform = .identity
            self.labelB.font = self.labelA.font
            self.bTop.constant = self.aTop.constant
            self.bLeading.constant = self.aLeading.constant
        }

    }
    
}

关于ios - CGAffineTransform:同时应用平移和缩放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66409356/

相关文章:

swift - 使用私有(private) Google 存储的 Firebase iOS SDK 身份验证

ios - Storyboard上的 Xcode 5 与 iOS 5 问题

ios - XCode 如何在文件夹中组织 Assets

ios - 部署旧版本的 iOS 应用程序

ios - 如何阅读plist

ios - 如何将方法调用延迟 1 秒?

android - 如何在 Flutter 中使 Expanded 中的文本可滚动

swift - 快速以编程方式导航 View Controller

ios - 运行时隐藏/显示状态栏 iOS 9+

ios - 无法分配给属性 : 'width' is a get-only property