根据预览视图控制器的 PHAsset 大小计算 preferredContentSize

Calculate preferredContentSize based on PHAsset size for a Preview View Controller

我正在实现 3D Touch 预览(窥视)视图控制器,以在用力按下 PHAsset 时显示。我 return 来自 previewingContext:viewControllerForLocation: 的视图控制器只是全屏显示照片。我目前没有在该视图控制器上设置 preferredContentSize,因此系统会根据需要调整它的大小。因此,当照片不完全适合框架时(或者如果我使用 ScaleAspectFill 而不是 Fit,照片会被裁剪),照片上方和下方会有一些额外的填充。我想确保不会发生这种情况 - 照片应该完全适合预览框架,没有额外的填充和裁剪。我的问题是,如何确定正确的尺寸?

PHAssetpixelWidthpixelHeight 可能非常有用。但在 Apple's sample code 中,它规定在设置内容大小时提供的宽度应为零,因为它不用于纵向。而且我可以确认它确实忽略了纵向宽度,但没有忽略横向宽度。所以我想我可以在预览视图控制器中检测视图的宽度,例如在 viewWillAppear 中,并使用它来执行计算,但是这个 return 的宽度与全屏相同( 375 iPhone 6 秒)。

如何设置 preferredContentSize 以适应全尺寸图片的纵横比?

//Width should be zero, because it's not used in portrait.
photoViewController.preferredContentSize = CGSize(width: 0.0, height: 0.0)

请注意,Dropbox 应用的行为与预期相符 - 预览 window 的尺寸适合正在预览的照片。当然还有照片应用程序。

经过进一步思考,我想到了一个很好的解决方案。只是一点点数学。 :)

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)
    }
}

因为纵向忽略了宽度,您可能需要将 imageViewcontentMode 设置为 .ScaleAspectFill(在查看时设置为 .ScaleAspectFill,在弹出时设置为 .ScaleAspectFit) .

我不得不解决同样的问题,但是,不是用 PHAssets,而是 "normal" 个图像。

我对你的回答的问题是 self.view.frame.size.width 没有 return 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);
        }
    }
}