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

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

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

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

Swift

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

Q&A

解決済

1回答

747閲覧

AssetCatalogに格納した画像のpathをinfo.plistに格納し、UITableViewで表示したい。

Risney

総合スコア148

Xcode

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

Swift

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

0グッド

0クリップ

投稿2020/08/15 10:34

編集2020/08/15 10:40

前提・実現したいこと

・AssetCatalogに格納した画像のpathをinfo.plistに格納し、UITableViewで表示したい。
※もしこの方法が非効率であり、効率的な方法があるのであればご教授いただければ幸いです。

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

・AssetCatalogに格納した画像をUITableViewに表示することはできたが、
現在のコードでは直接呼び出しているので、全て同じ画像(MickeyIcon)になっている。

イメージ説明
※名前と画像を一致させたい

該当のソースコード

swift

1import UIKit 2 3class ViewController: UIViewController ,UITableViewDelegate, UITableViewDataSource{ 4 var _items:NSArray = [] 5 6 override func viewDidLoad() { 7 super.viewDidLoad() 8 9 // Plistファイルパス 10 let path = Bundle.main.path(forResource: "DisneyCharacterList", ofType:"plist") 11 _items = NSArray(contentsOfFile:path!)! 12 //println(_items); 13 } 14 15 // 設定 16 func numberOfSectionsInTableView(tableView: UITableView) -> Int { 17 return 1 18 } 19 20 // 設定(行数) 21 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) 22 -> Int { 23 return _items.count 24 } 25 26 // 設定(セル) 27 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 28 29 let cell = tableView.dequeueReusableCell(withIdentifier: "DisneyCell", for: indexPath as IndexPath) 30 let dic = _items.object(at: indexPath.row) as! NSDictionary 31 cell.textLabel!.text = dic.value(forKey: "Name") as? String 32 cell.imageView?.image = UIImage(named: "0.MickeyIcon") 33 34 return cell 35 } 36 //セルタップ時にセルの内容を取得する 37 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 38 let cell = tableView.dequeueReusableCell(withIdentifier: "DisneyCell", for: indexPath as IndexPath) 39 let dic = _items.object(at: indexPath.row) as! NSDictionary 40 cell.textLabel!.text = dic.value(forKey: "Name") as? String 41 print(cell.textLabel!.text as Any) 42 } 43}

AssetCatalog
イメージ説明

info.Plist
イメージ説明
このPlistに「image」みたいなカラムを追加して、
AssetCataloogの画像のpathを書くイメージ

info.Plist

1 2<?xml version="1.0" encoding="UTF-8"?> 3<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 4<plist version="1.0"> 5<array> 6 <dict> 7 <key>Name</key> 8 <string>Mickey</string> 9 </dict> 10 <dict> 11 <key>Name</key> 12 <string>Minnie</string> 13 </dict> 14 <dict> 15 <key>Name</key> 16 <string>Donald</string> 17 </dict> 18 <dict> 19 <key>Name</key> 20 <string>Goofy</string> 21 </dict> 22 <dict> 23 <key>Name</key> 24 <string>Pluto</string> 25 </dict> 26</array> 27</plist> 28

試したこと

自分の調べ方が悪いのか、該当する記事がみつからず、
他にできることがないか調べている最中です…

その他

セルタップ時にセルの内容を取得するメソッドの中身ってもっとスマートになりませんかね…

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

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

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

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

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

guest

回答1

0

ベストアンサー

Risneyさんが書かれている対策で、セルに対応した画像を表示することは可能かと思われます。

このPlistに「image」みたいなカラムを追加して、AssetCataloogの画像のpathを書くイメージ

DisneyCharacterList.plist に Name に併せて Imageを定義して、下記のようにImageのvalueに MickeyIcon などのファイル名を追加する。

plist

1<array> 2 <dict> 3 <key>Name</key> 4 <string>Mickey</string> 5 <key>Image</key> 6 <string>MickeyIcon</string> 7 </dict>

次に tableView(_ tableView:, cellForRowAt:) で下記のようにして画像を取得し、 UIImageViewに設定してみてはいかがでしょうか。

swift

1let imageName = dic.value(forKey: "Image") as! String 2cell.imageView?.image = UIImage(named: imageName)

ここからは別の解釈で、表示したいセル数が固定でアイテム数も多くないのであれば、plistを使わないのもひとつの手かもしれません。

swift

1 struct HogeItem { 2 let name: String 3 let imageName: String 4 } 5 6 let _items: [HogeItem] = [ 7 HogeItem(name: "Mickey", imageName: "MickeyIcon"), 8 HogeItem(name: "Donald", imageName: "DonaldIcon") 9 ]

UITableViewのdelegateでは下記のように扱うことが可能です。

swift

1 // 設定 2 func numberOfSectionsInTableView(tableView: UITableView) -> Int { 3 return 1 4 } 5 6 // 設定(行数) 7 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 8 return _items.count 9 } 10 11 // 設定(セル) 12 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 13 14 let item = _items[indexPath.row] 15 16 let cell = tableView.dequeueReusableCell(withIdentifier: "DisneyCell", for: indexPath as IndexPath) 17 cell.textLabel?.text = item.name 18 cell.imageView?.image = UIImage(named: item.imageName) 19 20 return cell 21 } 22 //セルタップ時にセルの内容を取得する 23 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 24 let item = _items[indexPath.row] 25 26 print(item.name) 27 }

追記

セクション名をplistで指定することは可能でしょうか?

可能です。下記のようにplistを定義すれば、セクションごとの名前とデータを持つことができます。

イメージ説明

データの取り出し方が変わりますのでご注意ください。


追記2

セクションごとの名前とデータを持つことができます。
データの取り出し方が変わりますのでご注意ください。

この場合、セルに表示する「Name」と「Image」を取得する際に、「セクション1」の中の「Name」と「Image」…と指定するということですかね。

それで良いと思います!

質問の内容からは大きく離れてしまいますが、もし私が実装するとすれば データの取り出し方には Decodable を使うかと思います。

swift

1 struct HogeItem: Decodable { 2 let name: String 3 let imageName: String 4 } 5 6 struct HogeSection: Decodable { 7 let name: String 8 let items: [HogeItem] 9 } 10 11 var _items: [HogeSection] = []

データ表示は下記のように書くことができます。

swift

1 override func viewDidLoad() { 2 super.viewDidLoad() 3 4 // Plistファイルパス 5 if let path = Bundle.main.path(forResource: "hoge", ofType:"plist" ) { 6 let data = try! Data(contentsOf: URL(fileURLWithPath: path)) 7 _items = try! PropertyListDecoder().decode([HogeSection].self, from: data) 8 } 9 //...省略 10 } 11 12 // 設定 13 func numberOfSectionsInTableView(tableView: UITableView) -> Int { 14 return _items.count 15 } 16 17 // 設定(行数) 18 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 19 return _items[section].items.count 20 } 21 22 // 設定(セクションタイトル) 23 func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 24 return _items[section].name 25 } 26 27 // 設定(セル) 28 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 29 let item = _items[indexPath.section].items[indexPath.row] 30 31 let cell = tableView.dequeueReusableCell(withIdentifier: "DisneyCell", for: indexPath as IndexPath) 32 cell.textLabel?.text = item.name 33 cell.imageView?.image = UIImage(named: item.imageName) 34 return cell 35 } 36 37 //セルタップ時にセルの内容を取得する 38 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 39 let item = _items[indexPath.section].items[indexPath.row] 40 41 print(item.name) 42 }

投稿2020/08/16 03:27

編集2020/08/16 12:08
ch3cooh

総合スコア287

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

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

Risney

2020/08/16 05:24 編集

おかげさまで解決しました!! しかもわざわざplist使わない方法までご教授いただきありがとうございます。 ちなみに同じ様な方法で、 セクション名をplistで指定することは可能でしょうか? 例えば、 今回作ったキャラクターの「Image」「Name」が入っているArrayとは別に 「Section」というカラムがあるArrayを作成し、セクションを取得するイメージです。 その場合、 以下のサイトの様にカラムが一つなので「Dictionary」を挟む必要はないと思っています。 ※しかし以下のサイト通りだとカ値を取得できませんでした… https://qiita.com/color_box/items/b82c2cfbed745e1ce031
Risney

2020/08/16 09:44

追記ありがとうございます。 >セクションごとの名前とデータを持つことができます。 >データの取り出し方が変わりますのでご注意ください。 この場合、セルに表示する「Name」と「Image」を取得する際に、 「セクション1」の中の「Name」と「Image」 …と指定するということですかね。 質問が多くなってしまいそうなので、 また別途質問を立てようと思います。
Risney

2020/08/17 06:18

追記ありがとうございます。 Githubのコードも確認してみます。 またセクションの件については、 もう一つのほうの質問欄にて返答させてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問