Autolayout和阴影

Kam*_*mil 8 xcode objective-c ios autolayout ios6

我在使用Autolayout在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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

当我调用这个方法时viewDidAppear它起作用,但是当新视图出现时,有一个短暂的时刻没有阴影并且它会在一段时间后出现.

如果我从设置shadowPath和删除行辞职self.layer.shadowPath一切正常,但视图转换不顺畅.

所以我的问题是,在启用了Autolayout的情况下,在iOS 6中添加阴影的正确方法是什么?

Yan*_*ick 14

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

self.layer.rasterizationScale = [[UIScreen mainScreen] scale]; // to define retina or not
self.layer.shouldRasterize = YES;
Run Code Online (Sandbox Code Playgroud)

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

这大大提高了性能!

  • 这应该标记为正确的答案.这只是把我的tableview滚动FPS从45到57.谢谢 (2认同)

mat*_*123 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];
}
Run Code Online (Sandbox Code Playgroud)

两件事情:

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

希望有帮助!