コード内のどこかでビューまたはレイヤーを意図せずに自動リリースしていないことを確認するように指示する以外は、クラッシュの処理を支援することはできません。シミュレーターが自動リリースのタイミングをデバイスとは異なる方法で処理するのを見てきました(ほとんどの場合、スレッドが関係している場合)。
ただし、ビューのスケーリングはUIScrollView
私が遭遇した問題です。ピンチズームイベント中に、 delegateメソッドでUIScrollView
指定したビューを取得し、それに変換を適用します。viewForZoomingInScrollView:
この変換により、フレームごとにビューを再描画することなく、ビューをスムーズにスケーリングできます。ズーム操作の最後に、デリゲートメソッドscrollViewDidEndZooming:withView:atScale:
が呼び出され、新しい倍率でビューのより高品質なレンダリングを実行する機会が与えられます。通常、ビューの変換をリセットしてから、ビューをCGAffineTransformIdentity
新しいサイズスケールで手動で再描画することをお勧めします。
UIScrollView
ただし、コンテンツビューの変換を監視していないように見えるため、これにより問題が発生します。次のズーム操作で、コンテンツビューの変換が全体的な倍率に設定されます。最後の倍率でビューを手動で再描画したため、表示されているスケーリングが複雑になります。
回避策として、次のメソッドを定義して、コンテンツビューにUIViewサブクラスを使用します。
- (void)setTransformWithoutScaling:(CGAffineTransform)newTransform;
{
[super setTransform:newTransform];
}
- (void)setTransform:(CGAffineTransform)newValue;
{
[super setTransform:CGAffineTransformScale(newValue, 1.0f / previousScale, 1.0f / previousScale)];
}
ここで、previousScaleはビューのfloatインスタンス変数です。次に、ズームデリゲートメソッドを次のように実装します。
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale;
{
[contentView setTransformWithoutScaling:CGAffineTransformIdentity];
// Code to manually redraw view at new scale here
contentView.previousScale = scale;
scrollView.contentSize = contentView.frame.size;
}
これにより、コンテンツビューに送信される変換は、ビューが最後に再描画されたスケールに基づいて調整されます。ピンチズームが完了すると、通常のsetTransform:
方法で調整をバイパスすることにより、変換が1.0のスケールにリセットされます。これにより、ズームの完了時に鮮明なビューを描画しながら、正しいスケーリング動作が提供されるようです。
更新(2010年7月23日):iPhone OS 3.2以降では、ズームに関するスクロールビューの動作が変更されました。これで、UIScrollView
はコンテンツビューに適用するID変換を尊重し、の相対的な倍率のみを提供し-scrollViewDidEndZooming:withView:atScale:
ます。したがって、UIView
サブクラスの上記のコードは、3.2より古いバージョンのiPhoneOSを実行しているデバイスにのみ必要です。