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

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

ただいまの
回答率

87.49%

[Swift]変更した値をTableviewに反映させたい

解決済

回答 1

投稿

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

score 44

前提・実現したいこと

TODOリストを作成しています。
・画面A(Todo一覧表示)
・画面B(Aをタップした時の詳細)
・画面C(Todo内容作成画面)

・CでTodo内容をTextViewに書き、完了押すとテキストデータをUserDefaultsに入れて画面Aに反映される
・画面Bに遷移した時にAの内容を表示

ここまで出来たのですが、
Bの内容を編集した時にAに反映させることが出来なくて困っています…
Todo内容は画面Cで完了を押した際にUserDefaultsに保存しています。

画面A
イメージ説明
画面Bに遷移時
イメージ説明

画面A

import UIKit

class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource{

    var celltapped:Int = 0
    var tweetArray:[String] = []

    @IBOutlet var tableview: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

    setup()

    }

    override func viewWillAppear(_ animated: Bool) {

        tweetArray = UserDefaults.standard.array(forKey: "tweet") as? [String] ?? []
        tableview.reloadData()
    }

        func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
            if editingStyle == .delete {
                tweetArray.remove(at: indexPath.row)
                UserDefaults.standard.set(tweetArray, forKey: "tweet")
                UserDefaults.standard.synchronize()

                tableview.reloadData()
            }
        }

    private func setup(){

        self.navigationController?.navigationBar.barStyle = .black
        self.navigationController?.navigationBar.tintColor = .white
        self.navigationController?.navigationBar.barTintColor = .systemBlue
        self.navigationController?.navigationBar.titleTextAttributes = [
                .foregroundColor: UIColor.white]
        tableview.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height)
        tableview.delegate = self
        tableview.dataSource = self
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return tweetArray.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: .default, reuseIdentifier: "Cell")
        cell.selectionStyle = .none
        cell.textLabel?.numberOfLines = 3
        cell.textLabel?.text = tweetArray[indexPath.row]
        return cell
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
          celltapped = indexPath.row
          performSegue(withIdentifier: "detail", sender: nil)
        }

    @IBAction func tweet(_ sender: Any) {
        performSegue(withIdentifier: "tweet", sender: nil)

    }
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        if segue.identifier == "detail" {

            let nextVC = segue.destination as! detailViewController
            nextVC.tweetDetail = tweetArray[celltapped]
        }
    }

}

画面B

import UIKit

class detailViewController: UIViewController,UINavigationControllerDelegate {

    var textview = UITextView()
    var tweetDetail:String = ""

    override func viewDidLoad() {
        super.viewDidLoad()

        text()
        navigationController?.delegate = self

        }

    private func text(){

        textview.frame = CGRect(x: 20, y: 110, width: view.frame.width - 40, height: view.frame.height)
        textview.text = tweetDetail
        textview.font = UIFont.systemFont(ofSize: 20)
        self.view.addSubview(textview)
        self.textview.becomeFirstResponder()
    }

}

試したこと

    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
        if viewController is ViewController {

    var textsave: [String] = UserDefaults.standard.array(forKey: "tweet") as? [String] ?? []
    textsave.append(self.textview.text!)
    UserDefaults.standard.set(textsave, forKey: "tweet")
    UserDefaults.standard.synchronize()
        }
    }


上のコードで更新できるかなと思って試してみたのですが、画面Aに新しいセルが追加されるだけでした…

didChangeNotificationで入力値に変更があった場合の処理を書こうともしてみましたが、
UserDefaultsの中身を変更する処理がわからず心折れてしまいました…
お手数おかけしますが何卒よろしくお願い致します……

ツールのバージョン

Xcode : Version 11.0
Swift : Apple Swift version 5.1

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+1

var textsave: [String] = UserDefaults.standard.array(forKey: "tweet") as? [String] ?? []
textsave.append(self.textview.text!)
UserDefaults.standard.set(textsave, forKey: "tweet")
UserDefaults.standard.synchronize()


appendだと配列に追加してしまうことになるので、値を更新したい場合は以下のように書くといいかと思います。

var textsave: [String] = UserDefaults.standard.array(forKey: "tweet") as? [String] ?? []
textsave[celltapped] = self.textview.text!
UserDefaults.standard.set(textsave, forKey: "tweet")
UserDefaults.standard.synchronize()


textsave[celltapped] = self.textview.text! の部分で指定したデータを上書きしています。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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