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
UIImageView/UIScrollView forcing a fixed aspect ratio to fit the screen
提问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 UIScrollView
is 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's
content-mode in Interface Builder to "Top-Left". This appeared to work perfectly, but then I realized that the UIScrollView
would 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's
Interface Builder 中的内容模式更改为“左上角”。这似乎工作得很好,但后来我意识到它UIScrollView
不会让你滚动图像超过最初显示的部分(左上角)。您可以放大左上角部分并滚动,但永远不要超过屏幕上最初显示的内容。
Code:
代码:
Here's the code that I'm using to setup the views. imageScrollView
is the UIScrollView
, and imageView
is the UIImageView
. They are both IBOutlets
.
这是我用来设置视图的代码。imageScrollView
是UIScrollView
,imageView
是UIImageView
。他们都是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 UIGestureRecongizers
to 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 ScaleToFill
contentMode
. Setting the ScrollView's
contentMode to UIViewContentModeScaleAspectFit
didn't work on its own, since the imageView
was still being distorted.
错误的原因是 Interface Builder 强制视图使用ScaleToFill
contentMode
. 将ScrollView's
contentMode设置为UIViewContentModeScaleAspectFit
本身不起作用,因为它imageView
仍然被扭曲。
The Fix:
修复:
The following code had to be added at the end of the setup for the UIScrollView
and UIImageView
(inside of the viewDidLoad()
method):
必须在UIScrollView
and的设置结束时添加以下代码UIImageView
(在viewDidLoad()
方法内部):
[imageScrollView setContentMode:UIViewContentModeScaleAspectFit];
[imageView sizeToFit];
[imageScrollView setContentSize:CGSizeMake(imageView.frame.size.width, imageView.frame.size.height)];
Explanation:
解释:
First, the UIScrollView's
contentMode
is set to AspectFit
, like @Mike suggested. Then, sizeToFit() is called on the imageView
to override Interface Builder's annoying presets, and to make the image the correct size.
首先,UIScrollView's
contentMode
设置为AspectFit
,就像@Mike 建议的那样。然后,调用 sizeToFit()imageView
以覆盖 Interface Builder 烦人的预设,并使图像具有正确的大小。
The last line is important. You mustset the contentSize
for the ScrollView AFTER you re-size the imageView
. Otherwise, the ScrollView
will 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 ScrollView
afterresizing the ImageView
and changing the ScrollView's
contentMode
makes the ScrollView
the actual size of the image.
最后一行很重要。您必须在contentSize
重新调整imageView
. 否则,它ScrollView
会认为图像仍然是 iPad 显示器的大小,因此不会认为有任何东西可以滚动。设置的大小ScrollView
后调整大小ImageView
和改变ScrollView's
contentMode
,使ScrollView
图像的实际大小。
Hope that helped!
希望有所帮助!
Thanks for the help Mike, it got me on the right track :)
感谢迈克的帮助,它让我走上了正轨:)
- Alex
- 亚历克斯
回答by Rayfleck
Since the imageView
is the content of the scrollview, try changing the ScrollView's
content mode to UIViewContentModeScaleAspectFit
. Try calling setNeedsDisplay
on the imageview
.
由于imageView
是滚动视图的ScrollView's
内容,请尝试将内容模式更改为UIViewContentModeScaleAspectFit
。尝试调用setNeedsDisplay
的imageview
。
回答by DarkoM
For those struggling to fix image aspect in landscape mode while using UICollectionView
while needing image to be fullscreen.
对于那些UICollectionView
在需要图像全屏的情况下使用时难以在横向模式下修复图像方面的人。
In your - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
do 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
}