【问题标题】:Why is my UIView not rotating about the z-axis?为什么我的 UIView 不绕 z 轴旋转?
【发布时间】:2023-02-23 02:48:50
【问题描述】:

我试图让我的 UIView 在 Swift 中绕 z 轴旋转。但由于某种原因,旋转轴并不像预期的那样:

    rotatedView.layer.anchorPoint = CGPoint(x: 0.5, y: 0.5)
    rotatedView.contentMode = .scaleToFill
    rotatedView.layer.transform = CATransform3DMakeRotation(rotatedObjectWrapper.object.rotation, 0, 0, 1)

如何让 UIView 绕 z 轴旋转?谢谢。

更新: 我调查后发现,当我使用 Stepper 元素控制旋转时,旋转是围绕 z 轴进行的。对于上下文,委托函数 delegate?.didRotateObject 更新 rotatedObjectWrapper.object.rotation 值。

滑块:

@IBAction func didChangeRotation(_ sender: UISlider) {
    delegate?.didRotateObject(to: Double(angleSlider.value))
}

步进器(更新 0.1 弧度):

 @IBAction func didChangeStepper(_ sender: Any) {
    delegate?.didRotateObject(to: Double(stepper.value))
}

我尝试使用一些动画来改变旋转值,它有点绕 z 轴旋转,同时仍然有奇怪的旋转行为:

    UIView.animate(withDuration: 0.5, animations: {
      rotatedView.layer.transform = CATransform3DMakeRotation(rotatedObjectWrapper.object.rotation, 0, 0, 1)
    })

结果:

更新 2: 我正在尝试这个:

        testView = CustomObjectView(image: UIImage(named: "black"))    
        guard let testView = testView else { return }
        testView.frame = CGRect(x: rotatedObject.position.x, y: rotatedObject.position.y, width: rotatedObject.width, height: rotatedObject.height)
        testView.layer.transform = CATransform3DMakeRotation(rotatedObjectWrapper.object.rotation, 0, 0, 1)
        rotatedView.layer.transform = CATransform3DMakeRotation(rotatedObjectWrapper.object.rotation, 0, 0, 1)
        print(testView.layer.frame)
        print(rotatedView.layer.frame)
        rotatedView.layer.frame = testView.layer.frame
        print(rotatedView.layer.frame)
        print(")))))))")

testView 仍在正确旋转,而 rotatedView 仍在奇怪地旋转。两者之间的唯一区别是 rotatedView 是从这样的字典中获得的:

guard let rotatedView = objectsToViews[rotatedObjectWrapper] else { return }

我正在尝试一种骇人听闻的方式将 rotatedView.layer.frame 设置为等于 testView.layer.frame 但它不起作用。

【问题讨论】:

  • 如果关闭秤以填充会怎样?
  • 它没有做任何不同的事情。
  • 更新:似乎这种行为是由 UISlider 引起的。上面的旋转是使用 UISlider 改变对象的旋转引起的。当我尝试使用其他 UI 控件/动画旋转它时,旋转似乎工作正常。

标签: ios swift uikit storyboard


【解决方案1】:

此代码根据滑块的值围绕 z 轴旋转视图,您可以在操场上运行它:

import UIKit
import PlaygroundSupport

class MyViewController : UIViewController {
    
    var viewToRotate: UIView!
    override func loadView() {
        let view = UIView()
        view.backgroundColor = .white

        let label = UILabel()
        label.frame = CGRect(x: 150, y: 200, width: 200, height: 20)
        label.text = "Hello World!"
        label.sizeToFit()
        label.textColor = .black
        viewToRotate = label
        
        let slider = UISlider(frame: CGRect(x: 50, y: 300, width: 300, height: 40))
        slider.minimumValue = 0
        slider.maximumValue = .pi * 2
        slider.addTarget(self, action: #selector(updateRotation(_:)), for: .valueChanged)
        
        view.addSubview(label)
        view.addSubview(slider)
        self.view = view
    }
    
    @objc private func updateRotation(_ sender: UISlider) {
        viewToRotate?.layer.transform = CATransform3DMakeRotation(CGFloat(sender.value), 0, 0, 1)
    }
    
    
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()

目前尚不清楚为什么您的代码无法正常工作,因为转换的设置方式相同,但它必须位于您问题中不存在的某些代码中。您为旋转传递的值是什么?是否有任何子层转换?

【讨论】:

  • 我认为这与我将视图存储在字典中有关。我有一些类型为 [Object: CustomView] 的辅助结构。我通过这个字典获取视图,并正在修改它(因为它是一个类对象,它应该反映超级视图的变化)。
【解决方案2】:
import UIKit

class ViewController: UIViewController {
    let rotatedView = UIView(frame: CGRect(x: 50, y: 50, width: 50, height: 50))
    
    var angle = 0.0
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        rotatedView.backgroundColor = .red
        view.addSubview(rotatedView)
        rotatedView.layer.anchorPoint = CGPoint(x: 0.5, y: 0.5)
           rotatedView.contentMode = .scaleToFill

        _ = Timer.scheduledTimer(timeInterval: 1/60, target: self, selector: #selector(updateFrame), userInfo: nil, repeats: true)
        
       
    }


    @objc func updateFrame(_ timer: Timer)
    {
        angle += 0.1
           rotatedView.layer.transform = CATransform3DMakeRotation(angle, 1, 0, 0)
    }
}

【讨论】:

  • 如果我想为旋转设置动画,这会起作用。抱歉缺乏上下文,正如我在上面的评论中提到的,我需要使用 UISlider 来控制旋转。
  • 您唯一需要做的就是发送 UISlider 的值而不是 angle += 0.1 。如果您做不到,请告诉我为您编写代码,因为我看到有人已经在下面为您实现了代码。在那种情况下,您不需要计时器。我刚刚在计时器中编写了代码,因此您可以看到它的运行情况,否则解决方案就是这样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-12
  • 1970-01-01
  • 2011-08-22
  • 1970-01-01
  • 2011-10-30
  • 2019-05-17
相关资源
最近更新 更多