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

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

ただいまの
回答率

90.32%

  • Swift

    7703questions

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

DatePickerの値を完了ボタンを押されたタイミングで取り出したい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 520

LunarStrain

score 6

 前提・実現したいこと

Swift歴 約1ヶ月の初心者です。

ストップウォッチのラップタイムの様に、過去の時間がセットされたtableview cellがあり、タップするとDate Pickerが現れて、そのセルのデータが書き換えられる様にしたいです。

Date Pickerと完了ボタンを表示しており、完了ボタンを押した時にセットされているDate Pickerの値で、元のデータを更新したいです。

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

完了ボタンを押した時にDate Pickerや完了ボタンを消すことは何とかできましたが、そのタイミングで値を取り出すことができません。

どの様なコードを書けば実現可能か、ご教示頂けると助かります。

 該当のソースコード

    //セルをタップするとDatePickerを呼び出す
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        tableView.deselectRow(at: indexPath as IndexPath, animated: true)

        //元のデータは、2次元配列に過去時間を入れてある
        let beforeChangeDate:String! = self.thingsList[self.pathNumber!][indexPath.row + 1]

        let datePicker: UIDatePicker = UIDatePicker()

        //日時データのフォーマット設定
        let dateFormatter = DateFormatter()
        dateFormatter.locale = Locale(identifier: "ja_JP")
        dateFormatter.dateStyle = .long
        dateFormatter.timeStyle = .medium
        dateFormatter.dateFormat = "yyyy年M月d日 H時mm分ss秒"
        let beforeChangeDateTypeDate = dateFormatter.date(from: (beforeChangeDate))

        // ピッカー設定
        datePicker.datePickerMode = UIDatePickerMode.date
        datePicker.locale =  Locale(identifier: "ja_JP")
        datePicker.frame = CGRect(x:0, y:(self.view.frame.height / 1 - 240), width:self.view.frame.width, height:240)
        datePicker.backgroundColor = UIColor.white
        datePicker.tag = 2

        // ピッカー初期値に元データを代入
        if let beforeChangeDateTypeDate = beforeChangeDateTypeDate {
            datePicker.date = beforeChangeDateTypeDate
        }

        // ピッカーの表示
        view.addSubview(datePicker)

        // 完了ボタンのツールバー設定
        let toolbar = UIToolbar(frame: CGRect(x: 0, y: (self.view.frame.height / 1 - 240 ), width: view.frame.size.width, height: 35))
        let spacelItem = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil)
        let doneItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector (doneButton))
        toolbar.setItems([spacelItem, doneItem], animated: true)
        toolbar.tag = 2

        // ツールバーの表示
        view.addSubview(toolbar)


    //ここの部分(元データの更新処理)を完了ボタンが押された時に動作させたい
    // @objc funcの中に移動させてもdatePickerの値やindexPath.rowの値が引き継がれない
        let pickerDate = datePicker.date
        let strPickerDate = "\(dateFormatter.string(from:pickerDate))"

        self.thingsList[self.pathNumber!][indexPath.row + 1] = strPickerDate

        tableView.reloadData()
    //ここまで

    }

    // 完了ボタン押下 (ここの処理ももっと良い書き方があるのかと思いますが、、)
    @objc func doneButton(parentView:UIView,sender:UIBarButtonItem) {
        //ピッカーを消す
        let delview = self.view.viewWithTag(2)
        delview?.removeFromSuperview()
        //ツールバーを消す
        let delview2 = self.view.viewWithTag(2)
        delview2?.removeFromSuperview()
    }

 試したこと

@objc funcの中に元データの更新処理部分を移動させてもdatePickerの値やindexPath.rowの値の取得の仕方がわからず、詰まってしまいました。

 補足情報(FW/ツールのバージョンなど)

xcode9.4.1 , swift4

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

0

この辺を見て、少し理解できました。

”#selector" に複数の引数を持たせたいです

【UIButton】addTargetのSelector経由でString型パラメタを渡す【Swift3.0】

"#selector"には複数の引数を持たせることはできないので、サブクラスを作ってプロパティに埋め込むという方法をとるそう。

fuzzballさんからコメントを頂きまして、以下の通りに直したらやりたかったことができました。
もっとまだシンプルにできそうですが、それはまたこれからの勉強ということで。

ありがとうございました。

//引き渡したいデータを入れるプロパティ用のサブクラス準備
class DoneButton:UIBarButtonItem {
    var pickerSend = UIDatePicker()
    var index:Int = 0
    var tableData = UITableView()
    var toolBarForm = UIToolbar()
}

//セルをタップするとDatePickerを呼び出す
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

  tableView.deselectRow(at: indexPath as IndexPath, animated: true)

   //元のデータは、2次元配列に過去時間を入れてある
   let beforeChangeDate:String! = self.thingsList[self.pathNumber!][indexPath.row + 1]

   let datePicker: UIDatePicker = UIDatePicker()

   let dateFormatter = DateFormatter()
   dateFormatter.locale = Locale(identifier: "ja_JP")
   dateFormatter.dateStyle = .long
   dateFormatter.timeStyle = .medium
   dateFormatter.dateFormat = "yyyy年M月d日 H時mm分ss秒"

   // ピッカー設定
   datePicker.datePickerMode = UIDatePickerMode.date
   datePicker.locale =  Locale(identifier: "ja_JP")
   datePicker.frame = CGRect(x:0, y:(self.view.frame.height / 1 - 240), width:self.view.frame.width, height:240)
   datePicker.backgroundColor = UIColor.white


   // ピッカーの表示
   view.addSubview(datePicker)

   // 完了ボタンのツールバー設定
   let toolbar = UIToolbar(frame: CGRect(x: 0, y: (self.view.frame.height / 1 - 240 ), width: view.frame.size.width, height: 35))
   let spacelItem = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil)

   //完了ボタンが押されるとfunc doneButtonへ        
   let doneItem = DoneButton(barButtonSystemItem: .done, target: self, action: #selector (doneButton))

   //その時に持っていくデータをサブクラスのプロパティに放り込んでおく
   doneItem.pickerSend = datePicker
   doneItem.toolBarForm = toolbar
   doneItem.index = indexPath.row
   doneItem.tableData = tableView

   // ツールバーの表示        
   toolbar.setItems([spacelItem, doneItem], animated: true)
   view.addSubview(toolbar)
}

// 完了ボタン押下
@objc func doneButton(_ sender:DoneButton) {

   let dateFormatter = DateFormatter()
   dateFormatter.locale = Locale(identifier: "ja_JP")
   dateFormatter.dateStyle = .long
   dateFormatter.timeStyle = .medium
   dateFormatter.dateFormat = "yyyy年M月d日 H時mm分ss秒"

   //ピッカーから値を取り出して、String型へ変更        
   let pickerDate = sender.pickerSend.date
   let strPickerDate = "\(dateFormatter.string(from:pickerDate))"

   //タップされたセルの行数とtable viewを呼び出して、更新された値でtable再表示
   let sendIndexPath = sender.index
   let tableView = sender.tableData        
   tableView.reloadData()

  //保存用変数を更新
   thingsList[pathNumber!][sendIndexPath + 1] = strPickerDate

   //サブビュー2つを消す
   let datePicker = sender.pickerSend
   datePicker.removeFromSuperview()
   let toolbar = sender.toolBarForm
   toolbar.removeFromSuperview()
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/09 09:29 編集

    これは回答ではなく質問に追記すべきだと思いますが、それはさておき‥

    Pickerから値を取るのは完了ボタンを押した後ですよね?
    であれば、DoneButtonにPickerを渡して、ボタンを押した後で値を取得(& remove)して下さい。
    ツールバーも渡してやればremove時に楽でしょう。(viewWithTag()使う必要なし)

    キャンセル

  • 2018/07/09 23:00 編集

    ありがとうございました。実現することができました。
    removeの方も修正できました。

    作法も慣れずに失礼いたしました。
    こうしてしまうと、折角答えていただいたのにベストアンサーがつけられず、自己解決になってしまうのですね。。。

    キャンセル

  • 2018/07/10 08:55

    この回答のコードを修正して、自己解決にすれば問題ないですよ。

    キャンセル

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

  • ただいまの回答率 90.32%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • Swift

    7703questions

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