Ios 照片框架。requestImageForAsset返回两个结果。Can';设置图像视图

Ios 照片框架。requestImageForAsset返回两个结果。Can';设置图像视图,ios,uiimageview,uicollectionview,photosframework,Ios,Uiimageview,Uicollectionview,Photosframework,因此,我使用SwipeView库()使用iOS8的照片框架显示图像 然而,当我调用requestImageForAsset时,我注意到我得到了两个结果,一个是缩略图大小,另一个是我想要的更大的大小。但是,较大的映像没有及时加载(我理解为async),因此它返回较小的映像 这段代码可能更有意义 func swipeView(swipeView: SwipeView!, viewForItemAtIndex index: Int, reusingView view: UIView!) -&g

因此,我使用SwipeView库()使用iOS8的照片框架显示图像

然而,当我调用requestImageForAsset时,我注意到我得到了两个结果,一个是缩略图大小,另一个是我想要的更大的大小。但是,较大的映像没有及时加载(我理解为async),因此它返回较小的映像

这段代码可能更有意义

    func swipeView(swipeView: SwipeView!, viewForItemAtIndex index: Int, reusingView view: UIView!) -> UIView! {
            let asset: PHAsset = self.photosAsset[index] as PHAsset

    var imageView: UIImageView!

    let screenSize: CGSize = UIScreen.mainScreen().bounds.size
    let targetSize = CGSizeMake(screenSize.width, screenSize.height)


    var options = PHImageRequestOptions()
//        options.deliveryMode = PHImageRequestOptionsDeliveryMode.Opportunistic
    options.resizeMode = PHImageRequestOptionsResizeMode.Exact


    PHImageManager.defaultManager().requestImageForAsset(asset, targetSize: targetSize, contentMode: .AspectFill, options: options, resultHandler: {(result, info)in
        println("huhuhuh")
        println(result.size)
        println(info)
        imageView = UIImageView(image: result)
    })
    println("setting view)
    return imageView
}
以下是日志输出:

Enteredhuhuhuh
(33.5,60.0)
SETTING VIEW
huhuhuh
(320.0,568.0)
如您所见,它在接收大图像之前返回图像视图。我如何让它返回这个更大的图像,这样它就不会显示拇指泥了


谢谢

查看苹果公司的文档了解这种方法,因为他们说:

对于异步请求,照片可能会调用结果处理程序块 不止一次。Photos首先调用块以提供低质量的 适合在准备打印时临时显示的图像 高质量图像。(如果立即删除低质量图像数据 如果可用,则第一次调用可能在方法返回之前发生。)


对于您来说,获取原始大小的图像可能需要一些时间。否则,您的代码对我来说似乎没问题。

您不应该在块内重写imageView,只需将image设置为它,一切都应该按照您的预期工作。为了避免显示两个图像,可以在指定之前检查图像的大小

var imageView =  UIImageView()
...
...
        PHImageManager.defaultManager().requestImageForAsset(asset, targetSize: targetSize, contentMode: .AspectFill, options: options, resultHandler: {(result, info)in
                println("huhuhuh")
                println(result.size)
                println(info)
                if result.size.width > 1000 &&  result.size.height > 1000 { // add any size you want 
                     imageView.setImage(result)
                }
            })

读取PHImageManager类的标题

If-[PHImageRequestOptionsisSynchronous]返回否(或选项为 nil),可以调用resultHandler 1次或多次。通常在这种情况下 在这种情况下,将在主线程上异步调用resultHandler 与要求的结果。但是,如果是deliveryMode= PHIMAGERequestOptionDeliveryMode机会主义,结果可能是 如果有图像数据丢失,则在调用线程上同步调用 立即可用。如果第一次传递中返回的图像数据 质量不足,将再次调用resultHandler, 稍后在主线程上使用“正确”同步 结果。如果请求被取消,则可能不会调用resultHandler 完全如果-[PHImageRequestOptions isSynchronous]返回YES, resultHandler将在服务器上同步调用一次 调用线程。无法取消同步请求。 异步请求的resultHandler,始终在主线程上调用

因此,您要做的是使
resultHandler
同步调用

PHImageRequestOptions *option = [PHImageRequestOptions new];
option.synchronous = YES;

[[PHImageManager defaultManager] requestImageForAsset:asset targetSize:target contentMode:PHImageContentModeAspectFill options:option resultHandler:^(UIImage *result, NSDictionary *info) {
        //this block will be called synchronously
}];
因此,在结束方法之前将调用块


祝你好运

默认情况下,
requestImageForAsset
是异步的。因此,在您的方法中,甚至在检索图像之前都会执行return语句。因此,我的建议是,不要返回imageView,而是传递imageView,因为您需要填充图像:

func swipeView(swipeView: SwipeView!, viewForItemAtIndex index: Int, reusingView view: UIView!, yourImageView: UIImageView)
{
    let asset: PHAsset = self.photosAsset[index] as PHAsset

    var imageView: UIImageView! = yourImageView;

    let screenSize: CGSize = UIScreen.mainScreen().bounds.size
    let targetSize = CGSizeMake(screenSize.width, screenSize.height)


    var options = PHImageRequestOptions()
    options.resizeMode = PHImageRequestOptionsResizeMode.Exact

    PHImageManager.defaultManager().requestImageForAsset(asset, targetSize: targetSize, contentMode: .AspectFill, options: options, resultHandler: {(result, info)in
        imageView.image = result;
    })
}
注意:

另一个选项是,您可以从resultHandler使用结果图像触发通知。但是我更喜欢上面提到的方法


有关详细信息,请参阅。

resultHandler:
块具有信息字典,该字典可能包含
PHImageResultIsDegradedKey
键的布尔值,该值指示结果图像是否是请求图像的低质量替代品

以下是文档说明的内容:

PHImageResultIsDegradedKey:一个布尔值,指示 结果图像是请求图像的低质量替代品。 (国家统计局编号)

如果是,resultHandler块的结果参数包含 低质量图像,因为照片还不能提供 更高质量的图像。取决于您在中的设置 随请求一起提供的PHImageRequestOptions对象, 照片可能会再次调用结果处理程序块以提供 更高质量的图像


尝试此操作也可以异步工作

[[PHImageManager defaultManager] requestImageForAsset:asset targetSize:target contentMode:PHImageContentModeAspectFill options:option resultHandler:^(UIImage *result, NSDictionary *info) {
    if ([info objectForKey:@"PHImageFileURLKey"]) {
      //your code
    }
}];
使用以下选项,swift 3.0


这是我应用过的最好的解决方案,它工作得非常好

let imageManager = PHImageManager.default()
        let requestOptions = PHImageRequestOptions()
    requestOptions.deliveryMode =  .highQualityFormat
    requestOptions.version = .current
    requestOptions.resizeMode = .exact
    requestOptions.isSynchronous = true

    imageManager.requestImage(for: self.assets.first!, targetSize: PHImageManagerMaximumSize, contentMode: .aspectFit, options: nil, resultHandler: { image, info in
        if let info = info, info["PHImageFileUTIKey"] == nil {
            if let isDegraded = info[PHImageResultIsDegradedKey] as? Bool, isDegraded {
                //Here is Low quality image , in this case return
                print("PHImageResultIsDegradedKey =======> \(isDegraded)")
                return
            }
            //Here you got high resilutions image
            
        }
    })

我认为VietHung有正确的答案。要强制返回全分辨率图像,请选择同步选项。否则,您可以保持代码不变,首先显示低分辨率缩略图,然后允许对块进行第二次调用以更新图像视图中的图像。这很可能就是苹果选择在主线程上执行回调的原因,这样你就可以在完整的分辨率图像可用后进行任何更新。如果你选择后者,也许可以在块中的imageView上调用setNeedsDisplay,看看会发生什么。这正是我想要的。超级:)太好了!很好的解释,谢谢。很好的解释。你已经解决了这个问题吗?使用
options.isSynchronous=true
uhh,这种解决方案是一种非常不可靠的黑客攻击,请参阅公认的答案以获得一个好的解决方法密钥PhimageResultisDegradeKey的值在这种情况下为false
let imageManager = PHImageManager.default()
        let requestOptions = PHImageRequestOptions()
    requestOptions.deliveryMode =  .highQualityFormat
    requestOptions.version = .current
    requestOptions.resizeMode = .exact
    requestOptions.isSynchronous = true

    imageManager.requestImage(for: self.assets.first!, targetSize: PHImageManagerMaximumSize, contentMode: .aspectFit, options: nil, resultHandler: { image, info in
        if let info = info, info["PHImageFileUTIKey"] == nil {
            if let isDegraded = info[PHImageResultIsDegradedKey] as? Bool, isDegraded {
                //Here is Low quality image , in this case return
                print("PHImageResultIsDegradedKey =======> \(isDegraded)")
                return
            }
            //Here you got high resilutions image
            
        }
    })