0

最新のSDKを使用してiOSアプリを開発しています。

私はこのように作成しますAVCaptureVideoPreviewLayer

// Create the preview layer
_videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];
[_videoPreviewLayer setFrame:self.view.bounds];
_videoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self.view.layer insertSublayer:_videoPreviewLayer atIndex:0];

そして今、私はこれをしたい:

_videoPreviewLayer.affineTransform = CGAffineTransformMakeScale(2, 2);

しかし、前[_videoPreviewLayer setFrame:self.view.bounds];に置くと、後とは異なる結果が得られます。

どこにスケールを適用する必要がありますか?

そして、設定したい場合CGAffineTransformMakeRotation(-M_PI_2); // -90 degrees、どこで設定する必要がありますか?

4

1 に答える 1

1

変換が ID ではないビューで setFrame を使用しないでください。UIViewのframeプロパティに関するAppleのドキュメントによると:

transform プロパティが恒等変換でない場合、このプロパティ [frame] の値は定義されていないため、無視する必要があります。

UIView.h では、frame プロパティの上に

ビューの実際の位置を正しく反映しないため、ビューが変換される場合はフレームを使用しないでください。代わりに境界 + センターを使用してください。

したがって、このコードで setFrame の代わりに setBounds と setCenter を使用するように切り替えれば、探している一貫した結果が得られるでしょう。

質問に直接答えるには: setFrame も使用している場合、これらの変換 (スケールまたは回転) のいずれかを配置する正しい場所はありません。setBounds と setCenter を使用すると、setBounds/setCenter の前に変換を適用しても、setBounds/setCenter の後に変換を適用しても、同じ結果が得られます。

編集: VansFannel は、これは UIView ではなく CALayer であると指摘しているため、上記のコメントは実際には当てはまりません。VansFannel のコメントのコンテキストを奪わないように、また、UIView に対する適切な警告であるため、それらを残しています。

ここで、CALayers の場合、フレーム ([_videoPreviewLayer setFrame:self.view.bounds] など) を設定すると、_videoPreviewLayer に非同一性変換がある場合でも、_videoPreviewLayer の実際のレンダリング フレームが self.view.bounds になります。CALayer のフレームは実際には派生プロパティであることを覚えておくことが重要です。これは、レイヤーの境界、位置、アンカーポイント、および変換から派生します。setFrame を使用すると、QuartzCore は、既存の anchorPoint と変換の下で setFrame に渡したフレームを生成する境界と位置を計算します。

したがって、これらの変換に何らかの効果を持たせたい場合は、setFrame の呼び出しの後に配置する必要があります。最初に変換を設定すると、setFrame はそれらを効果的に無効にします。絶対に最初に変換を設定する必要がある場合は、setFrame を避けて、レイヤーの境界と位置を直接操作する必要があります。

于 2013-03-18T18:55:27.573 に答える