だから私はSwipeViewライブラリ( https://github.com/nicklockwood/SwipeView )を使用して、iOS8のPhotosフレームワークを使用して画像を表示しています。
ただし、requestImageForAssetを呼び出すと、サムネイルサイズと、必要な大きいサイズの2つの結果が得られます。ただし、大きなイメージは返される時間にロードされないため(非同期と呼ばれます)、小さなイメージが返されます。
このコードの方が意味があります。
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)
ご覧のとおり、大きな画像が受信される前に画像ビューを返します。サムネイルを表示しないように、この大きな画像を返すようにするにはどうすればよいですか?
ありがとう。
PHImageManager
クラスのヘッダーを読み取ります
-[PHImageRequestOptions isSynchronous]がNO(またはオプションがnil)を返す場合、resultHandlerが1回以上呼び出されることがあります。通常、この場合、resultHandlerは、要求された結果を使用してメインスレッドで非同期的に呼び出されます。ただし、deliveryMode = PHImageRequestOptionsDeliveryModeOpportunisticの場合、画像データがすぐに利用可能であれば、呼び出し側スレッドでresultHandlerを同期的に呼び出すことができます。この最初のパスで返された画像データの品質が不十分である場合、後で「正しい」結果でメインスレッドで非同期にresultHandlerが再度呼び出されます。要求がキャンセルされると、resultHandlerがまったく呼び出されない場合があります。 -[PHImageRequestOptions isSynchronous]がYESを返す場合、resultHandlerは同期して呼び出しスレッドで1回だけ呼び出されます。同期リクエストはキャンセルできません。非同期リクエストの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
}];
したがって、メソッドを終了する前にブロックが呼び出されます
幸運を!
デフォルトでは、requestImageForAsset
は非同期として機能します。したがって、メソッドでは、イメージが取得される前でもreturnステートメントが実行されます。だから私の提案は、imageViewを返す代わりに、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;
})
}
注:
もう1つのオプションは、resultHandlerからの結果イメージを使用して通知を起動することです。しかし、私は上記の方法を好みます。
詳細については PHImageManager を参照してください。
resultHandler:
ブロックには、PHImageResultIsDegradedKey
キーのブール値を含む情報ディクショナリがあります。これは、結果の画像が要求された画像の低品質の代替であるかどうかを示します。
ドキュメントの内容は次のとおりです。
PHImageResultIsDegradedKey:結果画像が要求された画像の低品質の代替であるかどうかを示すブール値。 (NSNumber)
YESの場合、Photosはまだ高品質の画像を提供できなかったため、resultHandlerブロックの結果パラメーターには低品質の画像が含まれています。要求で指定したPHImageRequestOptionsオブジェクトの設定に応じて、Photosは結果ハンドラーブロックを再度呼び出して、より高品質の画像を提供する場合があります。
Appleこのメソッドのドキュメント here。 で彼らが言っていることで:
非同期リクエストの場合、Photosは結果ハンドラーブロックを複数回呼び出すことがあります。写真は最初にブロックを呼び出して、高品質の画像を準備している間に一時的に表示するのに適した低品質の画像を提供します。(低品質の画像データの場合がすぐに利用できる場合、メソッドが戻る前に最初の呼び出しが発生する可能性があります。)
あなたの場合、元のサイズの画像を取得するには時間がかかるかもしれません。それ以外の場合、あなたのコードは私には問題ないようです。
ImageViewをブロック内で書き換えるのではなく、画像を設定するだけで、すべてが期待どおりに動作するはずです。 2つの画像が表示されないようにするには、割り当てる前に画像のサイズを確認できます。
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)
}
})
以下のオプションを使用、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}
これを試してみても非同期に機能します。
[[PHImageManager defaultManager] requestImageForAsset:asset targetSize:target contentMode:PHImageContentModeAspectFill options:option resultHandler:^(UIImage *result, NSDictionary *info) {
if ([info objectForKey:@"PHImageFileURLKey"]) {
//your code
}
}];