菜鸟教程小白 发表于 2022-12-11 20:06:22

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


                                            <p><p>我的应用程序的启动屏幕是一个 Collection View 。如果用户选择,他/她可以在应用启动时使用 Face ID/Touch ID “锁定”应用。我通过在我的 Collection ViewController 顶部展示一个包含 <code>UIVisualEffectView</code> 的 ViewController 来做到这一点。我在 <code>viewDidLoad</code> 中对我的 Collection ViewController 进行截图,然后将截图放在 <code>UIVisualEffectView</code> 下方的 <code>UIImageView</code> 中。 </p>

<p>问题是,截屏时没有加载 Collection View ,出现 <code>UIVisualEffectView</code>Controller 。屏幕截图包含导航栏,但 View 的内容只是黑色的。我调用该函数在 Collection View 的 <code>viewDidLoad</code> 函数中显示视觉效果 ViewController 。 </p>

<p>在我在 <code>viewDidLoad</code> 中截屏之前,有没有办法加载 Collection View 的数据?数据存储在核心数据中。我已经尝试将核心数据函数从 <code>viewWillAppear</code> 移动到 <code>viewDidLoad</code>,但这也没有用。 </p>

<p>编辑:我能够解决我的问题,但不能通过在 ViewDidLoad 中加载我的 <code>UICollectionView</code> 的数据,因为这似乎是不可能的。我在 <code>UICollectionView</code> 上直接添加了一个 <code>UIVisualEffectView</code>。我还将它作为 subview 添加到 <code>UIApplication.shared.keyWindow</code> 以便它出现在导航栏上方。编辑后的代码如下。</p>

<p>这是我的代码:</p>

<p>对于 Collection ViewController :</p>

<pre><code>import UIKit
import CoreData
import LocalAuthentication

var ssImage: UIImage?

class AlbumViewController: UIViewController {

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

var albums: = []

// MARK: - Actions

func getScreenShot()-&gt; 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(&#34;Got screenshot.&#34;)
    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&lt;NSManagedObject&gt;(entityName: &#34;Album&#34;)
    let sortDescriptor = NSSortDescriptor(key: &#34;albumName&#34;, ascending: true, selector: #selector(NSString.localizedCaseInsensitiveCompare(_:)))
    fetchRequest.sortDescriptors =
    do {
      albums = try managedContext.fetch(fetchRequest)
    } catch let error as NSError {
      print(&#34;Could not fetch. \(error), \(error.userInfo)&#34;)
    }

    //Setup
    self.albumCollectionView.reloadData()

}

override func viewDidLoad() {
    super.viewDidLoad()

    if AppSettings.requiresLogin == true {

      getScreenShot()
      let storyboard = UIStoryboard(name: &#34;Main&#34;, bundle: nil)
      let rootController = storyboard.instantiateViewController(withIdentifier: &#34;authenticateVC&#34;) 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: &#34;Album&#34;,
                                 in: managedContext)!
    let albumName = NSManagedObject(entity: entity,
                                    insertInto: managedContext)
    albumName.setValue(name, forKeyPath: &#34;albumName&#34;)
    do {
      try managedContext.save()
      albums.append(albumName)
    } catch let error as NSError {
      print(&#34;Could not save. \(error), \(error.userInfo)&#34;)
    }
}
}

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

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

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -&gt; UICollectionViewCell {
    let reuseIdentifier = &#34;AlbumCell&#34;
    // 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
    cell.albumNameLabel?.text = albumName.value(forKeyPath: &#34;albumName&#34;) as? String
    //Return the finished cell
    return cell
}
}
</code></pre>

<p>对于 UIVisualEffectViewController :</p>

<pre><code>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(&#34;Locked VC dismissed.&#34;)
      }
    }

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

    override func viewWillAppear(_ animated: Bool) {
      super.viewWillAppear(animated)
      screenshotImageView.image = ssImage
    }
}
</code></pre>

<p>编辑:我的 Collection ViewController 的修改代码:</p>

<pre><code>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: = []

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&lt;NSManagedObject&gt;(entityName: &#34;Album&#34;)
    let sortDescriptor = NSSortDescriptor(key: &#34;albumName&#34;, ascending: true, selector: #selector(NSString.localizedCaseInsensitiveCompare(_:)))
    fetchRequest.sortDescriptors =
    do {
      albums = try managedContext.fetch(fetchRequest)
    } catch let error as NSError {
      print(&#34;Could not fetch. \(error), \(error.userInfo)&#34;)
    }

    //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 = &#34;Albums are locked.Tap anywhere to use Face ID to unlock.&#34;
    case .touchID:
      lockedLabel.text = &#34;Albums are locked.Tap anywhere to use Touch ID to unlock.&#34;
    default:
      lockedLabel.text = &#34;Albums are locked.Tap anywhere to use your passcode to unlock.&#34;
    }

    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: &#34;Album&#34;,
                                 in: managedContext)!
    let albumName = NSManagedObject(entity: entity,
                                    insertInto: managedContext)
    albumName.setValue(name, forKeyPath: &#34;albumName&#34;)
    do {
      try managedContext.save()
      albums.append(albumName)
    } catch let error as NSError {
      print(&#34;Could not save. \(error), \(error.userInfo)&#34;)
    }
}
}

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

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

// make a cell for each cell index path
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -&gt; UICollectionViewCell {
    let reuseIdentifier = &#34;AlbumCell&#34;
    // 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
    cell.albumNameLabel?.text = albumName.value(forKeyPath: &#34;albumName&#34;) as? String
    //Return the finished cell
    return cell
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let albumNameFromCell = albums
    albumNameTapped = albumNameFromCell.value(forKeyPath: &#34;albumName&#34;) as! String
    self.performSegue(withIdentifier: &#34;albumCellTappedSegue&#34;, sender: self)
}
}
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>您似乎无法在 <code>viewDidLoad</code> 中加载任何 View 的内容。根据 AppleViewController 编程指南,“<code>viewDidLoad</code> 在 ViewController 的内容 View (其 View 层次结构的顶部)被创建并从 Storyboard 中加载时被调用。”基本上,它在 ViewController 及其 subview 被加载但不可见时被调用。 <code>ViewDidAppear</code> 是 ViewController 及其 subview 可见的地方。根据 AppleViewController 编程指南,“<code>viewDidAppear</code> 在 ViewController 的内容 View 添加到应用程序的 View 层次结构后立即调用。”换句话说, ViewController 及其 subview 已经可见。</p>

<p>我能够解决我的问题,虽然它的答案没有回答这个问题。我添加了该问题的答案作为对我的问题的修改。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 我可以在 ViewDidLoad 中加载 UICollectionView 的数据吗?,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/50122632/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/50122632/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 我可以在 ViewDidLoad 中加载 UICollectionView 的数据吗?