【问题标题】:CGAffineTransform rotation causes a switch between width and height when defining SnapKit values定义 SnapKit 值时,CGAffineTransform 旋转会导致宽度和高度之间的切换
【发布时间】:2019-09-16 23:31:43
【问题描述】:

我相当习惯使用 SnapKit,但我不知道如何解决这个问题。

这是我当前 UI 的样子:

为了实现这一点,我这样做:

 override func viewDidLoad() {
        super.viewDidLoad()

 regionsPicker.snp.makeConstraints { (make) in
            make.centerX.equalToSuperview()
            make.height.equalToSuperview() // since we rotate (this is the width)
            make.top.equalTo(regionsLabel.snp.bottom).offset(15)
            make.width.equalTo(100)
        }
 rotationAngle = -90 * (.pi/180)
        regionsPicker.transform = CGAffineTransform(rotationAngle: rotationAngle)
}

如上所示,我正在尝试将标签底部与选取器视图的顶部对齐。但由于我正在旋转我的视图,使高度等于 superview,它会创建这个巨大的空间。

我看到this answer 建议在这种特定情况下使用自动布局,或者,我也可以使用集合视图,但我很想知道是否有 SnapKit 解决方案可以解决这个问题

感谢您的帮助。

【问题讨论】:

    标签: ios autolayout snapkit


    【解决方案1】:

    问题在于苹果文档中transform的这部分描述:https://developer.apple.com/documentation/uikit/uiview/1622459-transform

    在 iOS 8.0 及更高版本中,transform 属性不会影响自动布局。自动布局根据其未转换的框架计算视图的对齐矩形。 因此,当您更改标签的文本时,您的约束与未转换的框架相关。

    因此,您将 pickerView 的 height 设置为视图的 height。然后你旋转它,它出现 来看看你想要的样子。

    不过,如果您使用Debug View Hierarchy,您会看到pickerView 现在远远超出了其superView 的前缘和后缘。

    您还会看到 pickerView 的 bounds 的宽度和高度 - 100 x 667(在 iPhone 8 上) - 这与您的预期不同。

    当视图大小发生变化时(例如设备旋转),这也会出现问题。

    这是一个示例方法:

    import UIKit
    
    class ViewController: UIViewController {
    
        let regionsLabel: UILabel = {
            let v = UILabel()
            v.backgroundColor = .red
            v.text = "Testing"
            return v
        }()
    
        let regionsPicker: UIPickerView = {
            let v = UIPickerView()
            v.backgroundColor = .green
            return v
        }()
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            view.backgroundColor = .cyan
    
            // add the label
            view.addSubview(regionsLabel)
    
            // center label horizontally, 10-pts from view top (safe area)
            regionsLabel.snp.makeConstraints { (make) in
                make.centerX.equalToSuperview()
                make.top.equalTo(self.view.safeAreaLayoutGuide.snp.top).offset(10)
            }
    
            // add the picker view
            view.addSubview(regionsPicker)
    
            // rotate the picker view
            let rotationAngle: CGFloat = -90 * (.pi/180)
            regionsPicker.transform = CGAffineTransform(rotationAngle: rotationAngle)
    
        }
    
        override func viewDidLayoutSubviews() {
            super.viewDidLayoutSubviews()
    
            regionsPicker.snp.remakeConstraints { (make) in
    
                // constrain picker view center horizontally
                make.centerX.equalToSuperview()
    
                // constant of 100 - because it's rotated, set the width
                make.width.equalTo(100)
    
                // constrain the height to a constant equal to the view width
                make.height.equalTo(view.bounds.width)
    
                // constrain the centerY to the centerY of the label,
                // plus one-half the label's frame height / 2
                // plus a constant of 65 (half the "height" of the picker view + 15-pts spacing)
                make.centerY.equalTo(regionsLabel.snp.centerY).offset(regionsLabel.frame.height / 2.0 + 65.0)
    
            }
    
        }
    
    }
    

    结果:

    【讨论】:

    • 感谢您的详细解答!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-01
    • 2014-06-12
    • 2018-05-06
    相关资源
    最近更新 更多