私のアプリケーションでは、写真アプリで使用されているのと同じような全画面の写真ビューアーをユーザーに提示したいと思います。これは1枚の写真のためのものであり、非常に簡単なはずです。ユーザーがこの1枚の写真をズームおよびパンできる機能で表示できるようにしたいだけです。
私はそれのほとんどを働いています。また、UIImageViewを中央に配置しないと、すべてが完全に動作します。ただし、画像が十分にズームアウトされている場合は、UIImageViewを画面の中央に配置する必要があります。スクロールビューの左上隅に貼り付けたくありません。
このビューを中央に配置しようとすると、垂直スクロール可能領域が本来よりも大きく表示されます。そのため、少し拡大すると、画像の上部から約100ピクセル先までスクロールできます。何が悪いのですか?
@interface MyPhotoViewController : UIViewController <UIScrollViewDelegate>
{
UIImage* photo;
UIImageView *imageView;
}
- (id)initWithPhoto:(UIImage *)aPhoto;
@end
@implementation MyPhotoViewController
- (id)initWithPhoto:(UIImage *)aPhoto
{
if (self = [super init])
{
photo = [aPhoto retain];
// Some 3.0 SDK code here to ensure this view has a full-screen
// layout.
}
return self;
}
- (void)dealloc
{
[photo release];
[imageView release];
[super dealloc];
}
- (void)loadView
{
// Set the main view of this UIViewController to be a UIScrollView.
UIScrollView *scrollView = [[UIScrollView alloc] init];
[self setView:scrollView];
[scrollView release];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Initialize the scroll view.
CGSize photoSize = [photo size];
UIScrollView *scrollView = (UIScrollView *)[self view];
[scrollView setDelegate:self];
[scrollView setBackgroundColor:[UIColor blackColor]];
// Create the image view. We Push the Origin to (0, -44) to ensure
// that this view displays behind the navigation bar.
imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, -44.0,
photoSize.width, photoSize.height)];
[imageView setImage:photo];
[scrollView addSubview:imageView];
// Configure zooming.
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
CGFloat widthRatio = screenSize.width / photoSize.width;
CGFloat heightRatio = screenSize.height / photoSize.height;
CGFloat initialZoom = (widthRatio > heightRatio) ? heightRatio : widthRatio;
[scrollView setMaximumZoomScale:3.0];
[scrollView setMinimumZoomScale:initialZoom];
[scrollView setZoomScale:initialZoom];
[scrollView setBouncesZoom:YES];
[scrollView setContentSize:CGSizeMake(photoSize.width * initialZoom,
photoSize.height * initialZoom)];
// Center the photo. Again we Push the center point up by 44 pixels
// to account for the translucent navigation bar.
CGPoint scrollCenter = [scrollView center];
[imageView setCenter:CGPointMake(scrollCenter.x,
scrollCenter.y - 44.0)];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[[self navigationController] navigationBar] setBarStyle:UIBarStyleBlackTranslucent];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent animated:YES];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[[[self navigationController] navigationBar] setBarStyle:UIBarStyleDefault];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES];
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return imageView;
}
@end
このコードは、iOSのほとんどのバージョンで動作するはずです(3.1以降で動作するようにテストされています)。
PhotoScrollerのApple WWDCコード に基づいています。
以下をUIScrollView
のサブクラスに追加し、tileContainerView
を画像またはタイルを含むビューに置き換えます。
- (void)layoutSubviews {
[super layoutSubviews];
// center the image as it becomes smaller than the size of the screen
CGSize boundsSize = self.bounds.size;
CGRect frameToCenter = tileContainerView.frame;
// center horizontally
if (frameToCenter.size.width < boundsSize.width)
frameToCenter.Origin.x = (boundsSize.width - frameToCenter.size.width) / 2;
else
frameToCenter.Origin.x = 0;
// center vertically
if (frameToCenter.size.height < boundsSize.height)
frameToCenter.Origin.y = (boundsSize.height - frameToCenter.size.height) / 2;
else
frameToCenter.Origin.y = 0;
tileContainerView.frame = frameToCenter;
}
UIViewAutoresizingオプションをチェックアウトしましたか?
(ドキュメントから)
UIViewAutoresizing
Specifies how a view is automatically resized.
enum {
UIViewAutoresizingNone = 0,
UIViewAutoresizingFlexibleLeftMargin = 1 << 0,
UIViewAutoresizingFlexibleWidth = 1 << 1,
UIViewAutoresizingFlexibleRightMargin = 1 << 2,
UIViewAutoresizingFlexibleTopMargin = 1 << 3,
UIViewAutoresizingFlexibleHeight = 1 << 4,
UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};
typedef NSUInteger UIViewAutoresizing;
この問題を解決できましたか?同様の問題が発生します。それの背後にある理由は、zoomScaleがscrollView内のサブビューの実際のサイズ(あなたの場合はimageView)に関係なく、contentSize全体に適用されるためだと思います。 contentSizeの高さは常にscrollViewフレームの高さと同じかそれよりも大きいようですが、決して小さくなることはありません。したがって、それにズームを適用すると、contentSizeの高さがzoomScale係数で乗算されます。そのため、垂直スクロールの100ピクセルほどの余分なピクセルが取得されます。