我的目标是在纵向或横向模式下手动控制自定义视图布局。在启动时,View通常可以通过纵向或横向模式显示子视图1和视图2,这意味着我的约束设置应该没问题。但是在旋转之后,视图将显示为空,而不是我期望的view1和view2布局。我无法理解如何强制UI刷新以显示我的新布局。
以下是我的代码段和测试结果。
class ConstraintViewController: UIViewController
{
let metrics = ["topMargin":64,"leftMargin":10,"rightMargin":10,"bottomMargin":10,"interSpace":20]
var viewsDictionary: Dictionary<String,UIView!>?
var view1: UIView?
var view2: UIView?
let button1 = UIButton.buttonWithType(UIButtonType.System) as UIButton
let label1 = UILabel() as UILabel
let atRest = "Doesn't do much"
let atWork = "Secret Agent"
override func viewDidLoad() {
super.viewDidLoad()
// Remove conflicting NSIBPrototypingLayoutConstraints.
NSLayoutConstraint.deactivateConstraints(self.view.constraints())
setupElements()
println("In viewDidLoad")
if(UIDeviceOrientationIsLandscape(UIDevice.currentDevice().orientation)) {
//Landscape code
isPortrait = false
landscapeConstraint()
} else {
//Portrait code
isPortrait = true
portraitConstraint()
}
}
override func shouldAutorotate() -> Bool {
return true
}
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
if(UIDeviceOrientationIsLandscape(UIDevice.currentDevice().orientation)) {
//Landscape code
println("Detect landscape mode")
NSLayoutConstraint.deactivateConstraints(self.view.constraints())
self.view1!.removeConstraints(self.view1!.constraints())
self.view2!.removeConstraints(self.view2!.constraints())
self.view!.removeConstraints(self.view!.constraints())
//self.view.removeConstraints(<#constraints: [AnyObject]#>)
landscapeConstraint()
self.view1?.layoutIfNeeded()
self.view2?.layoutIfNeeded()
self.view.layoutIfNeeded()
} else {
//Portrait code
println("Detect portrait mode")
NSLayoutConstraint.deactivateConstraints(self.view.constraints())
self.view1!.removeConstraints(self.view1!.constraints())
self.view2!.removeConstraints(self.view2!.constraints())
self.view!.removeConstraints(self.view!.constraints())
portraitConstraint()
self.view1?.layoutIfNeeded()
self.view2?.layoutIfNeeded()
self.view.layoutIfNeeded()
}
}
func setupElements() {
//Make a view
view1 = UIView()
view1!.setTranslatesAutoresizingMaskIntoConstraints(false)
view1!.backgroundColor = UIColor.redColor()
//Make a second view
view2 = UIView()
view2!.setTranslatesAutoresizingMaskIntoConstraints(false)
view2!.backgroundColor = UIColor(red: 0.75, green: 0.75, blue: 0.1, alpha: 1.0)
//Make a label
label1.text = atRest
label1.setTranslatesAutoresizingMaskIntoConstraints(false)
//Make a button
button1.setTranslatesAutoresizingMaskIntoConstraints(false)
button1.setTitle("Platypus", forState: UIControlState.Normal)
button1.addTarget(self, action: "buttonPressed", forControlEvents: UIControlEvents.TouchUpInside)
button1.backgroundColor = UIColor.blueColor()
button1.setTitleColor(UIColor.whiteColor(), forState: UIControlState.Normal)
//Add the views
view.addSubview(view1!)
view.addSubview(view2!)
view2!.addSubview(button1)
view2!.addSubview(label1)
viewsDictionary = ["view":self.view,"view1":view1,"view2":view2,"button1":button1,"label1":label1]
}
func landscapeConstraint() {
//--------------- landscape constraints
println("In landscapeConstraint")
//make dictionary for views
//views
let view1_constraint_V:NSArray = NSLayoutConstraint.constraintsWithVisualFormat("V:|-topMargin-[view1]-bottomMargin-|", options: NSLayoutFormatOptions(0), metrics: metrics, views: viewsDictionary!)
let view2_constraint_V:NSArray = NSLayoutConstraint.constraintsWithVisualFormat("V:|-topMargin-[view2]-bottomMargin-|", options: NSLayoutFormatOptions(0), metrics: metrics, views: viewsDictionary!)
let view_constraint_H:NSArray = NSLayoutConstraint.constraintsWithVisualFormat("H:|-10-[view1]-20-[view2]-10-|", options: NSLayoutFormatOptions.AlignAllTop, metrics: nil, views: viewsDictionary!)
let view1_width_constraint = NSLayoutConstraint(item: view1!, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: view2!, attribute: NSLayoutAttribute.Width, multiplier: 1.0, constant: 0)
self.view.addConstraints(view1_constraint_V)
self.view.addConstraints(view2_constraint_V)
self.view.addConstraints(view_constraint_H)
self.view.addConstraint(view1_width_constraint)
//controls
let control_constraint_H:NSArray = NSLayoutConstraint.constraintsWithVisualFormat("H:|-[button1(>=20)]-interSpace-[label1(>=30)]", options: NSLayoutFormatOptions.AlignAllCenterY, metrics: metrics, views: viewsDictionary!)
let control_constraint_V:NSArray = NSLayoutConstraint.constraintsWithVisualFormat("V:[button1(20)]-10-|", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDictionary!)
view2!.addConstraints(control_constraint_H)
view2!.addConstraints(control_constraint_V)
}
func portraitConstraint() {
//--------------- portrait constraints
println("In portraitConstraint")
//make dictionary for views
//views
let view1_constraint_H:NSArray = NSLayoutConstraint.constraintsWithVisualFormat("H:|-leftMargin-[view1]-rightMargin-|", options: NSLayoutFormatOptions(0), metrics: metrics, views: viewsDictionary!)
let view2_constraint_H:NSArray = NSLayoutConstraint.constraintsWithVisualFormat("H:|-leftMargin-[view2]-rightMargin-|", options: NSLayoutFormatOptions(0), metrics: metrics, views: viewsDictionary!)
let view_constraint_V:NSArray = NSLayoutConstraint.constraintsWithVisualFormat("V:|-topMargin-[view1]-interSpace-[view2]-bottomMargin-|", options: NSLayoutFormatOptions.AlignAllLeading, metrics: metrics, views: viewsDictionary!)
let view1_height_constraint = NSLayoutConstraint(item: view1!, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: view2!, attribute: NSLayoutAttribute.Height, multiplier: 1.0, constant: 0)
self.view.addConstraints(view1_constraint_H)
self.view.addConstraints(view2_constraint_H)
self.view.addConstraints(view_constraint_V)
self.view.addConstraint(view1_height_constraint)
//controls
let control_constraint_H:NSArray = NSLayoutConstraint.constraintsWithVisualFormat("H:|-[button1(>=80)]-interSpace-[label1(>=100)]", options: NSLayoutFormatOptions.AlignAllCenterY, metrics: metrics, views: viewsDictionary!)
let control_constraint_V:NSArray = NSLayoutConstraint.constraintsWithVisualFormat("V:[button1(40)]-40-|", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDictionary!)
view2!.addConstraints(control_constraint_H)
view2!.addConstraints(control_constraint_V)
}
}
测试结果:
init布局视图显示正确。
旋转后,视图显示为空,未更新为预期的布局。
答案 0 :(得分:0)
你写viewWillTransitionToSize
的地方
self.view!.removeConstraints(self.view!.constraints())
这将删除您添加的新约束,还创建视图时创建的初始默认约束。如果没有这些默认约束,视图的大小将缩小为零,并且子视图的大小会缩小以匹配。
您可以创建新的实例变量
var viewInitialConstraints: [AnyObject]?
然后在viewDidAppear
中(它在viewDidLoad
或viewWillAppear
中不起作用)
viewInitialConstraints = view.constraints()
(将最初添加的额外约束移至ViewDidAppear
),然后您可以写入viewWillTransitionToSize
view.removeConstraints(view.constraints())
view.addConstraints(viewInitialConstraints)
或者,您可以尝试跟踪您添加的约束:
view.removeConstraints(viewExtraConstraints)