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

Posted

技术标签:

【中文标题】根据预览视图控制器的 PHAsset 大小计算 preferredContentSize【英文标题】:Calculate preferredContentSize based on PHAsset size for a Preview View Controller 【发布时间】:2016-01-04 03:21:53 【问题描述】:

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

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

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

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

请注意,Dropbox 应用的行为符合您的要求 - 预览窗口的大小适合正在预览的照片。当然还有照片应用。

【问题讨论】:

【参考方案1】:

对此进行了更多思考,我想出了一个不错的解决方案。只是一点数学。 :)

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,在弹出时设置为.ScaleAspectFit

【讨论】:

【参考方案2】:

不过,我必须解决同样的问题,不是使用 PHAsset,而是使用“普通”图像。

我对您的回答的问题是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);
        
    

【讨论】:

以上是关于根据预览视图控制器的 PHAsset 大小计算 preferredContentSize的主要内容,如果未能解决你的问题,请参考以下文章

将 NSUrl 转换为 PHAsset iOS 8

android 屏幕适配

如何获取 PHAsset 的文件大小?

从 PHAsset 确定图像 MB 大小

如何获取视频 PHAsset 磁盘文件大小?

如何根据文本视图内容大小设置滚动视图中的启用或禁用滚动?