我遇到了一些关于UIView
s的意外(至少对我来说)大小的难题。
考虑这个UIViewController
课程。 interfaceBuilderView
在Storyboard
文件中声明,并限制占据UIView
的整个区域。因此,在调用interfaceBuilderView
时,我希望programicallyCreatedView
与*.frame.width
的大小相同。但他们不是。
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var interfaceBuilderView: MyCustomView!
override func viewDidLoad() {
super.viewDidLoad()
let programmicallyCreatedView = MyCustomView(frame: self.view.frame)
//commented out this to get first picture
self.view.addSubview(programmicallyCreatedView)
self.interfaceBuilderView.setAppearance()
self.programmicallyCreatedView.setAppearance()
print(self.view.frame.width)//prints 375
print(self.interfaceBuilderView.frame.width)//prints 600
print(self.programmicallyCreatedView.frame.width)//prints 375
}
}
现在,考虑MyCustomView
类的这种实现。
import UIKit
class MyCustomView: UIView {
func setAppearance() {
let testViewWidth: CGFloat = 200.0
let centerXCoor = (self.frame.width - testViewWidth) / 2.0
let testView = UIView(frame: CGRectMake(centerXCoor, 0, testViewWidth, 100))
testView.backgroundColor = UIColor.redColor()
self.addSubview(testView)
}
}
正如你所看到的,我只是画一个宽度为200.0的红色直尺,它应该是居中的。结果如下。
使用Interface Builder创建的视图。
使用以编程方式创建的视图。
如您所见,以编程方式创建的视图可实现所需的结果。毫无疑问,因为打印的尺寸与superview(375)相同。
因此,我的问题只是为什么会发生这种情况?此外,我如何使用界面构建器中声明的视图,并以编程方式向其添加其他视图,其中包含我期望的尺寸和位置?
答案 0 :(得分:2)
一些想法:
此代码正在访问frame
中的viewDidLoad
值,但此时frame
值尚不可靠。该观点尚未确定。如果您要使用自定义frame
值,请在viewDidAppear
或viewDidLayoutSubviews
中执行此操作。
如今,我们通常不再使用frame
值。相反,我们定义约束来以编程方式定义布局。与自定义frame
值不同,您可以在viewDidLoad
中添加子视图时定义约束。
您拥有场景的主要view
,MyCustomView
,然后另一个UIView
为红色。这让我感到不必要的困惑。
我建议你只需在viewDidLoad
中添加以编程方式创建的子视图并指定其约束。使用新的iOS 9约束语法,您可以指定它应该居中,邻近view
的顶部,宽度的一半和高度的四分之一:
override func viewDidLoad() {
super.viewDidLoad()
let redView = UIView()
redView.backgroundColor = UIColor.redColor()
redView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(redView)
NSLayoutConstraint.activateConstraints([
redView.centerXAnchor.constraintEqualToAnchor(view.centerXAnchor),
redView.topAnchor.constraintEqualToAnchor(view.topAnchor),
redView.widthAnchor.constraintEqualToAnchor(view.widthAnchor, multiplier: 0.5),
redView.heightAnchor.constraintEqualToAnchor(view.heightAnchor, multiplier: 0.25)
])
}
显然,调整这些约束适合你,但希望这说明了这个想法。不再使用frame
,而是使用约束。