【发布时间】:2021-04-23 00:35:54
【问题描述】:
目标:在通过 main.storyboard 中的故事板引用加载的单独故事板中,在充当初始视图控制器的 pageViewController 中,我想通过函数 .instantiateViewController(标识符:)。
问题:我试图实例化为常量的最后一个 viewController 没有加载。错误 - *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Could not load the scene view controller for identifier 'FinalVC''"
此故事板中的所有其他 viewController 都可以正常加载。最后一个视图控制器有一个正确的自定义类链接和一个唯一的故事板标识符。
调试:我创建了一个断点,在此视图控制器被实例化并在调试控制台中注意到所有其他视图控制器对象加载为“BillyCues.repeatViewController + 唯一标识号”,而最后一个 vc加载为“UIViewController + 0x000000000000000”。就好像这个 vc 不是 app bundle 的一部分或没有被正确引用,但是当我在目录中搜索时它就在那里。
我尝试过的方法不起作用:
- 检查另一个 vc 是否具有相同的标识符
- 清理构建文件夹
- 在身份检查器中选中“使用 Storyboard ID”
let finalVC = storyBoard.instantiateViewController(identifier: "FinalVC") as! FinalViewController- 重启 Xcode
- 使用相同的自定义类创建具有不同故事板标识符的全新视图控制器
- 从最后一个 vc 中的按钮和标签中删除了所有连接
- 确保 main.storyboard 中的所有故事板引用都链接了正确的故事板
结论:我所有的谷歌搜索都导致其他开发人员遇到关于 NIB 或 tableviews 不一定是视图控制器的错误。如果我的 vc 具有正确的自定义类和唯一标识符,则不应发生错误。如果有人可以提供指导,我将不胜感激;我傻眼了。
我希望我在适当的结构中寻求帮助,但如果需要更多代码或屏幕截图,请告诉我。
PageViewController 代码
import UIKit
class LauncherViewController: UIPageViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.setViewControllers([viewControllerList[0]], direction: .forward, animated: false, completion: nil)
// Do any additional setup after loading the view.
}
private var viewControllerList: [UIViewController] = {
let storyBoard = UIStoryboard.cueCreation
let firstVC = storyBoard.instantiateViewController(identifier: "CueNameVC")
let secondVC = storyBoard.instantiateViewController(identifier: "DueDateVC")
let thirdVC = storyBoard.instantiateViewController(identifier: "IconVC")
let fourthVC = storyBoard.instantiateViewController(identifier: "IconColorVC")
let fifthVC = storyBoard.instantiateViewController(identifier: "RepeatVC")
let finalVC = storyBoard.instantiateViewController(identifier: "FinalVC") as! FinalViewController
return [firstVC, secondVC, thirdVC, fourthVC, fifthVC, finalVC]
}()
var selectedReminderBill: CueObject?
public var currentIndex = 0
static var cueName: String = ""
static var cueDate: Date = Date()
static var cueIcon: Data = Data()
static var iconColor:String = "14CC7F"
static var repeatMonthly: Bool = false
// Navigation button functions below to move to the next or previous page
func pushNext() {
if currentIndex + 1 < viewControllerList.count {
self.setViewControllers([self.viewControllerList[self.currentIndex + 1]], direction: .forward, animated: true, completion: nil)
currentIndex += 1
}
}
func pullBack() {
print(currentIndex)
if currentIndex - 1 < viewControllerList.count {
self.setViewControllers([self.viewControllerList[self.currentIndex-1]], direction: .reverse, animated: true, completion: nil)
currentIndex -= 1
}
}
}
FinalViewController 代码
import UIKit
import UserNotifications
import RealmSwift
class FinalViewController: UIViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
cueName.text = LauncherViewController.cueName
dueDate.text = CueLogic.convertPaymentDateToString(for: LauncherViewController.cueDate)
iconBackgroundView.backgroundColor = colorLogic.colorWithHexString(hexString: LauncherViewController.iconColor)
cueIcon.image = UIImage(data: LauncherViewController.cueIcon)
repeatsMonthly.text = repeatMonthlyToString
}
override func viewDidLoad() {
super.viewDidLoad()
cueName.layer.cornerRadius = 15
cueName.clipsToBounds = true
iconBackgroundView.layer.cornerRadius = 20
iconBackgroundView.clipsToBounds = true
dueDate.layer.cornerRadius = 15
dueDate.clipsToBounds = true
repeatsMonthly.layer.cornerRadius = 15
repeatsMonthly.clipsToBounds = true
backButton.layer.cornerRadius = 15
backButton.clipsToBounds = true
saveButton.layer.cornerRadius = 15
saveButton.clipsToBounds = true
// Do any additional setup after loading the view.
}
let colorLogic = ColorLogic()
let realm = try! Realm()
weak var delegate: HomeScreenDelegate?
var launcher = LauncherViewController()
var repeatMonthlyToString: String {
get {
if LauncherViewController.repeatMonthly == true {
return "Repeats Monthly: Yes"
} else {
return "Repeats Monthly: No"
}
}
}
@IBOutlet var cueName: UILabel!
@IBOutlet var dueDate: UILabel!
@IBOutlet var saveButton: UIButton!
@IBOutlet var backButton: UIButton!
@IBOutlet var iconBackgroundView: UIView!
@IBOutlet var cueIcon: UIImageView!
@IBOutlet var repeatsMonthly: UILabel!
@IBAction func dismissButtonTapped(_ sender: Any) {
self.dismiss(animated: true, completion: nil)
}
@IBAction func backButtonTapped(_ sender: Any) {
if let pageController = parent as? LauncherViewController {
pageController.pullBack()
}
}
@IBAction func saveButtonTapped(_ sender: Any) {
// Request authorization from the user to allow notifications
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound], completionHandler: {success, error in
if success {
// schedule test
} else if let error = error {
print("error occured \(error)")
}
})
let newCue = CueObject()
let launcherVC = LauncherViewController.self
newCue.name = launcherVC.cueName
newCue.paymentDate = launcherVC.cueDate
newCue.icon = launcherVC.cueIcon
newCue.iconColor = launcherVC.iconColor
newCue.repeatsMonthly = launcherVC.repeatMonthly
NotificationLogic.scheduleLocalAlertForBill(named: newCue.name, due: newCue.paymentDate, repeatsMonthly: newCue.repeatsMonthly)
saveToDB(for: newCue)
delegate?.loadCuesFromRealm()
self.dismiss(animated: true, completion: nil)
}
func saveToDB(for cue: CueObject) {
do {
try realm.write({
realm.add(cue)
})
} catch {
print("Error - \(error)")
}
}
}
protocol HomeScreenDelegate: AnyObject {
func loadCuesFromRealm()
}
我在另一个 viewController 中写的扩展
extension UIStoryboard {
static let onboarding = UIStoryboard(name: "Onboarding", bundle: nil)
static let main = UIStoryboard(name: "Main", bundle: nil)
static let cueCreation = UIStoryboard(name:"CueCreation", bundle: nil)
}
【问题讨论】:
-
您是否尝试复制/粘贴 VC 标识符?会不会有隐形角色?也许取消选中/选中“从目标继承模块”。
-
我只是手动写入并取消选中“从目标继承模块” - 仍然收到相同的错误。