我的应用程序的启动屏幕是一个 Collection View 。如果用户选择,他/她可以在应用启动时使用 Face ID/Touch ID “锁定”应用。我通过在我的 Collection View Controller 顶部展示一个包含 UIVisualEffectView
的 View Controller 来做到这一点。我在 viewDidLoad
中对我的 Collection View Controller 进行截图,然后将截图放在 UIVisualEffectView
下方的 UIImageView
中。
问题是,截屏时没有加载 Collection View ,出现 UIVisualEffectView
Controller 。屏幕截图包含导航栏,但 View 的内容只是黑色的。我调用该函数在 Collection View 的 viewDidLoad
函数中显示视觉效果 View Controller 。
在我在 viewDidLoad
中截屏之前,有没有办法加载 Collection View 的数据?数据存储在核心数据中。我已经尝试将核心数据函数从 viewWillAppear
移动到 viewDidLoad
,但这也没有用。
编辑:我能够解决我的问题,但不能通过在 ViewDidLoad 中加载我的 UICollectionView
的数据,因为这似乎是不可能的。我在 UICollectionView
上直接添加了一个 UIVisualEffectView
。我还将它作为 subview 添加到 UIApplication.shared.keyWindow
以便它出现在导航栏上方。编辑后的代码如下。
这是我的代码:
对于 Collection View Controller :
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 Controller :
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
}
}
编辑:我的 Collection View Controller 的修改代码:
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)
}
}
您似乎无法在 viewDidLoad
中加载任何 View 的内容。根据 Apple View Controller 编程指南,“viewDidLoad
在 View Controller 的内容 View (其 View 层次结构的顶部)被创建并从 Storyboard 中加载时被调用。”基本上,它在 View Controller 及其 subview 被加载但不可见时被调用。 ViewDidAppear
是 View Controller 及其 subview 可见的地方。根据 Apple View Controller 编程指南,“viewDidAppear
在 View Controller 的内容 View 添加到应用程序的 View 层次结构后立即调用。”换句话说, View Controller 及其 subview 已经可见。
我能够解决我的问题,虽然它的答案没有回答这个问题。我添加了该问题的答案作为对我的问题的修改。
关于ios - 我可以在 ViewDidLoad 中加载 UICollectionView 的数据吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50122632/
欢迎光临 OStack程序员社区-中国程序员成长平台 (https://ostack.cn/) | Powered by Discuz! X3.4 |