ios UIImageView/UIScrollView 强制固定纵横比以适应屏幕

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4938129/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 18:49:47  来源:igfitidea点击:

UIImageView/UIScrollView forcing a fixed aspect ratio to fit the screen

ipadiosuiscrollviewiphone

提问by AlexFZ

I am making a simple app for the iPad that consists of a giant image that you can zoom-in/out on and navigate.

我正在为 iPad 制作一个简单的应用程序,其中包含一个巨大的图像,您可以放大/缩小和导航。

This image is placed inside a UIImageView, which is then placed inside a UIScrollView.

此图像放置在 a 中UIImageView,然后将其放置在 a 中UIScrollView

The navigation and zooming work 100% fine; however, the image is loaded at a fixed aspect-ratio to fit the screen, and will never change (even when zooming-in).

导航和缩放工作 100% 良好;然而,图像以固定的纵横比加载以适应屏幕,并且永远不会改变(即使在放大时)。

I have a feeling that Interface Builder is setting some property that I'm not aware of, but I've tried everything that I can think of to fix this.

我有一种感觉,Interface Builder 正在设置一些我不知道的属性,但我已经尝试了所有我能想到的方法来解决这个问题。

The Problem:

问题:

When the app initially loads, the contents inside the UIScrollViewis automatically re-sized to exactly fit the iPad screen by having its aspect ratio changed./fixed; the actual image is giant (way bigger than the iPad resolution). This scaled aspect ratio remains even when zooming in on the image, and causes the image to look stretched.

当应用程序最初加载时,里面的内容会UIScrollView通过改变纵横比自动重新调整大小以完全适合 iPad 屏幕。/fixed; 实际图像是巨大的(比 iPad 分辨率大得多)。即使在放大图像时,这种缩放的纵横比也会保持不变,并导致图像看起来被拉伸。

No matter what I try, I cannot stop the iPad from automatically rescaling my image. I simply want the app to start with my image displayed normally (100% zoom) on the iPad, with the portion that currently fits on the iPad screen being the top-left corner of the image.

无论我尝试什么,我都无法阻止 iPad 自动重新缩放我的图像。我只是希望应用程序开始时我的图像在 iPad 上正常显示(100% 缩放),当前适合 iPad 屏幕的部分是图像的左上角。

What I've tried to fix it:

我试图解决的问题:

I tried changing the UIImageView'scontent-mode in Interface Builder to "Top-Left". This appeared to work perfectly, but then I realized that the UIScrollViewwould not let you scroll around the image past the initially displayed portion (the top-left). You could zoom-in on the top-left portion and scroll, but never past what was initially shown on the screen.

我尝试将UIImageView'sInterface Builder 中的内容模式更改为“左上角”。这似乎工作得很好,但后来我意识到它UIScrollView不会让你滚动图像超过最初显示的部分(左上角)。您可以放大左上角部分并滚动,但永远不要超过屏幕上最初显示的内容。

Code:

代码:

Here's the code that I'm using to setup the views. imageScrollViewis the UIScrollView, and imageViewis the UIImageView. They are both IBOutlets.

这是我用来设置视图的代码。imageScrollViewUIScrollViewimageViewUIImageView。他们都是IBOutlets

   // Set the needed attributes of the imageView
    [imageView setImage:[UIImage imageNamed: @"TestImage.png"]];
    imageView.userInteractionEnabled = YES;

    // Set a bunch of the imageScrollView attributes.

    // calculate minimum scale to perfectly fit image width, and begin at that scale
    float minimumScale = [imageScrollView frame].size.width  / [imageView frame].size.width;
    [imageScrollView setMinimumZoomScale:minimumScale];
    [imageScrollView setZoomScale:1];
    [imageScrollView setMaximumZoomScale:10];
    [imageScrollView setContentSize:CGSizeMake(imageView.frame.size.width, imageView.frame.size.height)];
    [imageScrollView setScrollEnabled:YES];
    [imageScrollView setUserInteractionEnabled:YES];
    imageScrollView.clipsToBounds = YES;
    imageScrollView.bounces = FALSE;
    imageScrollView.bouncesZoom = FALSE;

I also have two UIGestureRecongizersto handle tap-zooming, but I do not believe that they are the issue. When I comment them out, nothing changes.

我也有两个UIGestureRecongizers来处理点击缩放,但我不相信它们是问题所在。当我将它们注释掉时,没有任何变化。

Any help would be extremelyappreciated.

任何帮助将非常感激。

回答by AlexFZ

I fixed it!

我修好了它!

For anyone else having the same problem, here's how I fixed the code:

对于遇到同样问题的其他人,这是我修复代码的方法:

The Causeof the bug was that Interface Builder was forcing the views to use the ScaleToFillcontentMode. Setting the ScrollView'scontentMode to UIViewContentModeScaleAspectFitdidn't work on its own, since the imageViewwas still being distorted.

错误的原因是 Interface Builder 强制视图使用ScaleToFillcontentMode. 将ScrollView'scontentMode设置为UIViewContentModeScaleAspectFit本身不起作用,因为它imageView仍然被扭曲。

The Fix:

修复:

The following code had to be added at the end of the setup for the UIScrollViewand UIImageView(inside of the viewDidLoad()method):

必须在UIScrollViewand的设置结束时添加以下代码UIImageView(在viewDidLoad()方法内部):

    [imageScrollView setContentMode:UIViewContentModeScaleAspectFit];
    [imageView sizeToFit];
    [imageScrollView setContentSize:CGSizeMake(imageView.frame.size.width, imageView.frame.size.height)];

Explanation:

解释:

First, the UIScrollView'scontentModeis set to AspectFit, like @Mike suggested. Then, sizeToFit() is called on the imageViewto override Interface Builder's annoying presets, and to make the image the correct size.

首先,UIScrollView'scontentMode设置为AspectFit,就像@Mike 建议的那样。然后,调用 sizeToFit()imageView以覆盖 Interface Builder 烦人的预设,并使图像具有正确的大小。

The last line is important. You mustset the contentSizefor the ScrollView AFTER you re-size the imageView. Otherwise, the ScrollViewwill think that the image is still the size of the iPad display, and therefore won't think that there's anything to scroll. Setting the size of the ScrollViewafterresizing the ImageViewand changing the ScrollView'scontentModemakes the ScrollViewthe actual size of the image.

最后一行很重要。您必须contentSize重新调整imageView. 否则,它ScrollView会认为图像仍然是 iPad 显示器的大小,因此不会认为有任何东西可以滚动。设置的大小ScrollView调整大小ImageView和改变ScrollView'scontentMode,使ScrollView图像的实际大小。

Hope that helped!

希望有所帮助!

Thanks for the help Mike, it got me on the right track :)

感谢迈克的帮助,它让我走上了正轨:)

  • Alex
  • 亚历克斯

回答by Rayfleck

Since the imageViewis the content of the scrollview, try changing the ScrollView'scontent mode to UIViewContentModeScaleAspectFit. Try calling setNeedsDisplayon the imageview.

由于imageView是滚动视图的ScrollView's内容,请尝试将内容模式更改为UIViewContentModeScaleAspectFit。尝试调用setNeedsDisplayimageview

回答by DarkoM

For those struggling to fix image aspect in landscape mode while using UICollectionViewwhile needing image to be fullscreen.

对于那些UICollectionView在需要图像全屏的情况下使用时难以在横向模式下修复图像方面的人。

In your - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPathdo the following:

在你- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath做以下事情:

CGFloat newWidth = self.view.bounds.size.width; //if iPad in landscape and fullscreen value is 1024
CGFloat newHeight = image.size.height / image.size.width * newWidth;

cell.clipsToBounds = YES;
cell.imageView.frame = CGRectMake(0, 0, newWidth, newHeight);
cell.imageView.contentMode = UIViewContentModeScaleAspectFill;
cell.imageView.image = image;
cell.scrollView.contentSize = cell.imageView.frame.size;

The key thing is to make image view frame the correct size while keeping correct aspect ratio.

关键是在保持正确的纵横比的同时使图像视图框架具有正确的大小。

回答by david72

This code worked for me: (Swift)

这段代码对我有用:(Swift)

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    let imgView = UIImageView(image: UIImage(named: "MyImage"))
    imgView.contentMode = .ScaleAspectFit
    var size = imgView.frame.size
    size.height = size.height / size.width * scrollView.frame.width
    size.width = scrollView.frame.width
    imgView.frame.size = size
    scrollView.addSubview(imgView)
    scrollView.contentSize = size
}