我正在实施一个3D Touch预览(peek)视图控制器,以便在按下PHAsset时显示。我从previewingContext:viewControllerForLocation:
返回的视图控制器只显示照片全屏。我目前没有在该视图控制器上设置preferredContentSize
,因此系统会根据需要调整它。因此,当照片不准确地适合框架时,照片上方和下方会有一些额外的填充(如果我使用ScaleAspectFill而不是Fit,则会裁剪照片)。我想确保不会发生 - 照片应该完全适合预览框架,没有额外的填充和没有裁剪。我的问题是,如何确定正确的大小?
PHAsset
有pixelWidth
和pixelHeight
可能非常有用。但是在Apple's sample code中,它指出在设置内容大小时提供的宽度应该为零,因为它没有在纵向中使用。我可以确认它确实忽略了纵向的宽度,但没有忽略横向。所以我认为我可以在预览视图控制器中检测视图的宽度,例如在viewWillAppear
中,并使用它来执行计算,但这会返回与全屏相同的宽度(375)适用于iPhone 6s)。
如何设置preferredContentSize
以适合全尺寸图像的宽高比?
//Width should be zero, because it's not used in portrait.
photoViewController.preferredContentSize = CGSize(width: 0.0, height: 0.0)
请注意,Dropbox应用程序的行为符合要求 - 预览窗口的大小适合预览的照片。当然还有照片应用程序。
答案 0 :(得分:3)
对此更多的思考,我提出了一个很好的解决方案。只是一点数学。 :)
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
if self.isShowingAsPreview {
let photoWidth = self.asset.pixelWidth
let photoHeight = self.asset.pixelHeight
let viewWidth = self.view.frame.size.width
let widthAspectRatio = CGFloat(photoWidth) / viewWidth
self.preferredContentSize = CGSizeMake(0, CGFloat(photoHeight) / widthAspectRatio)
}
}
由于纵向忽略宽度,您可能希望在偷看时将imageView
contentMode
设为.ScaleAspectFill
,{{1}弹出时。
答案 1 :(得分:1)
我必须解决同样的问题,但不是PHAssets,而是“普通”图像。
我对你的回答的问题是self.view.frame.size.width
没有在viewWillAppear
中返回正确的值,因为视图在被调用时尚未布局。此外,我不想更改contentMode
。
这是我的解决方案,对我来说总是会产生正确的preferredContentSize
(肖像和风景):
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
if (self.isShowingAsPreview) {
CGFloat viewWidth = self.view.frame.size.width;
CGFloat viewHeight = self.view.frame.size.height;
// Doesn't need to be an PHAsset, just get your image's size.
CGFloat imageAspectRatio = self.asset.pixelWidth / self.asset.pixelHeight;
if (viewWidth / viewHeight > imageAspectRatio) { // Height is limiting size
self.preferredContentSize = CGSizeMake(viewHeight*imageAspectRatio, viewHeight);
}
else { // Width is limiting size
self.preferredContentSize = CGSizeMake(viewWidth, viewWidth/imageAspectRatio);
}
}
}