我正在使用这段代码来修整我的 UIView
的一个角:
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:
self.view.bounds byRoundingCorners:(UIRectCornerTopLeft) cornerRadii:
CGSizeMake(10.0, 10.0)];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
maskLayer.frame = self.view.bounds;
maskLayer.path = maskPath.CGPath;
self.view.layer.mask = maskLayer;
self.view.layer.masksToBounds = NO;
只要我不调整 View 大小,这段代码就可以工作。如果我放大 View ,则不会出现新区域,因为它位于 mask 层的边界之外(此 mask 层不会随 View 自动调整自身大小)。我可以把面具做得尽可能大,但它可能在 iPad 上是全屏的,所以我担心这么大的面具的性能(我会有不止一个这样的面具)界面)。此外,超大尺寸的 mask 不适用于我需要将右上角(单独)四舍五入的情况。
有没有更简单、更容易的方法来实现这一点?
更新:这是我要实现的目标:http://i.imgur.com/W2AfRBd.png (我想要的圆角在这里用绿色圈起来了)。
我已经实现了这个的工作版本,使用 UINavigationController
的子类并重写 viewDidLayoutSubviews
,如下所示:
- (void)viewDidLayoutSubviews {
CGRect rect = self.view.bounds;
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:rect
byRoundingCorners:UIRectCornerTopLeft cornerRadii:CGSizeMake(8.0, 8.0)];
self.maskLayer = [CAShapeLayer layer];
self.maskLayer.frame = rect;
self.maskLayer.path = maskPath.CGPath;
self.view.layer.mask = self.maskLayer;
}
然后我用我的 View Controller 实例化我的 UINavigationController
子类,然后我将导航 Controller View 的框架偏移 20 像素 (y) 以显示状态栏并留下 44 像素高的导航栏,如图所示。
该代码可以正常工作,只是它根本不能很好地处理旋转。当应用程序旋转时,viewDidLayoutSubviews
在旋转之前 被调用,我的代码创建一个适合 View 的 mask 在旋转之后;这对旋转产生了不希望的 block 效应,在旋转过程中,本应隐藏的位会暴露出来。此外,虽然应用的旋转在没有此 mask 的情况下非常平滑,但在创建 mask 后旋转变得明显不稳定和缓慢。
iPad 应用程序 Evomail 也有这样的圆角,他们的应用程序也有同样的问题。
最佳答案
问题是,CoreAnimation 属性不会在 UIKit 动画 block 中进行动画处理。您需要创建一个单独的动画,它与 UIKit 动画具有相同的曲线和持续时间。
我在 viewDidLoad
中创建了 mask 层。当 View 即将布局时,我只修改了 mask 层的path
属性。
您不知道布局回调方法中的旋转持续时间,但您在旋转之前(以及触发布局之前)知道它,因此您可以将其保留在那里。
下面的代码运行良好。
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
//Keep duration for next layout.
_duration = duration;
}
-(void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
UIBezierPath* maskPath = [UIBezierPath bezierPathWithRoundedRect:self.view.bounds byRoundingCorners:UIRectCornerTopLeft cornerRadii:CGSizeMake(10, 10)];
CABasicAnimation* animation;
if(_duration > 0)
{
animation = [CABasicAnimation animationWithKeyPath:@"path"];
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[animation setDuration:_duration];
//Set old value
[animation setFromValue:(id)((CAShapeLayer*)self.view.layer.mask).path];
//Set new value
[animation setToValue:(id)maskPath.CGPath];
}
((CAShapeLayer*)self.view.layer.mask).path = maskPath.CGPath;
if(_duration > 0)
{
[self.view.layer.mask addAnimation:animation forKey:@"path"];
}
//Zero duration for next layout.
_duration = 0;
}
关于ios - 如何在 IOS 中修整可调整大小的 UIView 的一个角?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21298335/