以编程方式添加的视图与界面构建器视图的宽度不一致

时间:2016-02-12 00:35:44

标签: ios iphone uiview uikit

我遇到了一些关于UIView s的意外(至少对我来说)大小的难题。

考虑这个UIViewController课程。 interfaceBuilderViewStoryboard文件中声明,并限制占据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创建的视图。

enter image description here

使用以编程方式创建的视图。

enter image description here

如您所见,以编程方式创建的视图可实现所需的结果。毫无疑问,因为打印的尺寸与superview(375)相同。

因此,我的问题只是为什么会发生这种情况?此外,我如何使用界面构建器中声明的视图,并以编程方式向其添加其他视图,其中包含我期望的尺寸和位置?

1 个答案:

答案 0 :(得分:2)

一些想法:

  1. 此代码正在访问frame中的viewDidLoad值,但此时frame值尚不可靠。该观点尚未确定。如果您要使用自定义frame值,请在viewDidAppearviewDidLayoutSubviews中执行此操作。

  2. 如今,我们通常不再使用frame值。相反,我们定义约束来以编程方式定义布局。与自定义frame值不同,您可以在viewDidLoad中添加子视图时定义约束。

  3. 您拥有场景的主要viewMyCustomView,然后另一个UIView为红色。这让我感到不必要的困惑。

  4. 我建议你只需在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,而是使用约束。