所以我想为我的应用程序开发演练屏幕。这是我到目前为止尝试过的。
我有3个视图控制器。
第一视图控制器具有一个UIView和两个按钮。 UIView用于显示滑动内容。第二视图控制器有两个文本字段,我想在其中显示一些信息。(DataViewController)第三视图控制器是UIPageViewController。
这里有一些代码可以更好地理解。
第一个ViewController的代码。
import UIKit
class ViewController: UIViewController{
let dataSource = ["Heading 1","Heading 2","Heading 3","Heading 4"]
@IBOutlet weak var welcomeContentView: UIView!
var currentIndex = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
configureWelcomeSlides()
}
func configureWelcomeSlides()
{
guard let welcomePageViewController = storyboard?.instantiateViewController(withIdentifier: String(describing: WelcomePageViewController.self)) as? WelcomePageViewController else{
return
}
welcomePageViewController.delegate = self
welcomePageViewController.dataSource = self
addChild(welcomePageViewController)
welcomePageViewController.didMove(toParent: self)
welcomePageViewController.view.translatesAutoresizingMaskIntoConstraints = false
welcomeContentView.addSubview(welcomePageViewController.view)
let views: [String: Any] = ["pageView": welcomePageViewController.view]
welcomeContentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[pageView]-0-|",
options: NSLayoutConstraint.FormatOptions(rawValue: 0),
metrics: nil,
views: views))
welcomeContentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[pageView]-0-|",
options: NSLayoutConstraint.FormatOptions(rawValue: 0),
metrics: nil,
views: views))
guard let startingViewController = detailViewControllerAt(index: currentIndex) else{
return
}
welcomePageViewController.setViewControllers([startingViewController], direction: .forward, animated: true, completion: nil)
}
func detailViewControllerAt(index: Int) -> WelcomePageContentController?{
if index >= dataSource.count || dataSource.count == 0 {
return nil
}
guard let welcomePageContentController = storyboard?.instantiateViewController(withIdentifier: String(describing: WelcomePageContentController.self)) as? WelcomePageContentController
else {
return nil
}
welcomePageContentController.index = index
welcomePageContentController.slideHeading!.text = dataSource[index]
return welcomePageContentController
}
}
extension ViewController: UIPageViewControllerDelegate, UIPageViewControllerDataSource {
func presentationIndex(for pageViewController: UIPageViewController) -> Int {
return currentIndex
}
func presentationCount(for pageViewController: UIPageViewController) -> Int {
return dataSource.count
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
let welcomePageContentController = viewController as? WelcomePageContentController
guard var currentIndex2 = welcomePageContentController?.index else {
return nil
}
currentIndex = currentIndex2
if currentIndex2 == 0{
return nil
}
currentIndex2 -= 1
return detailViewControllerAt(index: currentIndex2)
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
let welcomePageContentController = viewController as? WelcomePageContentController
guard var currentIndex2 = welcomePageContentController?.index else {
return nil
}
if currentIndex2 == dataSource.count {
return nil
}
currentIndex2 += 1
currentIndex = currentIndex2
return detailViewControllerAt(index: currentIndex2)
}
}
DataViewController的代码(在我的情况下,它命名为WelcomePageContentViewController)。
import UIKit
class WelcomePageContentController: UIViewController{
@IBOutlet weak var slideHeading: UITextView?
@IBOutlet weak var slideText: UITextView?
var displayText: String!
var index : Int!
override func viewDidLoad() {
super.viewDidLoad()
slideHeading!.text = displayText
slideText!.text = displayText
// Do any additional setup after loading the view.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
UIPageViewController的代码(在我的情况下,它命名为WelcomePageViewController)。
import UIKit
class WelcomePageViewController: UIPageViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
我在执行viewdidLoad()方法后从WelcomePageContentController访问文本字段,但我的应用程序仍然崩溃。
错误消息:致命错误:展开一个可选值时意外发现nil。
在此行发生崩溃。welcomePageContentController.slideHeading!.text = dataSource [index]在ViewController类中。
方法:-
func detailViewControllerAt(index:Int)-> WelcomePageContentController?
附有故事板图片。
Xcode版本(版本10.1(10B61))斯威夫特(4.2)
当从情节提要板实例化视图控制器时,实际上尚未加载视图,并且尚未设置IBOutlet
。似乎您正在试图强行访问尚未设置的UITextView
,这会导致崩溃。
从情节提要实例化视图控制器后立即尝试添加welcomePageContentController.loadViewIfNeeded()
:
guard let welcomePageContentController = storyboard?.instantiateViewController(withIdentifier: String(describing: WelcomePageContentController.self)) as? WelcomePageContentController
else {
return nil
}
welcomePageContentController.loadViewIfNeeded()
welcomePageContentController.index = index
welcomePageContentController.slideHeading!.text = dataSource[index]
这将加载视图并为您的IBOutlet
填充非零值(如果它们确实已连接到情节提要,这将允许您在文本视图中设置文本。)>