xcode 自动布局和阴影
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14528497/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Autolayout and shadow
提问by Kamil
I've got a problem with adding shadow to my UIView which is created in iOS 6 application with Autolayout.
我在向我的 UIView 添加阴影时遇到了问题,这是在 iOS 6 应用程序中使用 Autolayout 创建的。
Let's assume I have a method that adds a shadow on the bottom of UIView (this is actually a Category of UIView, so it's reusable):
假设我有一个在 UIView 底部添加阴影的方法(这实际上是 UIView 的一个类别,所以它是可重用的):
- (void) addShadowOnBottom {
self.layer.shadowOffset = CGSizeMake(0, 2);
self.layer.shadowOpacity = 0.7;
self.layer.shadowColor = [[UIColor blackColor] CGColor];
self.layer.shadowPath = [UIBezierPath bezierPathWithRect:self.bounds].CGPath;
}
When I call this method in viewDidLoad
of some UIViewController, shadow is not added, probably due to all constraints, that have to be calculated.
当我在viewDidLoad
某些 UIViewController 中调用此方法时,未添加阴影,可能是由于必须计算的所有约束。
When I call this method in viewWillAppear
the same situation.
当我在viewWillAppear
同样的情况下调用这个方法时。
When I call this method in viewDidAppear
it works, but when new view shows up there is a short moment when there is no shadow and it appears after a while.
当我在viewDidAppear
其中调用此方法时,它可以工作,但是当新视图出现时,有一小段时间没有阴影,一段时间后出现。
If I resign from setting the shadowPath and remove line self.layer.shadowPath
everything works, but view transitions are not smooth.
如果我退出设置 shadowPath 并删除行,self.layer.shadowPath
一切正常,但视图转换不平滑。
So my question is what is the right way to add a shadow to view in iOS 6 with Autolayout turned on ?
所以我的问题是在启用自动布局的 iOS 6 中添加阴影的正确方法是什么?
回答by Yannick
Another thing you can add to the layer when working with AutoLayout and you need a shadow on a UIView
where the frame is not yet known is this :
使用 AutoLayout 时可以添加到图层的另一件事是UIView
在框架未知的地方需要阴影:
self.layer.rasterizationScale = [[UIScreen mainScreen] scale]; // to define retina or not
self.layer.shouldRasterize = YES;
Then remove the shadowPath property because the auto layout constraints are not yet processed, so it's irrelevant. Also at the time of execution you will not know the bounds or the frame of the view.
然后去掉shadowPath属性,因为自动布局约束还没有处理,所以无关紧要。同样在执行时,您将不知道视图的边界或框架。
This improves performance a lot!
这大大提高了性能!
回答by mattv123
Having the exact same issue...
有完全相同的问题...
Although I am unable to get the CALayer shadow on a view to animate nicely, at least the shadow does re-align properly after animation.
虽然我无法在视图上获得 CALayer 阴影以很好地动画,但至少在动画后阴影确实重新对齐。
My solution (which works fine in my application) is the set the shadowOpacity to 0, then reset it to the desired value AFTER the animation has completed. From a user's perspective, you cannot even tell the shadow is gone because the animations are typically too fast to perceive the difference.
我的解决方案(在我的应用程序中运行良好)是将 shadowOpacity 设置为 0,然后在动画完成后将其重置为所需的值。从用户的角度来看,您甚至无法判断阴影消失了,因为动画通常太快而无法感知差异。
Here is an example of some code in my application, in which I am changing the constant value of a constraint, which is 'trailing edge to superview' NSLayoutContraint:
这是我的应用程序中一些代码的示例,其中我正在更改约束的常量值,即“超视图的后沿”NSLayoutContraint:
- (void) expandRightEdge
{
[self.mainNavRightEdge setConstant:newEdgeConstant];
[self updateCenterContainerShadow];
[UIView animateWithDuration:ANIMATION_DURATION delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
[[NSNotificationCenter defaultCenter] postNotificationName:@"PanelLayoutChanged" object:nil];
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
nil;
}];
}
- (void) updateCenterContainerShadow
{
self.centerContainer.layer.masksToBounds = NO;
self.centerContainer.layer.shadowOpacity = 0.8f;
self.centerContainer.layer.shadowRadius = 5.0f;
self.centerContainer.layer.shadowOffset = CGSizeMake(0, 0);
self.centerContainer.layer.shadowColor = [UIColor blackColor].CGColor;
CGPathRef shadowPath = [UIBezierPath bezierPathWithRect:self.centerContainer.layer.bounds].CGPath;
[self.centerContainer.layer setShadowPath:shadowPath];
// Schedule a time to fade the shadow back in until we can figure out the CALayer + Auto-Layout issue
[self performSelector:@selector(fadeInShadow) withObject:nil afterDelay:ANIMATION_DURATION+.05];
}
- (void) fadeInShadow
{
[self.centerContainer.layer setShadowOpacity:0.8f];
}
Two things:
两件事情:
- I could have put the fadeInShadow in the completion block, but due to the way some of my other code is factored, this works better for me.
- I realize I am not performing a fade in with "fadeInShadow", but given how quickly it renderes after the completion of the animation, I found it is not necessary.
- 我本可以将fadeInShadow 放在完成块中,但是由于我的其他一些代码的分解方式,这对我来说效果更好。
- 我意识到我没有使用“fadeInShadow”执行淡入,但考虑到它在动画完成后渲染的速度,我发现它没有必要。
Hope that helps!
希望有帮助!
回答by Vaibhav Saran
i removed self.layer.shadowPath = [UIBezierPath bezierPathWithRect:self.bounds].CGPath;
from your code and it is working for me in viewDidLoad
, please confirm.
我self.layer.shadowPath = [UIBezierPath bezierPathWithRect:self.bounds].CGPath;
从你的代码中删除了它,它对我有用viewDidLoad
,请确认。
Increasing shdowOffset
will make you see the shadow more clear.
增加shdowOffset
会使您看到阴影更清晰。