iOS10 SDK 什么时候设置视图框大小?

When is view frame size set in iOS10 SDK?

多年来,在 Swift 和 ObjC 中,我一直使用这种技术来制作圆形视图:

view.layer.cornerRadius = view.frame.size.width / 2
view.clipsToBounds = true

当 Storyboard 中的 UILayoutConstraints 固定宽度/高度时,将此代码放入 viewDidLoad 或 viewWillAppear 中没有问题。内置 iOS9.3SDK,在 iOS10 等

中运行良好

iOS10SDK 在 Storyboard 中显示的帧大小与固定大小完全不同,甚至在 viewWillAppear 和 viewDidLayoutSubviews 等中也是如此。我的选择是:

1) 在 vi​​ewDidAppear 中执行此操作(糟糕的解决方案) 2) 对 cornerRadius 进行硬编码(工作正常,但很糟糕)

这看起来像是一个错误(因为在 Storyboard 中设置的固定 width/height 不应在控制台中至少没有警告的情况下更改)。是吗,或者现在这段代码有不同的地方吗? (附测试代码截图)

今天这件事困扰了我一整天。我在几个方面遇到了同样的问题我需要正确的框架大小来绘制自定义 UI 元素,或将样式应用于视图,特别是更改角半径。我找到的解决方案是使用以下实现创建 UIViewController 的子类:

class BaseViewController: UIViewController {

    /** 
        This is a helper property and a helper method that will be called
        when the frame is calculated, but will prevent the formatting code
        being called more than once
    */
    private var didCalculateInitialFrame = false
    private func checkIfFrameWasCalculated() {
        if self.didCalculateInitialFrame == false {
            self.viewDidCalculateInitialFrame()
            self.didCalculateInitialFrame = true
        }
    }

    //-- This is where you will tie your helper method with the view lifecycle
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        self.checkIfFrameWasCalculated()
    }

    /** 
        This is an overridable function that you will implement 
        in your subclasses, in case you need to use this approach
        in multiple places of your app. 
    */
    func viewDidCalculateInitialFrame() {

    }
}

这解决了故事板的所有问题。我希望这是有帮助的。

在 iOS 10 中,我在 6 月份开始使用 Xcode 8 后就遇到了这个问题,当时它是测试版。需要此解决方案:

layoutIfNeeded() 放在图层修改之前:

self.view.layoutIfNeeded()

view.layer.cornerRadius = view.frame.size.width / 2
view.clipsToBounds = true

将圆角半径的代码放入 viewDidLayoutSubviews() 方法:

override func viewDidLayoutSubviews() {

    view.layer.cornerRadius = view.frame.size.width / 2
    view.clipsToBounds = true

}

这似乎是 ios10

中的问题

可以通过覆盖控制器方法viewDidLayoutSubviews()或者 在获取其尺寸之前,为视图调用方法 layoutIfNeeded() 可能需要哪个尺寸值。 Objective-C :[viewObject layoutIfNeeded] Swift: viewObject.layoutIfNeeded()

如果尺寸值仍然不正确,则对视图对象的父视图使用 layoutIfNeeded 方法。