0

私のアプリの状況:
現在、動的な画像を表示するアプリを使用しています。そして、現在の画像をキャプチャしてディスクに保存したいと思います。

私の目標:
私はアニメーション化された視覚効果に取り組んでいます: 上に画像ビューを追加し、元のフレームから CGRecrZero にアニメーション化します。最後に、アニメーションが完了したら、この画像ビューを Vie 階層から削除します。


今の問題:
初めてアクションをトリガーすると、うまくいくようです。しかし、2 回目にトリガーすると、画像ビューはアニメーション化されず、すべてのサブビューの上にとどまります。


ビューコントローラーのコード(ARC あり):

まず、これはスナップショットをトリガーする IBAction です。

- (IBAction)actionSaveSnapshot:(id)sender
{
    ...    // Save the image file. This works everytime.

    NSThread *tempThread = [[NSThread alloc] initWithTarget:self
                                                   selector:@selector(threadSimulateScreenCapture:) 
                                                     object:nil];
    if (tempThread)
    {
        [tempThread start];
        tempThread = nil;     // Simply release it 
    }
}

そして、ここにスレッドがあります:

- (void)threadSimulateScreenCapture:(id)arg
{@autoreleasepool {
    NSImageView __strong *subImageView;
    subImageView = [[NSImageView alloc] init];
    NSRect subRect = [_imageView frame];    // the dynamic image view which I want to snapshot with
    const CGFloat animationTime = 0.4;

    [subImageView setWantsLayer:YES];
    [subImageView setImageScaling:NSImageScaleAxesIndependently];
    [subImageView setImage:[_imageView image]];

    dispatch_async(dispatch_get_main_queue(), ^{
        [CATransaction begin];
        [self.view addSubview:subImageView];
        [subImageView setFrame:subRect];
        [subImageView setNeedsDisplay:YES];
        [CATransaction commit];
    });

    [NSThread sleepForTimeInterval:0.01];
    dispatch_async(dispatch_get_main_queue(), ^{
        [CATransaction begin];
        [CATransaction setAnimationDuration:animationTime];
        [subImageView.layer setFrame:CGRectZero];
        [CATransaction commit];
    });

    [NSThread sleepForTimeInterval:(NSTimeInterval)animationTime];    // wait for end of animation

    dispatch_async(dispatch_get_main_queue(), ^{
        [subImageView removeFromSuperview];
    });

    NSLog(@"SubView Count: %@\n%@", self.view.subviews, subImageView);  // MARK. described below
    subImageView = nil;    // release the image
}} // ENDS: thread and aotureleasepool

プログラムが「MARK」行まで実行されてサブビュー配列が出力されるたびに、それがsubImageViewスーパービューから削除されていないことは明らかです。そして、スレッドが終了するたびに、「コミットされていない CATransaction を持つ削除されたスレッド ....」が発生しました。

私は何を間違えましたか?

4

1 に答える 1

0

私は自分の問題を解決したかもしれません: の行に[subImageView setFrame:subRect];、別の行を挿入します:[subImageView.layer setFrame:subRect];

一方、「addSubview:」メソッドの前に別の行を追加します[self.view setWantsLayer:YES];

それは仕事のようでした。しかし、理由はわかりません。ビューとレイヤーの両方のフレームを設定する必要があるのはなぜですか?

于 2013-08-14T02:12:02.473 に答える