在视图变换(旋转)和调整大小(到边界)后保持自动布局
Keeping autolayout after view transform(rotation) and resize(to bounds)
我在视图的一个角上有一个带有圆形子视图的视图。
我通过自动布局定义了圆圈的位置。
我需要旋转和调整基础视图的大小。
问题是如果我旋转然后调整视图大小,圆的位置将不会在我期望的位置。
在这种情况下如何保持布局?
没有调整大小或旋转。
旋转和调整大小后
import UIKit
class ExampleController: UIViewController {
// UI Appearance
private let buttonWidth: CGFloat = 40
private var themeColor: UIColor = UIColor.magentaColor()
// Resizing and rotating view
let myView: UIView = {
let v = UIView()
v.layer.borderWidth = 1
v.layer.borderColor = UIColor.magentaColor().CGColor
v.frame = CGRectMake(100, 150, 150, 225)
return v
}()
lazy var cornerButton: UIView = {
let b = UIView()
b.layer.cornerRadius = self.buttonWidth / 2
b.layer.borderWidth = 1
b.layer.borderColor = self.themeColor.CGColor
return b
}()
// Control
@IBOutlet weak var angleSlider: UISlider!
@IBOutlet weak var widthSlider: UISlider!
override func viewDidLoad() {
super.viewDidLoad()
setupSubviews()
}
func setupSubviews() {
view.addSubview(myView)
view.addSubview(angleSlider)
// Angle Slider
angleSlider.minimumValue = 0
angleSlider.maximumValue = 360
angleSlider.value = 0
// Width Slider
widthSlider.maximumValue = Float(view!.frame.width)
widthSlider.value = Float(myView.frame.width)
// Corner Button
myView.addSubview( cornerButton )
myView.addConstraintsWithFormat("H:[v0(\(buttonWidth))]", views: cornerButton) // Use extension to set width or height
myView.addConstraintsWithFormat("V:[v0(\(buttonWidth))]", views: cornerButton) // Use extension to set width or height
myView.addConstraint(NSLayoutConstraint(item: cornerButton, attribute: .CenterX, relatedBy: .Equal, toItem: myView, attribute: .Right, multiplier: 1, constant: 0))
myView.addConstraint(NSLayoutConstraint(item: cornerButton, attribute: .CenterY, relatedBy: .Equal, toItem: myView, attribute: .Top, multiplier: 1, constant: 0))
}
// Rotation
@IBAction func angleSliderDidChange(slider: UISlider) {
print(slider.value)
setAngle(forMyView: slider.value )
}
func setAngle(forMyView angle: Float) {
let radian = angle.degreesToRadians
myView.transform = CGAffineTransformMakeRotation( radian )
}
// Resize
@IBAction func widthSlider(sender: UISlider) {
let newWidth: CGFloat = CGFloat(sender.value)
let newSize = CGSizeMake(newWidth, myView.aspectRatioKeptHeight(forWidth: newWidth))
myView.bounds.size = newSize
}
}
最简单的方法是使圆形成为您要应用变换的矩形的子视图,并确保矩形视图的 clipsToBounds
设置为 false。考虑到您提供的信息,圆圈也将应用变换,我不能 100% 确定这就是您想要的。如果您提供更多详细信息,我们可以优化答案。
另一种方法是将圆限制在矩形视图的顶部和尾部边缘,而不使其成为子视图。您必须再次确认给定的结果符合您的要求。
问题:无论您做什么,您都需要更改 func widthSlider(sender: UISlider)
方法,因为您不能以这种方式混合使用自动布局和框架。您在矩形上设置宽度约束和高度约束,然后调整约束的常量。这将要求您将默认尺寸存储在其他地方。
@IBAction func widthSlider(sender: UISlider) {
let newWidth = CGFloat(sender.value)
rectangleViewWidthConstraint.constant = newWidth
let newHeight = myView.aspectRatioKeptHeight(forWidth: newWidth)
rectangleViewHeightConstraint.constant = newHeigh
}
我自己解决了这个问题。
这很棘手但很简单。
我说过当角度为 0 时更改边界不会破坏布局。
这意味着我只需要在更改边界时将角度临时设置为 0。
完整的过程是...
- 存储当前角度
- 将视图的角度设置为 0
- 设置新界限
- 设置存储角度
我在视图的一个角上有一个带有圆形子视图的视图。 我通过自动布局定义了圆圈的位置。
我需要旋转和调整基础视图的大小。
问题是如果我旋转然后调整视图大小,圆的位置将不会在我期望的位置。
在这种情况下如何保持布局?
没有调整大小或旋转。
旋转和调整大小后
import UIKit
class ExampleController: UIViewController {
// UI Appearance
private let buttonWidth: CGFloat = 40
private var themeColor: UIColor = UIColor.magentaColor()
// Resizing and rotating view
let myView: UIView = {
let v = UIView()
v.layer.borderWidth = 1
v.layer.borderColor = UIColor.magentaColor().CGColor
v.frame = CGRectMake(100, 150, 150, 225)
return v
}()
lazy var cornerButton: UIView = {
let b = UIView()
b.layer.cornerRadius = self.buttonWidth / 2
b.layer.borderWidth = 1
b.layer.borderColor = self.themeColor.CGColor
return b
}()
// Control
@IBOutlet weak var angleSlider: UISlider!
@IBOutlet weak var widthSlider: UISlider!
override func viewDidLoad() {
super.viewDidLoad()
setupSubviews()
}
func setupSubviews() {
view.addSubview(myView)
view.addSubview(angleSlider)
// Angle Slider
angleSlider.minimumValue = 0
angleSlider.maximumValue = 360
angleSlider.value = 0
// Width Slider
widthSlider.maximumValue = Float(view!.frame.width)
widthSlider.value = Float(myView.frame.width)
// Corner Button
myView.addSubview( cornerButton )
myView.addConstraintsWithFormat("H:[v0(\(buttonWidth))]", views: cornerButton) // Use extension to set width or height
myView.addConstraintsWithFormat("V:[v0(\(buttonWidth))]", views: cornerButton) // Use extension to set width or height
myView.addConstraint(NSLayoutConstraint(item: cornerButton, attribute: .CenterX, relatedBy: .Equal, toItem: myView, attribute: .Right, multiplier: 1, constant: 0))
myView.addConstraint(NSLayoutConstraint(item: cornerButton, attribute: .CenterY, relatedBy: .Equal, toItem: myView, attribute: .Top, multiplier: 1, constant: 0))
}
// Rotation
@IBAction func angleSliderDidChange(slider: UISlider) {
print(slider.value)
setAngle(forMyView: slider.value )
}
func setAngle(forMyView angle: Float) {
let radian = angle.degreesToRadians
myView.transform = CGAffineTransformMakeRotation( radian )
}
// Resize
@IBAction func widthSlider(sender: UISlider) {
let newWidth: CGFloat = CGFloat(sender.value)
let newSize = CGSizeMake(newWidth, myView.aspectRatioKeptHeight(forWidth: newWidth))
myView.bounds.size = newSize
}
}
最简单的方法是使圆形成为您要应用变换的矩形的子视图,并确保矩形视图的 clipsToBounds
设置为 false。考虑到您提供的信息,圆圈也将应用变换,我不能 100% 确定这就是您想要的。如果您提供更多详细信息,我们可以优化答案。
另一种方法是将圆限制在矩形视图的顶部和尾部边缘,而不使其成为子视图。您必须再次确认给定的结果符合您的要求。
问题:无论您做什么,您都需要更改 func widthSlider(sender: UISlider)
方法,因为您不能以这种方式混合使用自动布局和框架。您在矩形上设置宽度约束和高度约束,然后调整约束的常量。这将要求您将默认尺寸存储在其他地方。
@IBAction func widthSlider(sender: UISlider) {
let newWidth = CGFloat(sender.value)
rectangleViewWidthConstraint.constant = newWidth
let newHeight = myView.aspectRatioKeptHeight(forWidth: newWidth)
rectangleViewHeightConstraint.constant = newHeigh
}
我自己解决了这个问题。
这很棘手但很简单。
我说过当角度为 0 时更改边界不会破坏布局。 这意味着我只需要在更改边界时将角度临时设置为 0。
完整的过程是...
- 存储当前角度
- 将视图的角度设置为 0
- 设置新界限
- 设置存储角度