我可以在ViewDidLoad中加载UICollectionView的数据吗?

时间:2018-05-01 19:31:29

标签: ios swift core-data uicollectionview viewdidload

我的应用程序的启动屏幕是一个集合视图。如果用户选择,他/她可以锁定"应用程序启动时使用Face ID / Touch ID的应用程序。我通过在我的集合视图控制器顶部呈现包含UIVisualEffectView的视图控制器来完成此操作。我在viewDidLoad中截取了我的集合视图控制器,然后将屏幕截图放在UIImageView下面的UIVisualEffectView

问题是,在拍摄屏幕截图并显示UIVisualEffectView控制器时,不会加载集合视图。屏幕截图包含导航栏,但视图内容仅为黑色。我调用该函数在集合视图的viewDidLoad函数中显示视觉效果视图控制器。

viewDidLoad截取屏幕截图之前,有没有办法加载集合视图的数据?数据存储在Core Data中。我已经尝试将核心数据功能从viewWillAppear移到viewDidLoad,但这也没有用。

编辑:我能够解决我的问题,但不是通过在ViewDidLoad中加载我的UICollectionView数据,因为这似乎是不可能的。我在UIVisualEffectView的顶部直接添加了UICollectionView。我还将其作为子视图添加到UIApplication.shared.keyWindow,以便它显示在导航栏上方。编辑后的代码如下所示。

这是我的代码:

对于集合视图控制器:

import UIKit
import CoreData
import LocalAuthentication

var ssImage: UIImage?

class AlbumViewController: UIViewController {

// MARK: - Properties
@IBOutlet weak var albumCollectionView: UICollectionView!

var albums: [NSManagedObject] = []

// MARK: - Actions

func getScreenShot()-> UIImage? {

    var screenshotImage :UIImage?
    let layer = UIApplication.shared.keyWindow!.layer
    let scale = UIScreen.main.scale
    UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale);
    guard let context = UIGraphicsGetCurrentContext() else {return nil}
    layer.render(in:context)
    screenshotImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    ssImage = screenshotImage
    print("Got screenshot.")
    return screenshotImage
}

// ViewDidLoad and ViewWillAppear
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    //Core Date functions
    guard let appDelegate =
        UIApplication.shared.delegate as? AppDelegate else {
            return
    }
    let managedContext =
        appDelegate.persistentContainer.viewContext
    let fetchRequest =
        NSFetchRequest<NSManagedObject>(entityName: "Album")
    let sortDescriptor = NSSortDescriptor(key: "albumName", ascending: true, selector: #selector(NSString.localizedCaseInsensitiveCompare(_:)))
    fetchRequest.sortDescriptors = [sortDescriptor]
    do {
        albums = try managedContext.fetch(fetchRequest)
    } catch let error as NSError {
        print("Could not fetch. \(error), \(error.userInfo)")
    }

    //Setup
    self.albumCollectionView.reloadData()

}

override func viewDidLoad() {
    super.viewDidLoad()

    if AppSettings.requiresLogin == true {

        getScreenShot()
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let rootController = storyboard.instantiateViewController(withIdentifier: "authenticateVC") as! LockedLaunchVC
        self.present(rootController, animated: false, completion: nil)
    }
}

//Core Data functions
func save(name: String) {
    guard let appDelegate =
        UIApplication.shared.delegate as? AppDelegate else {
            return
    }
    let managedContext =
        appDelegate.persistentContainer.viewContext
    let entity =
        NSEntityDescription.entity(forEntityName: "Album",
                                   in: managedContext)!
    let albumName = NSManagedObject(entity: entity,
                                    insertInto: managedContext)
    albumName.setValue(name, forKeyPath: "albumName")
    do {
        try managedContext.save()
        albums.append(albumName)
    } catch let error as NSError {
        print("Could not save. \(error), \(error.userInfo)")
    }
}
}

//Collection View functions
extension AlbumViewController: UICollectionViewDataSource, UICollectionViewDelegate {

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return albums.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let reuseIdentifier = "AlbumCell"
    // get a reference to our storyboard cell
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath as IndexPath) as! AlbumsViewCell
    //Core Data methods
    let albumName = albums[indexPath.row]
    cell.albumNameLabel?.text = albumName.value(forKeyPath: "albumName") as? String
    //Return the finished cell
    return cell
}
}

对于UIVisualEffectView控制器:

import UIKit
import LocalAuthentication

class LockedLaunchVC: UIViewController {

    let bioIDAuth = BiometricIDAuth()

    @IBOutlet weak var screenshotImageView: UIImageView!
    @IBAction func unlockButtonTapped(_ sender: UIButton) {
        authAndDismiss()
    }

    func authAndDismiss(){
        bioIDAuth.authenticateUser() {
            self.dismiss(animated: true, completion: nil)
            print("Locked VC dismissed.")
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        self.modalTransitionStyle = .crossDissolve
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        screenshotImageView.image = ssImage
    }
}

编辑:我的集合视图控制器的修改代码:

import UIKit
import CoreData

class AlbumViewController: UIViewController {

// MARK: - Properties
@IBOutlet weak var albumCollectionView: UICollectionView!
@IBOutlet weak var lockedBlurView: UIVisualEffectView!
@IBOutlet weak var lockedLabelView: UIView!
@IBOutlet weak var lockedLabel: UILabel!

var albums: [NSManagedObject] = []

let bioIDAuth = BiometricIDAuth()

// MARK: - Actions

@IBAction func unwindToAlbumsScreen(sender: UIStoryboardSegue) {
}

@IBAction func unlockButtonTapped(_ sender: UIButton) {
    bioIDAuth.authenticateUser() {
        UIView.animate(withDuration: 0.25, animations: {self.lockedBlurView.alpha = 0})
    }

}

// ViewDidLoad and ViewWillAppear
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    //Core Date functions
    guard let appDelegate =
        UIApplication.shared.delegate as? AppDelegate else {
            return
    }
    let managedContext =
        appDelegate.persistentContainer.viewContext
    let fetchRequest =
        NSFetchRequest<NSManagedObject>(entityName: "Album")
    let sortDescriptor = NSSortDescriptor(key: "albumName", ascending: true, selector: #selector(NSString.localizedCaseInsensitiveCompare(_:)))
    fetchRequest.sortDescriptors = [sortDescriptor]
    do {
        albums = try managedContext.fetch(fetchRequest)
    } catch let error as NSError {
        print("Could not fetch. \(error), \(error.userInfo)")
    }

    //Setup to do when the view will appear
    self.albumCollectionView.reloadData()

}

override func viewDidLoad() {
    super.viewDidLoad()
    lockedLabelView.layer.cornerRadius = 12
    switch bioIDAuth.biometricType() {
    case .faceID:
        lockedLabel.text = "Albums are locked.  Tap anywhere to use Face ID to unlock."
    case .touchID:
        lockedLabel.text = "Albums are locked.  Tap anywhere to use Touch ID to unlock."
    default:
        lockedLabel.text = "Albums are locked.  Tap anywhere to use your passcode to unlock."
    }

    if AppSettings.requiresLogin == false {
        lockedBlurView.alpha = 0
    }
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    if AppSettings.requiresLogin == true {
        let curWin = UIApplication.shared.keyWindow
        curWin?.addSubview(lockedBlurView)
    }
}

//Core Data functions
func save(name: String) {
    guard let appDelegate =
        UIApplication.shared.delegate as? AppDelegate else {
            return
    }
    let managedContext =
        appDelegate.persistentContainer.viewContext
    let entity =
        NSEntityDescription.entity(forEntityName: "Album",
                                   in: managedContext)!
    let albumName = NSManagedObject(entity: entity,
                                    insertInto: managedContext)
    albumName.setValue(name, forKeyPath: "albumName")
    do {
        try managedContext.save()
        albums.append(albumName)
    } catch let error as NSError {
        print("Could not save. \(error), \(error.userInfo)")
    }
}
}

//Collection View functions
extension AlbumViewController: UICollectionViewDataSource, UICollectionViewDelegate {

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return albums.count
}

// make a cell for each cell index path
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let reuseIdentifier = "AlbumCell"
    // get a reference to our storyboard cell
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath as IndexPath) as! AlbumsViewCell
    //Core Data methods
    let albumName = albums[indexPath.row]
    cell.albumNameLabel?.text = albumName.value(forKeyPath: "albumName") as? String
    //Return the finished cell
    return cell
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let albumNameFromCell = albums[indexPath.row]
    albumNameTapped = albumNameFromCell.value(forKeyPath: "albumName") as! String
    self.performSegue(withIdentifier: "albumCellTappedSegue", sender: self)
}
}

1 个答案:

答案 0 :(得分:0)

您似乎无法在viewDidLoad中加载任何观看内容。根据Apple View Controller编程指南,当视图控制器的内容视图(其视图层次结构的顶部)是从故事板创建并加载时,将调用&#34; viewDidLoad。基本上,它是在加载视图控制器及其子视图时调用的,但不可见。 ViewDidAppear是视图控制器及其子视图可见的位置。根据Apple View Controller编程指南,&#34; viewDidAppear在视图控制器的内容视图添加到应用程序的视图层次结构后立即调用。&#34;换句话说,视图控制器及其子视图已可见。

我能够解决我的问题,虽然它的答案并没有回答这个问题。我将问题的答案添加为我的问题的编辑。