1

私は2つの画像を持っています。画面全体を占める、同じサイズの同じシーンの両方。1 つは画像がぼやけていて、もう 1 つはピントが合っています。望ましい効果は、ユーザーが最初にぼやけた画像を表示し、画面上で指を左から右にドラッグすると、ドラッグした場所の左側にある画像の部分がフォーカスされることです (たとえば、ドラッグした場合)半分しかない場合、シーンの左半分は焦点が合った画像ですが、右半分はまだぼやけています。

UIImageViewフォーカスされた画像を画像としてサブクラス化しCALayer、マスクを適用してぼやけた画像を追加し、touchesBegan/touchesMovedに従ってマスクの位置を変更することでこれを行っています。問題は、以下のアプローチを使用するとパフォーマンスが非常に遅くなることです。だから私は何が間違っているのだろうかと思っています。

@interface DragMaskImageView : UIImageView
@end    

@implementation DragMaskImageView{
    BOOL userIsTouchingMask;
    CALayer *maskingLayer;
    CALayer *topLayer;
    float horzDistanceOfTouchFromCenter;
}

- (void)awakeFromNib {
    topLayer = [CALayer layer];    
    topLayer.contents = (id) [UIImage imageNamed:@"blurryImage.jpg"].CGImage;
    topLayer.frame = CGRectMake(0, 0, 480, 300);
    [self.layer addSublayer:topLayer];

    maskingLayer = [CALayer layer];
    maskingLayer.contents = (id) [UIImage imageNamed:@"maskImage.png"].CGImage;
    maskingLayer.anchorPoint = CGPointMake(0.0, 0.0);
    maskingLayer.bounds = CGRectMake(0, 0, 480, 300);
    [topLayer setMask:maskingLayer];
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    CGPoint touchPoint = [[[event allTouches] anyObject] locationInView:self];

    if (touchPoint.x < maskingLayer.frame.origin.x) {
        NSLog(@"user is touching to the left of mask - disregard");
        userIsTouchingMask = NO;
    } else {
        NSLog(@"user is touching ");
        horzDistanceOfTouchFromCenter = touchPoint.x - maskingLayer.frame.origin.x;
        userIsTouchingMask = YES;
    }    
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    if (userIsTouchingMask) {

        CGPoint touchPoint = [[[event allTouches] anyObject] locationInView:self];
        float newMaskX = touchPoint.x - horzDistanceOfTouchFromCenter;

        if (newMaskX < 0) {
            newMaskX = 0;
        }
        if (newMaskX > 480) {
            newMaskX = 480;
        }
        maskingLayer.frame = CGRectMake(newMaskX, 0 ,480, 300);
    }   
}

関連するスレッドコア アニメーション キャレイヤー マスク アニメーションのパフォーマンスを確認しましたが、どのレイヤーでも YES に設定shouldRasterizeしてもパフォーマンスの問題は解決しないようです。

4

2 に答える 2

4

私は同じ問題に遭遇しました、そしてマスクのフレームを更新することは常にタッチより遅れます。新しいフレームで実際にマスクを再作成すると、マスクが常に即座に更新されることがわかりました。

于 2012-07-07T21:27:32.070 に答える
4

おそらく問題は、レイヤーの暗黙的なアニメーションが原因で、動きが鈍くなっているように見えることです。暗黙的なアニメーションをオフにすると、問題が解決するはずです。

[CATransaction begin];
[CATransaction setDisableActions:YES];
maskingLayer.frame = CGRectMake(newMaskX, 0 ,480, 300);
[CATransaction commit];

これが@Rizwanの回避策が機能する理由です。これは、暗黙のアニメーションをバイパスする方法です。

于 2012-11-19T20:57:36.510 に答える