はじめに
いやあ〜クリスマスですね、思い出に残っているプレゼントはありますか?
僕は小学生の時にサンタさんにもらったガリューンです。(わかる人いますかねっ笑)
電脳冒険記ウェブダイバーってアニメのキャラなんです、もう内容は一つも覚えてないですが。。。
このおもちゃ、テレビに繋いでゲームができるんですよ!
あの当時、おもちゃがテレビと連動するなんて画期的すぎて、Oka少年は夢中でした。
やっぱりプレゼントっていいですね、クリスマスに限らずいつでもプレゼント募集してますので、皆さんお待ちしております!
はい、では前回に引き続き、API-FOOTBALLを使っていこうと思います。
今日のGOAL
完全に自己満で色んな選手のプレーデータを見たいので、
今日は、前回作成した選手検索画面から詳細画面に遷移して色々表示していこうと思います。
GOALまでの大雑把な道筋
①前回の検索画面にPickerViewを実装
②詳細画面へ検索結果の値を渡して画面遷移
③詳細画面にScrollViewを実装
④詳細画面でAPI通信し表示
①前回の検索画面にPickerViewを実装
前回の検索画面はSeasonやリーグ名をベタ打ちしてました。
なので、まず選択肢を配列で用意してそれをPickerViewで表示させます。
// 前回作成したTextField=>これにPickerViewを実装
@IBOutlet weak var seasonTextField: UITextField!
@IBOutlet weak var leagueTextField: UITextField!
// 各TextField用にUIPickerViewをインスタンス化
var seasonPickerView = UIPickerView()
var leaguePickerView = UIPickerView()
// SeasonとLeagueの選択肢を配列で作成
var seasonArray = ["1990", "1991", "1992", "1993", "1994", "1995", "1996", "1997", "1998", "1999", "2000", "2001", "2002", "2003", "2004", "2005", "2006", "2007", "2008", "2009", "2010", "2011", "2012","2013", "2014", "2015", "2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024"]
var leagueArray = ["Liga", "League1", "Premier", "SerieA", "Eredivisie"]
override func viewDidLoad() {
super.viewDidLoad()
// configurePickerView()を呼び出し
configurePickerView()
}
func configurePickerView() {
// UIPickerViewの各インスタンスのデリゲート先にself(=このViewController自身)を指定
seasonPickerView.delegate = self
seasonPickerView.dataSource = self
leaguePickerView.delegate = self
leaguePickerView.dataSource = self
// TextFieldのinputView(キーボードをカスタマイズ)にUIPickerViewを設定
seasonTextField.inputView = seasonPickerView
leagueTextField.inputView = leaguePickerView
}
// ViewControllerにUIPickerViewプロトコルを準拠させる
extension ViewController: UIPickerViewDelegate {
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
// PickerViewで選択時の挙動を設定。(今回はtextFieldに格納させる処理)
if pickerView == seasonPickerView {
seasonTextField.text = seasonArray[row]
} else {
leagueTextField.text = leagueArray[row]
}
}
}
// ViewControllerにUIPickerViewプロトコルを準拠させる
extension ViewController: UIPickerViewDataSource {
// PickerViewに表示する項目数を設定
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
// PickerViewの選択肢数を設定
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
// PickerViewがSeasonか、Leagueかで分岐
if pickerView == seasonPickerView {
return seasonArray.count
} else {
return leagueArray.count
}
}
// PickerViewに表示する選択肢の中身を設定
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if pickerView == seasonPickerView {
return seasonArray[row]
} else {
return leagueArray[row]
}
}
}
②詳細画面へ検索結果の値を渡して画面遷移
詳細画面に画面遷移をしたいのですが、
詳細画面では、playerIDとSeasonをパラメータにしてAPIリクエストを行いたいです。
なので、その2つの値も画面遷移と一緒に渡したいです。
ViewControllerにUIButtonを設置してIBActionを設定します。
まず、詳細画面のViewControllerをStoryBoardで作成します。
前画面から渡ってきた値を受け取る用の変数を用意しておきます。
class DetailViewController: UIViewController {
var playerID: String = ""
var season: String = ""
}
遷移元のViewControllerで値を渡して遷移する処理を実装。
@IBAction func moveToDetailVC(_ sender: Any) {
// storyBoardをインスタンス化
let storboard = self.storyboard!
// 遷移先のViewControllerをインスタンス化(今回はDetailViewControllerを作成)
// withIdentifierに遷移先のViewControllerのstoryBoardIDを設定
let detailVC = storboard.instantiateViewController(withIdentifier: "detailVC") as! DetailViewController
// 先ほど用意したDetailViewControllerの変数に値を格納
detailVC.playerID = self.playerID
detailVC.season = self.seasonText
// モーダル遷移(.fullScreenで全画面表示)
detailVC.modalPresentationStyle = .fullScreen
self.present(detailVC, animated: true, completion: nil)
}
これで値を渡せます!!
③詳細画面にScrollViewを実装
今回は、表示させたい項目が多くて画面に収まりきらないのでScrollViewを使用して、上下スクロールできるようにします。
かなり端折りますが、簡単に言うと下記の手順で設定。
1.ViewControllerにScrollViewを追加
(SafeAreaに対してConstraintsを上下左右0)
2.ScrollViewの下にUIViewを追加
(ScrollView配下のContentLayoutGuideに対してConstraintsを上下左右0、FrameLayoutGuideに対してEqualWidthを設定)
3.UIViewの高さを表示したい内容が収まる高さに設定
④詳細画面でAPI通信し表示
前の画面から受け取ったplayerIDとSeasonをパラメータに渡して、選手のデータを取得します。
API通信の処理は前回と全く同じなので、前回分を見ていただけたらと思います。
import UIKit
import Foundation
import SwiftyJSON
import AlamofireImage
class DetailViewController: UIViewController {
// 表示させたい項目をIBOutlet接続。
@IBOutlet weak var playerImage: UIImageView!
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var teamLabel: UILabel!
@IBOutlet weak var seasonLabel: UILabel!
@IBOutlet weak var goalLabel: UILabel!
@IBOutlet weak var shootsLabel: UILabel!
@IBOutlet weak var onTargetLabel: UILabel!
@IBOutlet weak var assistsLabel: UILabel!
@IBOutlet weak var totalPassesLabel: UILabel!
@IBOutlet weak var keyPassLabel: UILabel!
@IBOutlet weak var passAccuracyLabel: UILabel!
@IBOutlet weak var totalTacklesLabel: UILabel!
@IBOutlet weak var interceptionLabel: UILabel!
@IBOutlet weak var dribblesLabel: UILabel!
@IBOutlet weak var dribblesSuccessLabel: UILabel!
@IBOutlet weak var playedGamesLabel: UILabel!
@IBOutlet weak var playedMinutesLabel: UILabel!
@IBOutlet weak var duelsLabel: UILabel!
@IBOutlet weak var duelsWonLabel: UILabel!
// 前画面から値を受け取る用の変数
var playerID: String = ""
var season: String = ""
override func viewDidLoad() {
super.viewDidLoad()
loadData()
}
func loadData() {
let headers = [
"x-rapidapi-host": "api-football-v1.p.rapidapi.com",
"x-rapidapi-key": "71d5d7e247msh2e0b3ec472fd452p1b9c2fjsnacb7856b6d30"
]
let request = NSMutableURLRequest(url: NSURL(string: "https://api-football-v1.p.rapidapi.com/v3/players?id=\(self.playerID)&season=\(self.season)")! as URL,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if let json = try? JSON(data: data!) {
print("datadata", json["response"])
let name = json["response"][0]["player"]["name"]
let team = json["response"][0]["statistics"][0]["team"]["name"]
let season = json["response"][0]["statistics"][0]["league"]["season"]
let playedGames = json["response"][0]["statistics"][0]["games"]["appearences"]
let playedMinutes = json["response"][0]["statistics"][0]["games"]["minutes"]
let goal = json["response"][0]["statistics"][0]["goals"]["total"]
let shoots = json["response"][0]["statistics"][0]["shots"]["total"]
let onTarget = json["response"][0]["statistics"][0]["shots"]["on"]
let assists = json["response"][0]["statistics"][0]["goals"]["assists"]
let passes = json["response"][0]["statistics"][0]["passes"]["total"]
let keyPasses = json["response"][0]["statistics"][0]["passes"]["key"]
let passesAccuracy = json["response"][0]["statistics"][0]["passes"]["accuracy"]
let totalTackles = json["response"][0]["statistics"][0]["tackles"]["total"]
let interceptions = json["response"][0]["statistics"][0]["tackles"]["interceptions"]
let dribbles = json["response"][0]["statistics"][0]["dribbles"]["attempts"]
let dribblesSuccess = json["response"][0]["statistics"][0]["dribbles"]["success"]
let duels = json["response"][0]["statistics"][0]["duels"]["total"]
let duelsWon = json["response"][0]["statistics"][0]["duels"]["won"]
let imageURL = json["response"][0]["player"]["photo"]
let url = NSURL(string: imageURL.stringValue)
DispatchQueue.main.async() { () -> Void in
self.nameLabel.text = name.stringValue
self.teamLabel.text = team.stringValue
self.seasonLabel.text = season.stringValue
self.playedGamesLabel.text = playedGames.stringValue
self.playedMinutesLabel.text = playedMinutes.stringValue
self.goalLabel.text = goal.stringValue
self.shootsLabel.text = shoots.stringValue
self.onTargetLabel.text = onTarget.stringValue
self.assistsLabel.text = assists.stringValue
self.totalPassesLabel.text = passes.stringValue
self.keyPassLabel.text = keyPasses.stringValue
self.passAccuracyLabel.text = passesAccuracy.stringValue
self.totalTacklesLabel.text = totalTackles.stringValue
self.interceptionLabel.text = interceptions.stringValue
self.dribblesLabel.text = dribbles.stringValue
self.dribblesSuccessLabel.text = dribblesSuccess.stringValue
self.duelsLabel.text = duels.stringValue
self.duelsWonLabel.text = duelsWon.stringValue
self.playerImage.af.setImage(withURL: url! as URL)
}
}
})
dataTask.resume()
}
はい、完成で〜〜〜す! 画質悪っ笑
後半のバテた感じが顕著ですが、ご愛嬌ということで!
それではみなさん、良いお年を!!!