【问题标题】:Autolayout and shadow自动布局和阴影
【发布时间】:2013-09-03 20:38:40
【问题描述】:

我在使用自动布局在 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 中打开自动布局的情况下添加阴影以查看的正确方法是什么?

【问题讨论】:

  • 我只是自己计算CGRect:CGPathRef path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 320, 480)].CGPath; [cview.layer setShadowPath:path];为我工作..

标签: ios objective-c xcode ios6 autolayout


【解决方案1】:

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

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

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

这大大提高了性能!

【讨论】:

  • 这应该被标记为正确答案。这只是将我的 tableview 滚动 FPS 从 45 提高到 57。谢谢
  • 如果不使用 shadowpath ,它会减慢你的动画。你可以在这里看到我的问题stackoverflow.com/questions/27172911/…
  • 如何删除 shadowPath? nvm 我删除了该行,它认为你必须调用一个方法来删除它
【解决方案2】:

我从您的代码中删除了self.layer.shadowPath = [UIBezierPath bezierPathWithRect:self.bounds].CGPath; ,它在viewDidLoad 中为我工作,请确认。

增加shdowOffset会让你看到阴影更清晰。

【讨论】:

  • 如果我删除shadowPath,那么我的 iPhone 4 上的动画不流畅。在模拟器中它工作正常,但在真实设备上它很慢。它对你有什么作用?
  • 在我的设备上这是主要问题:)
  • @Kamil 是的,如果删除 shadowPath,动画会变慢,我在 iphone 6 上测试过,同样的问题
【解决方案3】:

遇到完全相同的问题...

虽然我无法让视图上的 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”执行淡入,但考虑到它在动画完成后渲染的速度,我发现没有必要。

希望有帮助!

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-31
  • 2019-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多