0

クラスで次のメソッドを呼び出して無限にアニメーション化するビューコントローラーのメインビュー内に、uiview のサブクラスのオブジェクトがいくつかあります。

- (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 に答える