10

我在使用自动布局在 iOS 6 应用程序中创建的 UIView 中添加阴影时遇到问题。

假设我有一个在 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;
}

当我在某些 UIViewController 中调用此方法时viewDidLoad,未添加阴影,可能是由于必须计算的所有约束。

viewWillAppear当我在相同的情况下调用此方法时。

当我在其中调用此方法时,viewDidAppear它可以工作,但是当新视图出现时,有一小段时间没有阴影,它会在一段时间后出现。

如果我放弃设置 shadowPath 并删除行self.layer.shadowPath,一切正常,但视图转换不平滑。

所以我的问题是在 iOS 6 中添加阴影以查看 Autolayout 的正确方法是什么?

4

3 回答 3

15

使用 AutoLayout 时您可以添加到图层的另一件事是,您需要在UIView尚不知道框架的地方添加阴影:

self.layer.rasterizationScale = [[UIScreen mainScreen] scale]; // to define retina or not
self.layer.shouldRasterize = YES;

然后删除 shadowPath 属性,因为尚未处理自动布局约束,因此无关紧要。同样在执行时,您将不知道视图的边界或框架。

这大大提高了性能!

于 2013-08-23T11:45:47.877 回答
2

i removed self.layer.shadowPath = [UIBezierPath bezierPathWithRect:self.bounds].CGPath; from your code and it is working for me in viewDidLoad, please confirm.

Increasing shdowOffset will make you see the shadow more clear.

于 2013-03-20T09:48:58.130 回答
1

有完全相同的问题...

虽然我无法让视图上的 CALayer 阴影很好地制作动画,但至少阴影在动画后会正确重新对齐。

我的解决方案(在我的应用程序中运行良好)是将 shadowOpacity 设置为 0,然后在动画完成后将其重置为所需的值。从用户的角度来看,您甚至无法判断阴影已经消失,因为动画通常太快而无法感知差异。

这是我的应用程序中一些代码的示例,其中我正在更改约束的常量值,即“到超级视图的后沿”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];
}

两件事情:

  • 我本可以将fadeInShadow 放在完成块中,但是由于我的一些其他代码被分解的方式,这对我来说效果更好。
  • 我意识到我没有使用“fadeInShadow”执行淡入,但考虑到它在动画完成后渲染的速度,我发现没有必要。

希望有帮助!

于 2013-02-02T03:48:14.333 回答