集合视图不会重新加载(Swift)

Posted

技术标签:

【中文标题】集合视图不会重新加载(Swift)【英文标题】:Collection view doesn't reload (Swift) 【发布时间】:2017-05-11 13:57:43 【问题描述】:

我正在构建一个应用程序(快速)。其中一个选项应该是允许用户选择多张照片并上传它们,或者拍照并用它创建一个帖子。 我的想法基于以下层次结构:

按下新照片发布按钮 -> 用户会看到 UICollection 视图控制器,其中包含其库中的所有照片以及选择多张照片的选项(我正在重用一个单元格以使用照片库中的图像填充这些集合视图)上面应该是相机单元格(用户需要单击按钮以允许访问相机才能拍照)。这是来自模拟器的表示。

我已经编写了从库中获取照片并将它们添加到此处的数组中的代码(我将在下面展示这些代码)。 问题是当您首次加载应用程序并尝试发布时,系统会要求您授予对照片的访问权限。尽管用户有选择,(他们同意或不同意)他们的集合视图不会更新。

需要发生的事情 - 当用户被要求授予对照片的访问权限并且他们单击“确定”时,它应该在集合视图中重新加载数据,但事实并非如此。当他们点击“不允许”时,它应该关闭整个视图控制器。这是我的代码

class CVController: UICollectionViewController, UINavigationControllerDelegate, UICollectionViewDelegateFlowLayout 

var photosLibraryArray = [UIImage]()

override func viewDidLoad() 
    super.viewDidLoad()

    grabAllPhotosFromPhoneLibrary()



// Grab All Photos from Library
func grabAllPhotosFromPhoneLibrary () 

    let imageManager = PHImageManager.default()

    let requestOptions = PHImageRequestOptions()
    requestOptions.isSynchronous = true  // synchronous works better when grabbing all images
    requestOptions.deliveryMode = .opportunistic

    let fetchOptions = PHFetchOptions()
    fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)] // if false = last image we took would show first

    let fetchResult: PHFetchResult = PHAsset.fetchAssets(with: .image, options: fetchOptions)

    // 1. Are there photos in the library
    if fetchResult.count > 0 

        // 2. if fetch.count > 0 it means there's at least 1 photo in the library
        for i in 0..<fetchResult.count 

            // 3. Cycling through the photos
            imageManager.requestImage(for: fetchResult.object(at: i), targetSize: CGSize(width: 200, height: 200), contentMode: .aspectFill, options: requestOptions, resultHandler:

                 image, error in
                    // 4. Append each image in the array
                    self.photosLibraryArray.append(image!)
            )
        

     else 
        print("You've got no photos")
        self.collectionView?.reloadData()
    

我尝试在viewWillApear()viewDidApear() 中调用collectionView.reloadData(),但没有任何效果。

【问题讨论】:

从上面发布的代码中,只有在没有照片时才调用 reloadData() 使用此self.collectionView?.reloadData() 获得事件确认。 @Spads 我还没有发布实现,因为在我的拙见中它并不是真正需要的。如果您也需要,我也可以,但它包含部分数量、部分中的项目数和项目单元格的一些基本实现。图像确实如模拟器中的屏幕截图所示加载,但只有在您授予对照片的访问权限后重新运行应用程序时才会发生这种情况 【参考方案1】:
    class CVController: UICollectionViewController, UINavigationControllerDelegate, UICollectionViewDelegateFlowLayout 

    var photosLibraryArray = [UIImage]()

    override func viewDidLoad() 
    super.viewDidLoad()

        checkPhotoLibraryPermission()
    

添加下面提到的这个功能

    func checkPhotoLibraryPermission() 
        let status = phphotoLibrary.authorizationStatus()
        switch status 
        case .authorized: 
        //handle authorized status - // call this function here
                grabAllPhotosFromPhoneLibrary()
            case .denied, .restricted : 
                //handle denied status
            case .notDetermined: 
                // ask for permissions
                PHPhotoLibrary.requestAuthorization()  status in
                    switch status 
                    case .authorized: 
                        // call this function here
                        grabAllPhotosFromPhoneLibrary()

                    case .denied, .restricted: 
                        // as above
                        _ = navigationController?.popViewController(animated: true)
                    case .notDetermined: 
                        // won't happen but still, if you want to handle.
                
        
    
    

您可以相应地在以下功能中进行更改。根据需要。

    // Grab All Photos from Library
    func grabAllPhotosFromPhoneLibrary () 

    let imageManager = PHImageManager.default()

    let requestOptions = PHImageRequestOptions()
    requestOptions.isSynchronous = true  // synchronous works better when grabbing all images
    requestOptions.deliveryMode = .opportunistic

    let fetchOptions = PHFetchOptions()
    fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)] // if false = last image we took would show first

    let fetchResult: PHFetchResult = PHAsset.fetchAssets(with: .image, options: fetchOptions)

    // 1. Are there photos in the library
    if fetchResult.count > 0 

        // 2. if fetch.count > 0 it means there's at least 1 photo in the library
        for i in 0..<fetchResult.count 

            // 3. Cycling through the photos
            imageManager.requestImage(for: fetchResult.object(at: i), targetSize: CGSize(width: 200, height: 200), contentMode: .aspectFill, options: requestOptions, resultHandler:

                 image, error in
                    // 4. Append each image in the array
                    self.photosLibraryArray.append(image!)
            )
        
    //Use this reload data here as - you want the data loaded in the array first and then show the data.

    self.collectionView?.reloadData()

     else 
        print("You've got no photos")
        //self.collectionView?.reloadData()

        // if you want to hide the view controller when there is no photo. pop the view controller from your navigation controller like this. 

     _ = navigationController?.popViewController(animated: true)
    

【讨论】:

@Swifter 这有帮助吗? 没有。还是不行。此外,这个函数grabAllPhotosFromPhoneLibrary()viewDidLoad() 中被调用,所以它是视图加载时被调用的第一件事。因此,如果用户没有授予对照片的任何访问权限,就会出现问题。当你第一次加载应用程序时,它会跳转到 else 语句并且它永远不会执行 if,除非你关闭应用程序并重新运行它。当用户允许访问照片时会调用什么?我尝试使用viewDidLoad()viewDidAppear() 并在那里调用self.collectionView?.reloadData(),但它不起作用 检查更新的答案。如果有任何冲突,请告诉我。虽然这是未经测试的。我想我在checkPhotoLibraryPermission()处理的最多

以上是关于集合视图不会重新加载(Swift)的主要内容,如果未能解决你的问题,请参考以下文章

单击按钮的Swift重新加载集合视图不起作用

集合视图不会每次都重新加载

如何重新加载 UIPageViewController 以在 Swift 中重新加载其视图

Swift:在警报视图中按下按钮后,tableView 不会重新加载数据

如何重新加载UIPageViewController以在Swift中重新加载其视图

如何自动重新加载集合视图?