親UIScrollViewをズームインすると、CATiledLayerで再描画の問題が発生します。
CATiledLayerでバックアップされたUIViewでPDFページをレンダリングしています。その背後には別のUIImageViewがあり、CATiledLayerが描画するページの低解像度の画像が含まれています。ズームインすると、期待どおりに機能します。CATiledLayerは、ズームレベルに応じてより高解像度の画像をレンダリングします。
ズーム後に問題が発生します。ズームインしてiPadをそのままにしておくと、表示された画像がぼやけてから鮮明になります。バッキングビューにぼやけた低解像度の画像が表示されるため、CATiledLayerが削除されているように見えます。その後、CATiledLayerが再描画されます。つまり、タイリング効果と画像の再シャープネスが表示されます。これは、アプリをそのままにして30〜40秒待つと発生します。私はそれをiPadの第3世代(新しいiPad、iPad3など)でしか観察していません。iPad2でもテストしていますが、まだ問題は発生していません。
他の誰かがこの問題に遭遇しましたか?既知の原因と、場合によっては解決策はありますか?
編集:
私のUIScrollViewDelegateメソッドは次のとおりです。
// currentPage, previousPage, and nextPage are the pdf page views
// that are having the refresh problem
- (void)positionBufferedPages {
// performs math {code omitted}
// then sets the center of the views
[previousPage.view setCenter:...];
[nextPage.view setCenter:...];
}
- (void)hideBufferedPages {
if ([previousPage.view isDescendantOfView:scrollView]) {
[previousPage.view removeFromSuperview];
}
if ([nextPage.view isDescendantOfView:scrollView]) {
[nextPage.view removeFromSuperview];
}
}
- (void)showBufferedPages {
if (![previousPage.view isDescendantOfView:scrollView]) {
[scrollView addSubview:previousPage.view];
}
if (![nextPage.view isDescendantOfView:scrollView]) {
[scrollView addSubview:nextPage.view];
}
if (![currentPage.view isDescendantOfView:scrollView]) {
[scrollView addSubview:currentPage.view];
}
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return currentPage.view;
}
- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view {
[self hideBufferedPages];
}
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollViewParam withView:(UIView *)view atScale:(float)scale {
[self positionBufferedPages];
[self showBufferedPages];
}
- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
// nothing relating to the pdf page view
// but does set the center of some other subviews on top of the pdf page views
}
問題が発生している間、scrollviewは入力を受け取らないため、これがどれほど役立つかはわかりません。上記のように、PDFページがCATiledLayerにロードされ、iPadをそのままにして(デバイスが入力を受信しない)、CATiledLayerが自動的に再描画します。
setNeedsDisplay
また、ビューとタイルレイヤーの両方でsetNeedsDisplayInRect:
、、、の呼び出しをキャッチしようとsetNeedsLayout
しましsetNeedsDisplayOnBoundsChange:
たが、これらの関数が呼び出されることなく再描画が行われます。drawLayer:inContext:
もちろん、が呼び出されますが、トレースには、バックグラウンドスレッドで開始された一部のQuartz呼び出しのみが示されているため(タイルレイヤーがバックグラウンドでコンテンツを準備するため、予想どおり)、それも役に立ちません。
前もって感謝します!