0

我有几个 uiview 子类的对象,在 viewcontroller 的主视图中,我通过在类中调用以下方法来无限地设置动画:

- (void)hover:(NSNumber *)upDown {
    int sense = [upDown intValue];
    [UIView animateWithDuration:0.8 delay:0.1 options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction
                     animations:^{                        
                         CGRect frame = self.frame;
                         frame.origin.y += (sense==1?1:-1) * 5;
                         self.frame = frame;
                     }
                     completion:^(BOOL finished){ 
                         [self hover:[NSNumber numberWithInt:(sense==1?0:1)]];
                     }];             
}

它工作得很好,除了在设备中,当按下主页按钮时,应用程序会半冻结(应用程序最终会通过反复按下主页按钮一段时间进入后台)并且与其他按钮的任何交互都会停止工作。它在任何其他情况下都可以正常工作,即只要我不按主页按钮,我就可以在控制器、按钮等...和模拟器上导航。

有任何想法吗?

更新:罪魁祸首似乎是我应用于我正在制作动画的视图的阴影

self.layer.shadowColor = [UIColor blackColor].CGColor;
self.layer.shadowOpacity = 1.0;
self.layer.shadowRadius = 5.0;

这似乎会导致某种开销,只会影响应用程序无法进入后台状态???

有人遇到过这个吗?

更新:最后我决定去掉那段代码,在 drawRect: 方法中用 Quartz 绘制阴影。我怀疑这个问题可能与 iPhone 在进入后台模式之前拍摄的快照以及应用于边界外图层的阴影有关,但这只是一个猜测。

4

3 回答 3

2

基本上问题与这种获得圆形和阴影的方式有关:

[self.layer setCornerRadius:radius];

self.layer.shadowColor = [UIColor blackColor].CGColor;
self.layer.shadowOpacity = 0.2;
self.layer.shadowRadius = 5;
self.layer.shadowOffset = CGSizeMake(0, 10);

阴影绘制在视图框架之外,iPhone 进入背景状态的过程在动画时似乎并不像那样。

正如我在更新中提到的,我摆脱了这一点,并使用 Quartz 在框架内绘制了两个形状的阴影。有很多关于如何做到这一点的帖子,但无论如何都在这里:

-(void)drawRect:(CGRect)rect
{
   const CGFloat *cComps = CGColorGetComponents([UIColor blackColor]).CGColor;
   CGContextRef context = UIGraphicsGetCurrentContext();

   CGFloat center = rect.size.width / 2.0;
   CGFloat radius = center;

   CGContextBeginPath(context);
   CGContextSetShadowWithColor(context, CGSizeMake(0, 10), 4, [UIColor colorWithWhite:0     alpha:0.1].CGColor);
   CGContextAddArc(context, center, center, radius, 0, 2*M_PI, 1);
   CGContextSetRGBFillColor(context, cComps[0], cComps[1], cComps[2], 1.0);
   CGContextFillPath(context);
}

注意:我将视图的高度设置为 +15px 以适应底部的阴影。

希望它可以帮助某人。这确实让我发疯了几天......

于 2012-04-23T11:26:39.807 回答
1

我最近遇到了这个问题,这篇文章对找出罪魁祸首非常有帮助。但事实证明,在阴影层上简单地设置 shouldRasterize 就足以防止冻结。(您还应该将 rasterizationScale 设置为与设备主屏幕的比例相同。)

我所有的阴影层都是相对静态的,并且不会一直保持动画效果,所以 YMMV。

您的标准阴影添加代码:

layer.shadowColor = [UIColor blackColor].CGColor;
layer.shadowOffset = CGSizeMake(0, 1);
layer.shadowOpacity = 0.5;
layer.shadowRadius = 1.0;

这是您需要添加的内容:

layer.rasterizationScale = [[UIScreen mainScreen] scale];
layer.shouldRasterize = YES;
于 2012-06-06T18:59:58.327 回答
0

我的第一个想法是你应该在你的 .h 文件中实现一个 BOOL(我们称之为 stopGoing)。然后执行以下操作:

- (void)hover:(NSNumber *)upDown {
    if(!stopGoing){
        int sense = [upDown intValue];
        [UIView animateWithDuration:0.8 delay:0.1 options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction
                     animations:^{                        
                         CGRect frame = self.frame;
                         frame.origin.y += (sense==1?1:-1) * 5;
                         self.frame = frame;
                     }
                     completion:^(BOOL finished){ 
                         [self hover:[NSNumber numberWithInt:(sense==1?0:1)]];
                     }];
    }  else {
        // do something else
    }           
}

然后,在您链接到按钮的 IBAction 中,执行以下操作:

-(IBAction)myButton:(id)sender{
    stopGoing = YES;
}

这应该有效地停止循环,而不会太具有侵略性。

于 2012-04-21T16:08:04.360 回答