我有一个自定义视图MyView
(红色),其中包含一个子视图MySubView
(蓝色)。我想围绕其中心旋转子视图。
我的问题是,当我使用autolayout设置MySubview
时,旋转正常:
但是当我设置子视图的框架(没有自动布局)时,旋转会扭曲视图:
在MySubview
类中,我公开了一个设置旋转的属性,如下所示
var rotateAngle: Int = 0 {
didSet {
let measurement = Measurement(value: Double(rotateAngle), unit: UnitAngle.degrees)
let radians = measurement.converted(to: UnitAngle.radians).value
layer.transform = CATransform3DMakeRotation(CGFloat(radians), 0.0, 0.0, 1.0)
}
}
在MyView
中,使用
subview.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
subview.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.5),
subview.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 0.5),
subview.centerXAnchor.constraint(equalTo: centerXAnchor),
subview.centerYAnchor.constraint(equalTo: centerYAnchor),
])
当我在不使用自动布局的情况下进行设置时,我只需设置子视图框
override func layoutSubviews() {
super.layoutSubviews()
subview.frame = CGRect(origin: CGPoint(x: frame.width / 4, y: frame.height / 4), size: CGSize(width: frame.width / 2, height: frame.height / 2))
}
我不想使用autolayout的原因是因为在真实的应用程序中,我经常刷新数百个视图,在没有自动布局的情况下表现更好。
以下是
的完整列表class RotateViewController: UIViewController {
@IBOutlet var myView: MyView!
@IBOutlet var slider: UISlider!
override func viewDidLoad() {
myView = MyView()
view.addSubview(myView)
myView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
myView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
myView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
myView.widthAnchor.constraint(equalToConstant: 60),
myView.heightAnchor.constraint(equalToConstant: 60)
])
}
@IBAction func sliderValueChanged() {
myView.subview.rotateAngle = Int(slider.value)
}
}
class MySubView: UIView {
var rotateAngle: Int = 0 {
didSet {
let measurement = Measurement(value: Double(rotateAngle), unit: UnitAngle.degrees)
let radians = measurement.converted(to: UnitAngle.radians).value
layer.transform = CATransform3DMakeRotation(CGFloat(radians), 0.0, 0.0, 1.0)
}
}
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .blue
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
backgroundColor = .blue;
}
}
class MyView: UIView {
let useAutoLayout = false
var subview = MySubView()
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(subview)
backgroundColor = .red
setupConsraints()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
addSubview(subview)
backgroundColor = .red
setupConsraints()
}
override func layoutSubviews() {
super.layoutSubviews()
if useAutoLayout {
return
}
subview.frame = CGRect(origin: CGPoint(x: frame.width / 4, y: frame.height / 4), size: CGSize(width: frame.width / 2, height: frame.height / 2))
}
private func setupConsraints() {
if !useAutoLayout {
return
}
subview.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
subview.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.5),
subview.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 0.5),
subview.centerXAnchor.constraint(equalTo: centerXAnchor),
subview.centerYAnchor.constraint(equalTo: centerYAnchor),
])
}
}
答案 0 :(得分:0)
这是因为重新运行了这个
override func layoutSubviews() {
super.layoutSubviews()
if(once)
{
subview.frame = CGRect(origin: CGPoint(x: frame.width / 4, y: frame.height / 4), size: CGSize(width: frame.width / 2, height: frame.height / 2))
print(subview.frame)
once = false
}
}
答案 1 :(得分:0)
阅读docs of UIView之后,我认为根本原因是在将transform
属性设置为其他标识后,框架变为无效:
如果transform属性不是identity变换,则此属性的值是未定义的,因此应该被忽略。
因此,我可以使用其边界来设置它,而不是使用旋转视图的frame
:
override func layoutSubviews() {
super.layoutSubviews()
subview.bounds.size = CGSize(width: frame.width / 2, height: frame.height / 2)
subview.center = CGPoint(x: frame.width / 2, y: frame.height / 2)
}
答案 2 :(得分:0)
问题在于您不断重置视图的帧,这会导致transform
失效。在MyView
更新setupConsraints()
即
private func setupConsraints() {
if !useAutoLayout {
subview.frame = CGRect(origin: CGPoint(x: frame.width / 4, y: frame.height / 4), size: CGSize(width: frame.width / 2, height: frame.height / 2))
return
}
subview.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
...
])
}
然后您可以完全删除layoutSubviews()
功能。