##やること
前回の続き
APIをTableviewに反映
##tableviewのデリゲートのメソットの設定
この前作ったtableviewのデリゲートのメソットを少し変更します。
その前にprivate var recips = [ResultList]()
をprivate let cellId = "cellId"
の下でもいいので追加
###tableviewのデリゲートのメソットの変更
①cellの高さを変えるコードを追加
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 80
}
②numberOfRowsInSectionのところを変更
return 10のところを下記に変更
if (recips.count == 0) {
return recips.count
} else {
return recips[0].result.count
}
}
③cellForRowAtのところを変更
cell.backgroundColor = .blue
コードを消してあげる。
let cell = ...
のコードの後ろにas! RTableViewCell
追加
下にcell.recip = self.recips[0].result[indexPath.row]
のコードを追加
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! RTableViewCell
cell.recip = self.recips[0].result[indexPath.row]
return cell
}
##recipsにresultList情報を入れてあげる
getRApiメソッドのdo-catch文の中に、resultListが作成された際にrecipsにresultList情報を入れるコードを追加
self.recips = [resultList]
##メインスレットで必要なコードを追加
DispatchQueue.main.async {
self.tableView.reloadData()
}
うまく表示されました!!達成感ー!!!
##課題
・Codableを使い方をいまいちうまく使いこなせてない感じから色々なAPIをCodableを使ってJson変換させてみる。
ここまで読んでくださって有り難うございます。
勉強記録として残しておきます。
初心者なので、これがベストなコードかわからないのですが、もっといい方法があればご教示頂ける有り難いです!!
##今までのコード
struct ResultList: Codable {
let result: [User]
struct User: Codable {
let foodImageUrl :String
let recipeTitle :String
}
}
class ViewController: UIViewController {
private let cellId = "cellId"
private var recips = [ResultList]()
//tableviewを作っていく
let tableView: UITableView = {
let tv = UITableView()
return tv
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(tableView)
tableView.frame.size = view.frame.size
tableView.delegate = self
tableView.dataSource = self
tableView.register(RTableViewCell.self, forCellReuseIdentifier: cellId)
navigationItem.title = "おすすめレシピ"
getRApi()
}
private func getRApi(){
guard let url = URL(string: "楽天API") else {return}
let task = URLSession.shared.dataTask(with: url) { (data, response, err)in
if let err = err {
print("情報の取得に失敗しました。:", err)
return
}
if let data = data{
do{
let resultList = try JSONDecoder().decode(ResultList.self, from: data)
self.recips = [resultList]
DispatchQueue.main.async {
self.tableView.reloadData()
}
print("json: ", resultList)
}catch(let err){
print("情報の取得に失敗しました。:", err)
}
}
}
task.resume()
}
}
extension ViewController: UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 80
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if (recips.count == 0) {
return recips.count
} else {
return recips[0].result.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! RTableViewCell
cell.recip = self.recips[0].result[indexPath.row]
return cell
}
}
class RTableViewCell: UITableViewCell {
let bodyTextLabel: UILabel = {
let label = UILabel()
label.text = "something in here"
label.font = .systemFont(ofSize: 15)
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
let userImageView: UIImageView = {
let iv = UIImageView()
iv.contentMode = .scaleAspectFill
iv.translatesAutoresizingMaskIntoConstraints = false
iv.clipsToBounds = true
return iv
}()
var recip: ResultList.User? {
didSet {
bodyTextLabel.text = recip?.recipeTitle
let url = URL(string: recip?.foodImageUrl ?? "")
do {
let data = try Data(contentsOf: url!)
let image = UIImage(data: data)
userImageView.image = image
}catch let err {
print("Error : \(err.localizedDescription)")
}
}
}
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
addSubview(userImageView)
addSubview(bodyTextLabel)
[
userImageView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 10),
userImageView.centerYAnchor.constraint(equalTo: centerYAnchor),
userImageView.widthAnchor.constraint(equalToConstant: 50),
userImageView.heightAnchor.constraint(equalToConstant: 50),
bodyTextLabel.leadingAnchor.constraint(equalTo: userImageView.trailingAnchor, constant: 20),
bodyTextLabel.centerYAnchor.constraint(equalTo: centerYAnchor),
].forEach{ $0.isActive = true }
userImageView.layer.cornerRadius = 50 / 2
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}