在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中设置的固定宽度/高度不应该被更改)。现在是这个代码还是有不同的地方? (附测试代码的截图)
答案 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方法。