ライブラリ「Instructions」で[ERROR] The overlay view added to the window has empty bounds, Instructions will stop.が出た
「Instructions」はチュートリアル画面を簡単に作れるようになると言うライブラリである。そのライブラリのREADMEのチュートリアルに従って書いたが、なぜかエラーになる。
import UIKit import Instructions class ViewController: UIViewController { @IBOutlet var textFieldCollection: [UITextField]! @IBOutlet weak var sumResultLabel: UILabel! let coachMarksController = CoachMarksController() override func viewDidLoad() { super.viewDidLoad() self.coachMarksController.dataSource = self } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) self.coachMarksController.start(in: .window(over: self)) } override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) self.coachMarksController.stop(immediately: true) } @IBAction func tappedSumButtom(_ sender: Any) { sumResultLabel.text = String(textFieldCollection.compactMap{Int($0.text!)}.reduce(0,+) } } extension ViewController:CoachMarksControllerDataSource,CoachMarksControllerDelegate{ func numberOfCoachMarks(for coachMarksController: CoachMarksController) -> Int { return 1 } func coachMarksController(_ coachMarksController: CoachMarksController, coachMarkAt index: Int) -> CoachMark { return coachMarksController.helper.makeCoachMark(for: sumResultLabel) } func coachMarksController( _ coachMarksController: CoachMarksController, coachMarkViewsAt index: Int, madeFrom coachMark: CoachMark ) -> (bodyView: UIView & CoachMarkBodyView, arrowView: (UIView & CoachMarkArrowView)?) { let coachViews = coachMarksController.helper.makeDefaultCoachViews( withArrow: true, arrowOrientation: coachMark.arrowOrientation ) coachViews.bodyView.hintLabel.text = "Hello! I'm a Coach Mark!" coachViews.bodyView.nextLabel.text = "Ok!" return (bodyView: coachViews.bodyView, arrowView: coachViews.arrowView) } }
このコードはアプリ道場サロンの課題で書いたものにお試しでInstructionsを当てはめたもの。エラーの文章には「[ERROR] The overlay view added to the window has empty bounds, Instructions will stop.
」とある。日本語にすると「ウィンドウに追加されたオーバーレイビューの境界が空であるため、命令が停止します。」イマイチよくわからん。このエラーメッセージはこのライブラリで定義されているものなので、エラーメッセージで検索して定義を見てみる。
// The delegate might have paused the flow, we check whether or not it's // the case. if !self.isPaused { if coachMarksViewController.instructionsRootView.bounds.isEmpty { print(ErrorMessage.Error.overlayEmptyBounds) self.stopFlow() return } coachMarksViewController.show(coachMark: ¤tCoachMark!, at: currentIndex) { self.canShowCoachMark = true self.delegate?.didShow(coachMark: self.currentCoachMark!, afterChanging: change, at: self.currentIndex) } }
この中のoverlayEmptyBounds
がこのエラーメッセージを定義つけている定数。なのでこの部分で引っかかってデバッグエリアにエラーメッセージが出ている。見た感じだとコーチマークの描写がそもそもできて無さそうなのでcoachMarksViewController
がそもそもインスタンス化できていないのではと思った。そこでブレークポイントを使って中身を見てみたが普通に出来てた。
原因がわからず、READMEをもう一度読み直しているとあることに気づく。僕のコードだとviewWillAppear
に書いている部分をREADMEではviewDidAppear
に書いているということを・・・・!僕がviewWillAppear
に書いたのは理由があります。それはREADMEのこの部分
Be careful, you can't call
start
in theviewDidLoad
method, since the view hierarchy has to be set up and ready for Instructions to work properly.
viewDidAppear
としか書いてないもん・・・。ならの次のviewWillAppear
に書こうとなるのが普通の発想だと思うが、viewWillAppear
じゃダメだった。READMEではviewDidAppear
がきちんとが使われいた。結局上のコードも
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) self.coachMarksController.start(in: .window(over: self)) }
を
override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) self.coachMarksController.start(in: .window(over: self)) }
に直したら普通に動いた😅 ちょっとREADMEに問題があるじゃねえの?と思うのでisseで問い合わせてみたいと思います!この件については次回!