我知道这个问题已经存在,但我不认为给定的答案是令人满意/完整的:How can IOS Photos app can show hundreds of photos in one screen?
我想要实现的目标
我想要像whatsapp(iOS)中的图像选择(见截图)。当您打开相机时,还有一个水平滑块,您可以在其中查看图库中的所有图像。
我尝试了什么
现在我的appDelegate中有以下代码:
#include <wrl\client.h>
using Microsoft::WRL::ComPtr;
void GetApplicationDataDirectory(wchar_t* dir, size_t maxsize)
{
if (!maxsize) return;
*dir = 0;
#if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)
// You can use the Win32 SHGetKnownFolderPath as well which is just
// a wrapper that does the same thing.
// On Windows XP, you use the older SHGetFolderPath function with
// different constants that have the same meaning.
ComPtr<IKnownFolderManager> mgr;
HRESULT hr = CoCreateInstance(CLSID_KnownFolderManager,
nullptr, CLSCTX_INPROC_SERVER, IID_IKnownFolderManager, (LPVOID*) &mgr);
if (SUCCEEDED(hr))
{
ComPtr<IKnownFolder> folder;
hr = mgr->GetFolder(FOLDERID_LocalAppData, &folder);
if (SUCCEEDED(hr))
{
LPWSTR szPath = 0;
hr = folder->GetPath(0, &szPath);
if (SUCCEEDED(hr))
{
// A big different with Windows desktop apps is here.
// With Windows Store apps, your appdata directory is
// isolated per-user and per-app. In Windows desktop,
// it is only isolated per-user so you have to create
// your own unique subdir and other Windows desktop apps
// can mess with your data
wcscpy_s(dir, maxsize, szPath);
wcscat_s(dir, maxsize, L”\\MyUniqueApplicationName”);
CreateDirectory(dir, nullptr);
CoTaskMemFree(szPath);
}
}
}
#else // Windows Store WinRT app
auto folder = Windows::Storage::ApplicationData::Current
->LocalFolder;
wcscpy_s(dir, maxsize, folder->Path->Data());
#endif
}
稍后我将图像加载到UITableViewController中并在scroll上调用以下函数:
let options = PHFetchOptions()
options.sortDescriptors = [
NSSortDescriptor(key: "creationDate", ascending: true)
]
if let results = PHAsset.fetchAssetsWithMediaType(.Image, options: options) {
results.enumerateObjectsUsingBlock { (object, idx, _) in
if let asset = object as? PHAsset {
Variables.assets.append(asset)
}
}
println(Variables.assets.count)
Variables.imageManager.startCachingImagesForAssets(Variables.assets, targetSize: CGSizeMake(viewWidth, viewWidth), contentMode: .AspectFill, options: self.requestOptions)
}
这很有效,但我遇到的问题是,在每个应用程序启动时,我的所有资产都会被缓存。这是解决我问题的正确方法吗?如何像whatsapp一样实时显示图库照片?
答案 0 :(得分:4)
参考此Photos Framework example 在这个项目中,您应该查看文件AAPLAssetGridViewController.m以及它如何根据您的滚动位置处理缓存。
- (void)updateCachedAssets
{
BOOL isViewVisible = [self isViewLoaded] && [[self view] window] != nil;
if (!isViewVisible) { return; }
// The preheat window is twice the height of the visible rect
CGRect preheatRect = self.collectionView.bounds;
preheatRect = CGRectInset(preheatRect, 0.0f, -0.5f * CGRectGetHeight(preheatRect));
// If scrolled by a "reasonable" amount...
CGFloat delta = ABS(CGRectGetMidY(preheatRect) - CGRectGetMidY(self.previousPreheatRect));
if (delta > CGRectGetHeight(self.collectionView.bounds) / 3.0f) {
// Compute the assets to start caching and to stop caching.
NSMutableArray *addedIndexPaths = [NSMutableArray array];
NSMutableArray *removedIndexPaths = [NSMutableArray array];
[self computeDifferenceBetweenRect:self.previousPreheatRect andRect:preheatRect removedHandler:^(CGRect removedRect) {
NSArray *indexPaths = [self.collectionView aapl_indexPathsForElementsInRect:removedRect];
[removedIndexPaths addObjectsFromArray:indexPaths];
} addedHandler:^(CGRect addedRect) {
NSArray *indexPaths = [self.collectionView aapl_indexPathsForElementsInRect:addedRect];
[addedIndexPaths addObjectsFromArray:indexPaths];
}];
NSArray *assetsToStartCaching = [self assetsAtIndexPaths:addedIndexPaths];
NSArray *assetsToStopCaching = [self assetsAtIndexPaths:removedIndexPaths];
[self.imageManager startCachingImagesForAssets:assetsToStartCaching
targetSize:AssetGridThumbnailSize
contentMode:PHImageContentModeAspectFill
options:nil];
[self.imageManager stopCachingImagesForAssets:assetsToStopCaching
targetSize:AssetGridThumbnailSize
contentMode:PHImageContentModeAspectFill
options:nil];
self.previousPreheatRect = preheatRect;
}
}
//In your case this computeDifference method changes to handle horizontal scrolling
- (void)computeDifferenceBetweenRect:(CGRect)oldRect andRect:(CGRect)newRect removedHandler:(void (^)(CGRect removedRect))removedHandler addedHandler:(void (^)(CGRect addedRect))addedHandler
{
if (CGRectIntersectsRect(newRect, oldRect)) {
CGFloat oldMaxY = CGRectGetMaxY(oldRect);
CGFloat oldMinY = CGRectGetMinY(oldRect);
CGFloat newMaxY = CGRectGetMaxY(newRect);
CGFloat newMinY = CGRectGetMinY(newRect);
if (newMaxY > oldMaxY) {
CGRect rectToAdd = CGRectMake(newRect.origin.x, oldMaxY, newRect.size.width, (newMaxY - oldMaxY));
addedHandler(rectToAdd);
}
if (oldMinY > newMinY) {
CGRect rectToAdd = CGRectMake(newRect.origin.x, newMinY, newRect.size.width, (oldMinY - newMinY));
addedHandler(rectToAdd);
}
if (newMaxY < oldMaxY) {
CGRect rectToRemove = CGRectMake(newRect.origin.x, newMaxY, newRect.size.width, (oldMaxY - newMaxY));
removedHandler(rectToRemove);
}
if (oldMinY < newMinY) {
CGRect rectToRemove = CGRectMake(newRect.origin.x, oldMinY, newRect.size.width, (newMinY - oldMinY));
removedHandler(rectToRemove);
}
} else {
addedHandler(newRect);
removedHandler(oldRect);
}
}
- (NSArray *)assetsAtIndexPaths:(NSArray *)indexPaths
{
if (indexPaths.count == 0) { return nil; }
NSMutableArray *assets = [NSMutableArray arrayWithCapacity:indexPaths.count];
for (NSIndexPath *indexPath in indexPaths) {
PHAsset *asset = self.assetsFetchResults[indexPath.item];
[assets addObject:asset];
}
return assets;
}
图像缓存管理器使用所需大小的资源进行加热,然后您可以从图像缓存管理器本身检索它们。
希望它对你有所帮助。