具有居中 UIImageView 的 UIScrollView,如照片应用

我想要一个带有图像内容视图的滚动视图.图像实际上是比屏幕大得多的地图.地图最初应该位于滚动视图的中心,就像您将 iPhone 转为横向时照片应用程序中的照片一样.

I would like to have scroll view with an image content view. The image is actually map which is much bigger than the screen. The map should be initially in the center of the scroll view, like photos in Photos app when you turn iPhone to landscape orientation.

我没有设法让地图同时正确缩放和滚动.假设地图图像从屏幕顶部开始(纵向),代码如下所示:

I did not manage to have the map in the center with correct zooming and scrolling at the same time. Provided that the map image starts from the top of the screen (in portrait orientation), the code looks something like:

- (void)loadView {
    mapView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"map.jpg"]];
    CGFloat mapHeight = MAP_HEIGHT * SCREEN_WIDTH / MAP_WIDTH;
    mapView.frame = CGRectMake(0, 0, SCREEN_WIDTH, mapHeight);
    scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)];
    scrollView.delegate = self;
    scrollView.contentSize = mapView.frame.size;
    scrollView.maximumZoomScale = MAP_WIDTH / SCREEN_WIDTH;
    scrollView.minimumZoomScale = 1;
    [scrollView addSubview:mapView];
    self.view = scrollView;
}

当我将图像框架移动到中心时,图像只会从其框架的顶部向下增长.我尝试使用 mapView 转换,动态更改 imageView 的框架.到目前为止,没有什么对我有用.

When I move the image frame to the center, the image grows only from the top of its frame down. I tried to play around with mapView transform, with dynamically changing frame of the imageView. Nothing works for me so far.

推荐答案

这段代码应该可以在大多数版本的 iOS 上运行(并且已经过测试可以在 3.1 以上版本上运行).

This code should work on most versions of iOS (and has been tested to work on 3.1 upwards).

它基于 Jonah 的回答中提到的 Apple WWDC 代码.

It's based on the Apple WWDC code mentioned in Jonah's answer.

将以下内容添加到您的 UIScrollView 子类中,并将 tileContainerView 替换为包含您的图像或图块的视图:

Add the below to your subclass of UIScrollView, and replace tileContainerView with the view containing your image or tiles:

- (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;
}

相关文章