質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

1回答

1923閲覧

swift topViewController

3n10

総合スコア8

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2017/07/17 06:15

###前提・実現したいこと
swift初心者です。
データ管理をするアプリケーションを、参考書通りに作成しています。
エラーの原因、対処法を教えていただきたいです。

###発生している問題・エラーメッセージ

viewDidLoad() の最後の文に出ました。 value of type 'UIViewController' has no member 'topViewController'

###該当のソースコード

import UIKit import CoreData class MasterViewController: UITableViewController, NSFetchedResultsControllerDelegate { var detailViewController: DetailViewController? = nil var managedObjectContext: NSManagedObjectContext? = nil override func awakeFromNib() { super.awakeFromNib() if UIDevice.currentDevice().userInterfaceIdiom == .Pad { self.clearsSelectionOnViewWillAppear = false self.preferredContentSize = CGSize(width: 320.0, height: 600.0) } } override func viewDidLoad() { super.viewDidLoad() self.navigationItem.leftBarButtonItem = self.editButtonItem() // ボタンが押された時に呼び出されるメソッドをshowAlert:に変更する let addButton = UIBarButtonItem(barButtonSystemItem: .Add, target: self, action: "showAlert") self.navigationItem.rightBarButtonItem = addButton if let split = self.splitViewController { let controllers = split.viewControllers __###self.detailViewController = controllers[controllers.count-1].topViewController as? DetailViewController__ } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func showAlert() { let alertController = UIAlertController(title: "新規作成", message: "名前を入力してください", preferredStyle: .Alert) // アラートビューにテキストフィールドを追加 alertController.addTextFieldWithConfigurationHandler(nil) // やめるボタン let cancelAction = UIAlertAction(title: "やめる", style: .Cancel, handler: nil) // 作成するボタン let otherAction = UIAlertAction(title: "作成する", style: .Default) { [unowned self] action in if let textFields = alertController.textFields { let textField = textFields[0] self.insertNewObject(textField.text!) } } alertController.addAction(cancelAction) alertController.addAction(otherAction) // アラートビューの表示 self.presentViewController(alertController, animated: true, completion: nil) } func insertNewObject(name: String) { let context = self.fetchedResultsController.managedObjectContext let entity = self.fetchedResultsController.fetchRequest.entity! // castオブジェクトを生成する let cast = NSEntityDescription.insertNewObjectForEntityForName(entity.name!, inManagedObjectContext: context) // worktimeオブジェクトを生成する let worktime = NSEntityDescription.insertNewObjectForEntityForName("WorkTime", inManagedObjectContext: context) // personオブジェクトに名前とAddressオブジェクトをセットする cast.setValue(name, forKey: "name") cast.setValue(worktime, forKey: "worktime") // データの保存 do { try context.save() } catch { // Replace this implementation with code to handle the error appropriately. // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. //print("Unresolved error \(error), \(error.userInfo)") abort() } } // MARK: - Segues override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { print("遷移元ビューコントローラー\(segue.sourceViewController)") print("遷移先ビューコントローラー\(segue.destinationViewController)") if segue.identifier == "showDetail" { if let indexPath = self.tableView.indexPathForSelectedRow { let object = self.fetchedResultsController.objectAtIndexPath(indexPath) as! Cast let controller = (segue.destinationViewController as! UINavigationController).topViewController as! DetailViewController controller.detailItem = object controller.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem() controller.navigationItem.leftItemsSupplementBackButton = true } } } // MARK: - Table View override func numberOfSectionsInTableView(tableView: UITableView) -> Int { return self.fetchedResultsController.sections!.count } override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { let sectionInfo = self.fetchedResultsController.sections![section] return sectionInfo.numberOfObjects } override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) self.configureCell(cell, atIndexPath: indexPath) return cell } override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool { // Return false if you do not want the specified item to be editable. return true } override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { if editingStyle == .Delete { let context = self.fetchedResultsController.managedObjectContext context.deleteObject(self.fetchedResultsController.objectAtIndexPath(indexPath) as! NSManagedObject) do { try context.save() } catch { // Replace this implementation with code to handle the error appropriately. // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. //print("Unresolved error \(error), \(error.userInfo)") abort() } } } func configureCell(cell: UITableViewCell, atIndexPath indexPath: NSIndexPath) { let object = self.fetchedResultsController.objectAtIndexPath(indexPath) as! NSManagedObject cell.textLabel!.text = object.valueForKey("name")!.description } // MARK: - Fetched results controller var fetchedResultsController: NSFetchedResultsController { // 既にオブジェクトが存在していればオブジェクトを返却して処理終了 if _fetchedResultsController != nil { return _fetchedResultsController! } /* * 以下このプロパティに初めてアクセスされた時の記述 */ // フェッチリクエストオブジェクトの生成 let fetchRequest = NSFetchRequest() // エンティティ記述を取得 let entity = NSEntityDescription.entityForName("Cast", inManagedObjectContext: self.managedObjectContext!) fetchRequest.entity = entity // 一度に取得するデータのサイズを指定 fetchRequest.fetchBatchSize = 20 // データの並び順を設定 let sortDescriptor = NSSortDescriptor(key: "name", ascending: true) _ = [sortDescriptor] fetchRequest.sortDescriptors = [sortDescriptor] // Edit the section name key path and cache name if appropriate. // nil for section name key path means "no sections". let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext!, sectionNameKeyPath: nil, cacheName: "Master") aFetchedResultsController.delegate = self _fetchedResultsController = aFetchedResultsController // データの読み込みを実行 do { try self.fetchedResultsController.performFetch() } catch { fatalError("Failed to initalize FetchResultsController: \(error)") } return _fetchedResultsController! } var _fetchedResultsController: NSFetchedResultsController? = nil func controllerWillChangeContent(controller: NSFetchedResultsController) { self.tableView.beginUpdates() } func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) { switch type { case .Insert: self.tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade) case .Delete: self.tableView.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade) default: return } } ...

###試したこと
課題に対してアプローチしたことを記載してください

###補足情報(言語/FW/ツール等のバージョンなど)
swift xcode

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

エラーは UIViewControllertopViewController をメンバーに持っていない、という意味になります。

topViewControllerUINavigationController のメンバーです。
topViewController - UINavigationController

下記コードの controllers[controllers.count - 1] の箇所で NavigationController が返ってくることを期待した記述となっていますが、実際には UIViewController が返ってきているため、エラーが発生しているものと推測します。

swift

1self.detailViewController = controllers[controllers.count-1].topViewController as? DetailViewController

topViewController を参照する前に UINavigationController かどうか型のチェックを丁寧に行えば、エラーを解消できると思います。

投稿2017/07/17 12:13

ykws

総合スコア1236

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問