照片框架。 requestImageForAsset返回两个结果。无法设置图像视图

时间:2014-12-27 18:38:36

标签: ios uiimageview uicollectionview photosframework

所以我使用SwipeView库(https://github.com/nicklockwood/SwipeView)使用iOS8的Photos框架显示图像。

然而,当我调用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)

如您所见,它会在收到大图像之前返回图像视图。如何让它返回这个较大的图像,以便它不显示缩略图?

感谢。

8 个答案:

答案 0 :(得分:76)

读取PHImageManager

的标题
  

如果 - [PHImageRequestOptions isSynchronous ]返回NO(或选项是   nil),resultHandler可以被调用1次或更多次。通常在这   case,resultHandler将在主线程上异步调用   与要求的结果。但是,如果deliveryMode =   PHImageRequestOptionsDeliveryModeOpportunistic,resultHandler可能是   如果有任何图像数据,则在调用线程上同步调用   立即可用。如果在第一次传递中返回图像数据   质量不够,结果会再次召唤出手,   以后在主线程上以“正确”的方式异步   结果。如果取消请求,则可能不会调用resultHandler   一点都不如果 - [PHImageRequestOptions isSynchronous]返回YES,   resultHandler将被调用一次,同步和在   调用线程。无法取消同步请求。   用于异步请求的resultHandler,总是在主线程上调用

所以,你要做的是让你resultHandler被称为 synchronously

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
}];

因此在结束方法之前将调用您的块

祝你好运!

答案 1 :(得分:4)

默认情况下,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中的结果图像触发通知。但我更喜欢上面提到的方法。

有关详细信息,请参阅PHImageManager

答案 2 :(得分:4)

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

这里有什么文件说明:

  

PHImageResultIsDegradedKey:一个布尔值,指示是否   结果图像是所请求图像的低质量替代品。   (的NSNumber)

     

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

答案 3 :(得分:1)

检查Apple文档以了解此方法here.他们说:

  

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

在获取原始尺寸图像的情况下,可能需要一些时间。否则你的代码对我来说似乎没问题。

答案 4 :(得分:1)

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

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

答案 5 :(得分:0)

尝试这也可以异步工作。

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

答案 6 :(得分:0)

  

使用以下选项,swift 3.0

publi var imageRequestOptions: PHImageRequestOptions{
let options = PHImageRequestOptions()
options.version = .current
options.resizeMode = .exact
options.deliveryMode = .highQualityFormat
options.isNetworkAccessAllowed = true
options.isSynchronous = true
return options}

答案 7 :(得分:0)

这是我应用的最佳解决方案,并且运行良好

SELECT
    tc.table_schema, 
    tc.constraint_name, 
    tc.table_name, 
    kcu.column_name, 
    ccu.table_schema AS foreign_table_schema,
    ccu.table_name AS foreign_table_name,
    ccu.column_name AS foreign_column_name 
FROM 
    information_schema.table_constraints AS tc 
    JOIN information_schema.key_column_usage AS kcu
      ON tc.constraint_name = kcu.constraint_name
      AND tc.table_schema = kcu.table_schema
    JOIN information_schema.constraint_column_usage AS ccu
      ON ccu.constraint_name = tc.constraint_name
      AND ccu.table_schema = tc.table_schema
WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_name='mytable';