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

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

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

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

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

Swift

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

Q&A

解決済

1回答

2568閲覧

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

Kaguya_4869

総合スコア117

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

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

Swift

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

0グッド

0クリップ

投稿2020/03/30 08:14

編集2020/03/31 02:37

#質問したいこと
先ほどこちらのページにて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") }

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

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

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

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

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

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

TsukubaDepot

2020/03/30 11:16

「そのtextViewで変えた色を違う画面のlabelにも反映させたいのですが、どうすればできるでしょうか?」というのは、labelの色をtextViewで変更した色に変更したい(labelのテキストはtextViewとは無関係)ということでしょうか。 それとも、textView でテキストをドラッグし、反転させ色を変えた部分のテキストをコピーして、属性も反映させたいということでしょうか。 前者であれば、label.textColor = UIColor.色名 で変更できますが、質問者さんはどんな感じのコードで試されたのでしょうか。
Kaguya_4869

2020/03/30 11:54

上の写真でいきますと、「My birthday」という文字があり、そのうちMyが青色でbirthdayが赤色になっているのですが、ラベルは黒い文字のまま反映されてしまっています。 ラベルの文字もMy を青色にbirthdayを赤色にするにはどうすればいいでしょうか?
TsukubaDepot

2020/03/30 12:00

つまり、textView に表示させた文字列の属性をそのままlabelにも反映させたい、ということでしょうか。 あと、作られたコードも見せてもらえませんでしょうか。
Kaguya_4869

2020/03/30 12:12

TsukubaDepotさんがおっしゃっている通り、textView に表示させた文字列の属性をそのままlabelにも反映させたいです。 また、UserDefaults.standard.set(typingColor, forKey: "blue")というようにしてみてできるかなと思ったのですが、 'Attempt to insert non-property list object UIExtendedSRGBColorSpace 0 0 1 1 for key blue' というエラーが出てしまい、どうすればいいか悩んでおります。
Kaguya_4869

2020/03/30 12:13

この選択した時に色を変える処理は質問のところにあるのだけです。
TsukubaDepot

2020/03/30 12:26

UserDefaults が出てくる、というのは遷移先の画面にあるラベルに反映させたい、ということでしょうか。 エラーメッセージをキーワード("Attempt to insert non-property list object"だけで)検索すると、このような例がでてきますので、一度型変換をおこなってみてはいかがでしょうか。 https://qiita.com/NatsumiShimamoto/items/1853007bdf8bdb2bfcf7
Kaguya_4869

2020/03/31 01:22

型変換のコードを書いてみたのですが、文法に誤りがあるらしく、 NSData as Data = try! NSKeyedArchiver.archivedData(withRootObject: typingColor, requiringSecureCoding: true) と書いた時に、 Cannot assign to immutable expression of type 'Data' というエラーが出てきてしまいます。 このエラーを調べてみたのですが、どのように直せばいいのか分からず困っております。 このエラーをどうしたら直せるかとそもそもこの方法でいいのかというところを教えていただけませんでしょうか?
TsukubaDepot

2020/03/31 01:34

昨日は > また、UserDefaults.standard.set(typingColor, forKey: "blue")というようにしてみてできるかなと思ったのですが、 > 'Attempt to insert non-property list object UIExtendedSRGBColorSpace 0 0 1 1 for key blue' というエラーが出てしまい、どうすればいいか悩んでおります。 というお話でしたが、今日は > NSData as Data = try! NSKeyedArchiver.archivedData(withRootObject: typingColor, requiringSecureCoding: true) > と書いた時に、 > Cannot assign to immutable expression of type 'Data' > というエラーが出てきてしまいます。 と異なった話になってしまっています。 断片的な情報では何も提案できませんので、保存の前後含めてコードを提示してもらえないでしょうか。 > このエラーをどうしたら直せるかとそもそもこの方法でいいのかというところを教えていただけませんでしょうか? UserDefault やそれに類似した方法で一時的に記録し、それを遷移先のクラスで読み込むのもひとつですが、データの型などを気にしなくて済むのは、遷移先のクラスのプロパティ(変数)に直接書き込むことだと思います。
Kaguya_4869

2020/03/31 02: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 03:57

もろもろの状況が把握できました。 UserDefaultは何でもかんでも保存できるわけではなく、保存できる型は限られいます。 ある特定の型以外はシリアライズに関連する処理を施した上で保存する必要がありますが、今回の処理を考えるとその処理もやや大袈裟な気がします。 参考: https://teratail.com/questions/124978 行いたいことは、遷移した先の画面に置かれているテキストの色を変えたい、ということですよね? そうであれば、遷移する処理を行う際に遷移先のテキストの色を変えるのが楽ですし、今後ほかの処理でも応用が効くと思いますが、いかがでしょうか。 それであれば簡単なサンプルはかけますので(というか、もう書いています)、その旨を教えてください。
Kaguya_4869

2020/03/31 04:14

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

回答1

0

ベストアンサー

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

  • 遷移元

Swift

1 // ボタンが押された時の処理 2 @IBAction func copyLabelButton(_ sender: Any) { 3 // Segue を実行する 4 performSegue(withIdentifier: "detail", sender: nil) 5 } 6 7 // セグエを実行する時の処理 8 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 9 if let vc = segue.destination as? DetailViewViewController { 10 // 遷移先のクラスにある変数に、属性が付いたテキストを代入する 11 vc.attributedText = eventText.attributedText 12 } 13 } 14
  • 遷移先

Swift

1class DetailViewController: UIViewController { 2 3 @IBOutlet weak var label: UILabel! 4 // ラベルの属性を一時保存する変数 5 var attributedText: NSAttributedString! 6 7 override func viewDidLoad() { 8 super.viewDidLoad() 9 10 // ビューが表示されてから、ラベルの属性を変更する。 11 label.attributedText = attributedText 12 } 13}

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

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

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


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

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

swift

1import UIKit 2 3class SomeClass: NSObject, NSCoding { 4 5 let color: UIColor 6 7 init(color: UIColor) { 8 self.color = color 9 } 10 11 func encode(with aCoder: NSCoder) { 12 aCoder.encode(self.color, forKey: "colorkey") 13 } 14 15 required init?(coder aDecoder: NSCoder) { 16 self.color = aDecoder.decodeObject(forKey: "colorkey") as! UIColor 17 } 18} 19 20let saveColor = SomeClass(color: UIColor.red) 21print("save color: ", saveColor.color) 22 23// 保存 24let data = try! NSKeyedArchiver.archivedData(withRootObject: saveColor, requiringSecureCoding: false) 25UserDefaults.standard.set(data, forKey: "saveColor") 26//以下の処理は非推奨になったので必要ない 27//UserDefaults.standard.synchronize() 28 29// 取得 30if let data = UserDefaults.standard.object(forKey: "saveColor") as? Data { 31 if let restoredColor = try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? SomeClass { 32 print("loaded color :", restoredColor.color) 33 } 34}

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

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

投稿2020/03/31 04:24

編集2020/04/06 00:26
TsukubaDepot

総合スコア5086

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

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

Kaguya_4869

2020/03/31 04:44

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

2020/03/31 05:18

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

2020/03/31 08:24

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

2020/03/31 08:27

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問