[英]UIScrollView with scaled UIImageView using autolayout
考慮具有單個子視圖的UIScrollView
。 子視圖是具有以下大小限制的UIImageView
:
UIScrollView
的高度。 UIImageView
的高度成比例縮放的圖像寬度。 預計UIImageView
的寬度將大於UIScrollView的寬度,因此需要滾動。
可以在viewDidLoad
(如果緩存)或異步期間設置圖像。
如何使用autolayout實現上述功能,盡可能多地使用Interface builder?
根據這個答案,我配置了我的筆尖:
UIScrollView
固定在其superview的邊緣。 UIImageView
固定在UIScrollView
的邊緣。 UIImageView
具有占位符內在大小(以避免Scrollable Content Size Ambiguity錯誤) 正如預期的那樣,結果是UIImageView
的大小與UIImage
的大小相同, UIScrollView
水平和垂直滾動(因為圖像比UIScrollView
)。
然后我嘗試了各種不起作用的東西:
UIImageView
的框架。 zoomScale
。 沒有明顯的效果。 以下代碼完全按照我的意願執行,盡管沒有自動布局或界面構建器。
- (void)viewDidLoad
{
{
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view addSubview:scrollView];
self.scrollView = scrollView;
}
{
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.scrollView.frame.size.width, self.scrollView.frame.size.height)];
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.scrollView addSubview:imageView];
self.scrollView.contentSize = imageView.frame.size;
self.imageView = imageView;
}
}
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
[self layoutStripImageView];
}
- (void)layoutStripImageView
{ // Also called when the image finishes loading
UIImage *image = self.imageView.image;
if (! image) return;
const CGSize imageSize = image.size;
const CGFloat vh = self.scrollView.frame.size.height;
const CGFloat scale = vh / imageSize.height;
const CGFloat vw = imageSize.width * scale;
CGSize imageViewSize = CGSizeMake(vw, vh);
self.imageView.frame = CGRectMake(0, 0, imageViewSize.width, imageViewSize.height);
self.scrollView.contentSize = imageViewSize;
}
我正在努力轉向自動布局,但這並不容易。
在autolayout制度下,理想情況下,UIScrollView contentSize僅由約束決定,而不是在代碼中明確設置。
所以在你的情況下:
創建約束以將子視圖固定到UIScrollView
。 約束必須確保子視圖和滾動視圖之間的邊距為0.我看到你已經嘗試過這個。
為子視圖創建高度和寬度約束。 否則, UIImageView
的內在大小決定了它的高度和寬度。 在設計時,此大小只是一個占位符,以保持Interface Builder的快樂。 在運行時,它將設置為實際圖像大小,但這不是您想要的。
在viewDidLayoutSubviews
期間,將約束更新為實際內容大小。 您可以通過更改height和width約束的constant
屬性直接執行此操作,也可以調用setNeedsUpdateConstraints
並覆蓋updateConstraints
以執行相同操作。
這確保了系統可以僅從約束中派生contentSize
。
我已經完成了上述工作,並且在iOS 6和7上可靠地使用UIScrollView
和自定義子視圖,因此它也適用於UIImageView
。 特別是如果你沒有將子視圖固定到滾動視圖,iOS 6中的縮放將是緊張的。
您也可以嘗試創建直接引用滾動視圖的高度和寬度的倍數的高度和寬度約束,但我還沒有嘗試過這種其他方法。
只有在代碼中實例化視圖時才需要translatesAutoresizingMaskIntoConstraints
。 如果您在IB中實例化它,則默認情況下禁用它
在我看來, UIImageView
應該填充ScrollView
。 稍后我會嘗試將scrollview
的縮放設置為適合您的值,這樣圖像只能在一個方向上平移
在我的情況下,它是一個全寬UIImageView有一個定義的高度約束導致問題。
我在UIImageView上設置了另一個約束,其寬度與UIScrollView的寬度相匹配,因為它在界面構建器中然后添加了一個出口到UIViewController:
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *imageViewWidthConstraint;
然后在viewDidLayoutSubviews上我更新了約束:
- (void) viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
self.imageViewWidthConstraint.constant = CGRectGetWidth(self.scrollView.frame);
}
這似乎可以解決問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.