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

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

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

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

Q&A

解決済

1回答

2300閲覧

FSCalendarで取得した日付を遷移前のViewControllerに遷移させたいです。

NobleNote

総合スコア4

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

0グッド

0クリップ

投稿2020/09/09 07:45

swift初学者です。FSCalendarで取得した日付を遷移させる方法が分からないです。
元のViewControllerのButtonからsegueで遷移して、FSCalendarをmodalで表示しています。
segueのidentifierは「toCalendar」です。

import UIKit import FSCalendar_Persian class CalendarViewController: UIViewController, FSCalendarDelegate { var calendar = FSCalendar() var getDate: String? override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. calendar.delegate = self } override func viewWillLayoutSubviews() { super .viewWillLayoutSubviews() calendar.frame = CGRect(x: 0, y: 100, width: view.frame.size.width, height: view.frame.size.width) view.addSubview(calendar) } func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) { let formattar = DateFormatter() formattar.dateFormat = "MM-dd-YYYY" self.getDate = formattar.string(from: date) self.performSegue(withIdentifier: "toCalendar", sender: nil) // print("(self.getDate)") } @IBAction func backButton(_ sender: Any) { if self.presentingViewController is UINavigationController { dismiss(animated: true, completion: nil) } else { self.navigationController?.popViewController(animated: true) } } // 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. if segue.identifier == "toCalendar" { let FirstVC = segue.destination as! FirstViewController FirstVC.titleLabel = self.getDate } } }

getDateで日付を取得することに成功したのですが、ここから取得した日付を元のViewControllerへの持っていき方が分かりません。
これまでは遷移してきたsegueのidentifierを使用して、saveButtonなどをExitに繋いで、元のViewControllerに遷移していたのですが、カレンダーをタップして日付を取得しているため、このやり方ではできませんでした(できるかもしれませんが、やり方が分かりません)。
Main.storyboardでViewをExitや遷移させたい所に引っ張ってみたりしたのですが、できませんでした。

遷移してきたsegueを使用する方法、または別の方法で、取得した日付を遷移させる方法を教えていただきたいです。よろしくお願いします。

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

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

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

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

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

TsukubaDepot

2020/09/09 08:49 編集

StoryBoardベースであれば、具体的には unwindSegue を使うことになるかと思います。 遷移先で表示された FSCalendarの日付をタップしたあと、どのような動作を想定されているのでしょうか。 1. カレンダーをタップすると日付が表示されるので、何らかのボタン(「戻る」)などを押して元の画面に戻る 2. 日付をタップした瞬間に元の画面に戻る 両方とも unwindSegue で実装できますが、説明の仕方が微妙にことなりますので、ご期待の動作を教えていただければと思います。
NobleNote

2020/09/09 10:08

ありがとうございます! 日付をタップした瞬間に元の画面に戻ることを想定しています。 よろしくお願いいたします。
guest

回答1

0

ベストアンサー

元の ViewController に値を渡す方法はいくつかあるのですが、StoryBoard を使っているのであれば、 unwindSegue を使うのが一番便利かもしれません。

ここでは FSCalendar は使わずに、ボタンを配置したシンプルな例で示しますが、考え方は全く同じなので、作られているアプリに合わせて変更していただければと思います。

まず、遷移元 に unwindSegue で戻ってきた時に実行する関数と、値を受け取るための変数を定義します。

Swift

1import UIKit 2 3class ViewController: UIViewController { 4 var dataFromNextVC: String? 5 6 override func viewDidLoad() { 7 super.viewDidLoad() 8 // Do any additional setup after loading the view. 9 } 10 11 @IBAction func unwindFunc(for unwindSegue: UIStoryboardSegue, towards subsequentVC: UIViewController) { 12 if let data = dataFromNextVC { 13 print(#function, data) 14 } 15 } 16}

ここでは、dataFromNextVC で値をうけとることにします。

また、unwindSegue で実行される関数名(ここではunwindFunc(for:subsequentVC:))ですが、名称そのものに制限はありません。ただし、引数の数と形式にはきまりがありますので、とりあえず上記のように定義しておくのがいいかと思います。

次に、Storyboard で Segue の設定をします。

「日付を決めたら元の ViewController に戻る」ということなので、prepare()を使って Segue を実行する例をご紹介します。

この場合、遷移先の ViewController で unwindSegue を作ります。

イメージ説明

上記の画面で「Next View Controller」とポップアップが出ているアイコンのところから(ポップアップの名称は、遷移先のクラス名によって異なってきます)、2つ右の Exit のボタンにドラッグします。ちょうど、ViewController 間で Segue を張るのと同じような操作方法で、今回の場合は Next View Controller から Exit の間で Segue を貼ります。

また、Segue に対して識別子(identifier)を設定します。通常の Segue であれば ViewController 間で線の形で見えていますが、今回は見えていませんので、左側ペインんのところにある、「unwind seuge ...」と書かれている部分をクリックし、Attribute inspector で identifier を設定します。ここでは back と設定しました。

次に、遷移先での操作について説明します。

Swift

1class NextViewController: ViewController { 2 override func viewDidLoad() { 3 super.viewDidLoad() 4 } 5 6 @IBAction func button(_ sender: Any) { 7 performSegue(withIdentifier: "back", sender: nil) 8 } 9 10 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 11 if let prevVC = segue.destination as? ViewController { 12 prevVC.dataFromNextVC = "戻ってきたよ" 13 } 14 } 15}

ここでは、「Back」ボタンを押したらbutton(_:)が実行されるようにアウトレットを設定しています。

ボタンを押したら Segue を実行するようにしています。ここでは、backと名付けられた Segue を実行したいので、

Swift

1 performSegue(withIdentifier: "back", sender: nil)

のような感じで実行させます。

FSCalendar と連携させるのであれば、日付を取得したあと、このメソッドを実行するような形になるかと思います。

実際に遷移元の ViewController に値を渡すのはprepare(for:sender:)の部分です。

Swift

1 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 2 if let prevVC = segue.destination as? ViewController { 3 prevVC.dataFromNextVC = "戻ってきたよ" 4 } 5 }

いわゆる、通常の「値渡し」と同じく、segue.destination には遷移先、つまり今回は「遷移元」の ViewController のインスタンスが入ってきますので、ViewController のプロパティであるdataFromNextVC に適切に値を代入します。

さて、問題は ViewControllerに戻ってきた値をどのようにして扱うかです。

ただ、unwindSegue を使った場合にはそれほどややこしくはなく、unwindSegue が実行された場合、ViewController の

Swift

1 @IBAction func unwindFunc(for unwindSegue: UIStoryboardSegue, towards subsequentVC: UIViewController) { 2 if let data = dataFromNextVC { 3 print(#function, data) 4 } 5 }

の部分が実行されますので、ここで希望した処理を行えば良いということになります。
今回は、実行している関数名と渡されたデータを表示しているだけですが、もちろん他の処理を行ってもかまいません。

また、unwindSegue は一つしか設定していませんので、identifier のチェックなどはおこなっていませんが、当然きちんと判別した方が安全性は上がります。

まずは、FSCalendar を使わずに簡単なプロジェクトを作成し、どのように値が渡ってくるかを確認してみるのがいいかと思います。

投稿2020/09/09 11:38

TsukubaDepot

総合スコア5086

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

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

NobleNote

2020/09/09 12:37

回答していただきありがとうございます。 教えていただいたことを参考に下記内容で受け取り側を作成してみましたが、 「has no segue with identifier 'toCalendar'"」のエラーが出てしまいました。 こちらは「toCalendar」のidentifierが指定されていないということでしょうか? segueのidentifierには「toCalendar」が設定されているのですが、 一度identifierを変更したので、そちらが影響しているのでしょうか? よろしくお願いいたします。 ``` @IBAction func unwindToDate(sender: UIStoryboardSegue) { guard let sourceVC = sender.source as? CalendarViewController, let date = sourceVC.getDate else { return } self.titleLabel?.append(date) } ```
NobleNote

2020/09/09 13:44

色々いじっていたら設定できていないidentifierを見つけることができ、遷移させることができました。 回答していただき誠にありがとうございました。 非常に助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問