何时在iOS10 SDK中设置了视图框架大小?

时间:2016-09-12 08:40:37

标签: autolayout ios10

在Swift和ObjC的几年里,我使用这种技术制作了一个圆形视图:

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

当故事板中的UILayoutConstraints是固定的宽度/高度时,将此代码放在viewDidLoad或viewWillAppear中是没有问题的。内置iOS9.3SDK,在iOS10等中运行良好。

iOS10SDK显示的框架大小与故事板中的固定大小完全不同,甚至高达viewWillAppear,以及viewDidLayoutSubviews等。我的选项是:

1)在viewDidAppear中执行此操作(糟糕的解决方案) 2)硬编码cornerRadius(工作正常,但可怕)

这看起来像一个错误(因为在控制台中至少没有警告,所以在Storyboard中设置的固定宽度/高度不应该被更改)。现在是这个代码还是有不同的地方? (附测试代码的截图)

enter image description here

3 个答案:

答案 0 :(得分:6)

在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

}

答案 1 :(得分:3)

今天整天困扰着我。我在几个点上遇到了同样的问题,我需要正确的帧大小来绘制自定义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() {

    }
}

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

答案 2 :(得分:0)

这似乎是ios10中的问题

可以通过覆盖控制器方法viewDidLayoutSubviews()或来解决 调用方法layoutIfNeeded()为视图获取其维度之前可能需要的维度值。 Objective-C:[viewObject layoutIfNeeded] Swift:viewObject.layoutIfNeeded()

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