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

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

ただいまの
回答率

87.59%

[swift 5]textViewで変えた色を違う画面のlabelに反映させたい

解決済

回答 1

投稿 編集

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

score 100

質問したいこと

先ほどこちらのページにてtextViewで選択した部分の色を変える方法を教えてもらいました。
次に、そのtextViewで変えた色を違う画面のlabelにも反映させたいのですが、どうすればできるでしょうか?
textViewで色を変えたところ 
↑textViewで色を変えたところ
違う画面に行ったところでのlabelに表示されている文字
↑違う画面にいったところでのlabelに表示されている文字

コード

    @IBAction func redColor(_ sender: UIButton) {
        typingColor = UIColor.red
        let range = eventText.selectedRange
        let string = NSMutableAttributedString(attributedString: eventText.attributedText)
        let attributes = [NSAttributedString.Key.foregroundColor: UIColor.red]
        string.addAttributes(attributes, range: eventText.selectedRange)
        eventText.attributedText = string
        eventText.selectedRange = range
        NSData as Data = try! NSKeyedArchiver.archivedData(withRootObject: typingColor, requiringSecureCoding: true)
        UserDefaults.standard.set(typingColor, forKey: "red")
    }
    @IBAction func blueColor(_ sender: UIButton) {
        typingColor = UIColor.blue
        let range = eventText.selectedRange
        let string = NSMutableAttributedString(attributedString: eventText.attributedText)
        let attributes = [NSAttributedString.Key.foregroundColor: UIColor.blue]
        string.addAttributes(attributes, range: eventText.selectedRange)
        eventText.attributedText = string
        eventText.selectedRange = range
        NSData as Data = try! NSKeyedArchiver.archivedData(withRootObject: typingColor, requiringSecureCoding: true)
        UserDefaults.standard.set(typingColor, forKey: "blue")
    }

どこに何をどのように書けばいいのかわからず、困っております。
ご教授よろしくお願いします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • Kaguya_4869

    2020/03/31 11:47

    昨日は、
    UserDefaults.standard.set(typingColor, forKey: "blue")
    というようにして見れば、違う画面でもその部分の色が反映されるかなと思ったのですが、
    Attempt to insert non-property list object UIExtendedSRGBColorSpace 0 0 1 1 for key blue
    というエラーが出てきてしまいました。そこで、アドバイスを元に型変換(nsdata -> data)をしてみたのですが、
    Cannot assign to immutable expression of type 'Data'
    というようなエラーになってしまっています。
    最初はビルドはできたのですが、現在は上記のようなエラーが出てきてしまっていてビルドができない状況です。保存をしているのは質問のところに書いてあるものだけです。

    キャンセル

  • TsukubaDepot

    2020/03/31 12:57

    もろもろの状況が把握できました。

    UserDefaultは何でもかんでも保存できるわけではなく、保存できる型は限られいます。
    ある特定の型以外はシリアライズに関連する処理を施した上で保存する必要がありますが、今回の処理を考えるとその処理もやや大袈裟な気がします。
    参考: https://teratail.com/questions/124978

    行いたいことは、遷移した先の画面に置かれているテキストの色を変えたい、ということですよね?
    そうであれば、遷移する処理を行う際に遷移先のテキストの色を変えるのが楽ですし、今後ほかの処理でも応用が効くと思いますが、いかがでしょうか。

    それであれば簡単なサンプルはかけますので(というか、もう書いています)、その旨を教えてください。

    キャンセル

  • Kaguya_4869

    2020/03/31 13:14

    ご迷惑をおかけして申し訳ありません。
    サンプルも書いてくださっているということで、本当にとても助かります。
    行いたいことは、TsukubaDepotさんが仰っている通り、遷移した先の画面に置かれているテキストの色を変えたいということです。
    ありがとうございます。

    キャンセル

回答 1

checkベストアンサー

0

遷移先のラベルの属性(attributedText)を変更するという例です。
Segueなどについては Interface Builder で設定する必要もあるので、必要に応じて調整してみてください。

  • 遷移元
    // ボタンが押された時の処理
    @IBAction func copyLabelButton(_ sender: Any) {
        // Segue を実行する
        performSegue(withIdentifier: "detail", sender: nil)
    }

    // セグエを実行する時の処理
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let vc = segue.destination as? DetailViewViewController {
            // 遷移先のクラスにある変数に、属性が付いたテキストを代入する
            vc.attributedText = eventText.attributedText
        }
    }
  • 遷移先
class DetailViewController: UIViewController {

    @IBOutlet weak var label: UILabel!
    // ラベルの属性を一時保存する変数
    var attributedText: NSAttributedString!

    override func viewDidLoad() {
        super.viewDidLoad()

        // ビューが表示されてから、ラベルの属性を変更する。
        label.attributedText = attributedText
    }
}


コメントでも触れた通り、遷移先のラベルのattributedTextプロパティに直接書き込めれば良いのですが、prepare(for:sender:)の段階ではまだビューが生成されていないため書き込めません。

なので、遷移先(のクラス)にある一時的な変数にとりあえずattributedTextを保存し、ビューの表示が終了してから改めて再代入するようにしています。

やりたいと思っていることは、おそらく属性付きのテキスト全てをコピーする処理だとおもいますので、これでいいかと思います。


UserDefault で保存する方法もやってみました。
iOS12 以降いくつか変更があったようで、ネット上の情報だけだと不足している感じでしたが、こんな感じでで保存できると思います。

要点をシンプルにするために、Playground で実行できるようにしています。
【2020.4.6: synchronize()は非推奨となっていたので修正】

import UIKit

class SomeClass: NSObject, NSCoding {

    let color: UIColor

    init(color: UIColor) {
        self.color = color
    }

    func encode(with aCoder: NSCoder) {
        aCoder.encode(self.color, forKey: "colorkey")
    }

    required init?(coder aDecoder: NSCoder) {
        self.color = aDecoder.decodeObject(forKey: "colorkey") as! UIColor
    }
}

let saveColor = SomeClass(color: UIColor.red)
print("save color: ", saveColor.color)

// 保存
let data = try! NSKeyedArchiver.archivedData(withRootObject: saveColor, requiringSecureCoding: false)
UserDefaults.standard.set(data, forKey: "saveColor")
//以下の処理は非推奨になったので必要ない
//UserDefaults.standard.synchronize()

// 取得
if let data = UserDefaults.standard.object(forKey: "saveColor") as? Data {
    if let restoredColor = try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? SomeClass {
        print("loaded color :", restoredColor.color)
    }
}


こんな感じで、NSObjectを継承し、NSCodingに準拠したクラスをひとつ作り、その中に色情報を保存し、それをシリアライズして保存したりすれば良さそうです。

ただ、色情報一つだけのためにこれだけの処理を書くのも手間なので、色情報を永続的に保存したいということでなければ、やはり遷移先のプロパティに直接書き込んだ方がよさそうに思います。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/03/31 13:44

    親切に対応してくださり、本当にありがとうございます。
    やりたいことを実現することができました!
    本当にありがとうございます。

    キャンセル

  • 2020/03/31 14:18

    一応、UserDefaultを使った方法も追記しましたので参考にしてください。

    キャンセル

  • 2020/03/31 17:24

    保存の方も追記してくださりありがとうございます。
    本当に感謝です!

    キャンセル

  • 2020/03/31 17:27

    最初の答えは当初の質問に対する直接的な回答ではなかったですし、私も中途半端なところがあったので追記しただけですので大丈夫ですよ。

    キャンセル

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

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

関連した質問

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