Xcode 8 - 移除了部分按钮的边框

8

我刚刚将我的Xcode版本从7.3升级到8.0,但是一些按钮的边框消失了。

代码看起来没问题,所以我真的不知道图层发生了什么事情。 顺便说一下,在其他一些控制器中,我可以看到图层的边框。

self.button.layer.borderColor = borderColor.CGColor;
self.button.layer.borderWidth = 2;
self.button.layer.cornerRadius = CGRectGetHeight(self.button.frame) / 2;

之前: (以下图片仅为示例-实时边框较为不同)

之前:

现在:

现在:


1
尝试在最后加上这一行代码: self.button.clipsToBounds = YES - Bhadresh Kathiriya
令人惊讶的是,即使您之前的按钮圆角半径似乎不到按钮高度的一半。 - ajay_nasa
图片仅为示例... - Asi Givati
1
@Asi Givati 请检查我的答案并回复。 - KSR
好的,我会尽快检查,谢谢。 - Asi Givati
我检查了一下,问题与QuartzCore/QuartzCore.h无关,但是我还是给了你+1 ;) - Asi Givati
6个回答

16

原因是XCode 8引入了一种新的在Storyboard中缩放的方式。

XCode 8之前,在视图控制器的生命周期中,frames在viewDidLoad(或属性didSet)中是不可知的。你必须等到viewDidLayoutSubviews(当自动布局完成应用约束以确定主视图中每个子视图的框架时)才能确定它们。 但bounds在此之前是可以访问的:它们只是设置为Storyboard中IBOutlet的大小。

在XCode 8中,情况有所不同:由于其新的缩放系统,甚至在ViewDidLayoutSubviews之前,bounds也不正确(它们可能存在,但具有像1000 x 1000这样的虚拟值)。

总之:

  • 只要使用固定值,就可以在viewDidLoad或IBOutlet didSet中使用cornerRadius。
  • 如果需要基于bounds定义您的cornerRadius,则在viewDidLayoutSubviews中进行,或使用NSLayoutConstraint(其值是从Autolayout固定且已知的)。
  • 如果需要在子类中的视图(如UITableViewCell或UICollectionViewCell)中使用cornerRadius,则可以在layoutSubviews中使用(但是此时需要给定一个固定值或NSLayoutConstraint常量给cornerRadius),或者在awakeFromNib中使用(在这种情况下,在执行任何frame或bounds相关操作之前,只需添加self.layoutIfNeeded,以强制单元格重新计算其子视图的框架即可)。

1000 x 1000 - 这正是我看到的虚拟框架导致问题的原因。现在,在您出色的回答之后,我将更好地知道如何处理它下一次 :) - Asi Givati
1
真让人沮丧,浪费了这么多时间来调试!谢谢分享。 - Crashalot
在Storyboard中加载自定义视图时,与viewDidLayoutSubviews函数相似的功能是什么?awakeFromNibinit?(coder aDecoder: NSCoder)在Xcode 8中也显示虚拟的1000x1000帧大小,尽管在Xcode 7中可以正常工作。 - Crashalot
“LayoutSubviews” 函数出现在自定义视图中,位于视图控制器的 “ViewWillLayoutSubviews” 和 “ViewDidLayoutSubviews” 之间。 - Frederic Adda
@Crashalot,你解决了这个问题吗?我也遇到了同样的问题。你是怎么解决的? - toxicsun

4
我认为问题出在IT技术方面:
CGRectGetHeight(self.button.frame) / 2;

当您设置角落时,我认为高度按钮没有值或值太大,边框将不会显示。您可以尝试更改为

self.button.layer.cornerRadius = 15;

如果出现问题,我认为你可以检查你的逻辑,并在高度按钮获得正确值时设置它。

但在昨天和Xcode 7一起工作时它还是能用的 :) - Asi Givati
我明白了。但是现在你正在使用Xcode8和iOS 10,所以有些东西发生了变化。 - vien vu
所以这就是问题所在。在 Xcode 7 中,CGRectGetHeight(self.button.frame)/2 工作得非常好,但现在由于某种原因我不得不为这个按钮添加高度约束并将其分成两部分才能获得正确的圆角高度。 - Asi Givati
@AsiGivati 嗯,我也遇到了同样的问题,在 Xcode 8 中无法使用帧值,但在 Xcode 7 中可以。哎呀! - Crashalot
@Crashalot - 这很容易解决 - 只需将您的代码从“viewDidLoad”移动到“viewDidLayoutSubviews”即可。 - Asi Givati

2

试一下并检查:

#import <QuartzCore/QuartzCore.h>

self.button.layer.borderColor = [UIColor whiteColor].CGColor;
self.button.layer.borderWidth = 2;
self.button.layer.cornerRadius = 5; // Change this value on your requirement
self.button.clipsToBounds = YES;

0

使用 dispatch_after

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.8 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.button.layer.borderColor = borderColor.CGColor;
self.button.layer.borderWidth = 2;
self.button.layer.cornerRadius = CGRectGetHeight(self.button.frame) / 2;    });

0

为了强制计算视图框架,您可以尝试使用layoutIfNeeded。例如,在UITableViewCell中的标签:

override func awakeFromNib() {
    super.awakeFromNib()
    self.layoutIfNeeded()
    self.qualityIndexLabel.makeRound()
}

-1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接