まだ非同期周りの処理は学び中なので間違ったコード or 長ったらしいコードを書いている可能性があります、その点はご了承ください、優しい方であれば下記コメント欄でアドバイスください。
Storyboard
◎添付画像ではxibファイルで開発していますが、真似して作る際は普通にStoryboardで実装してOKです。
コード記述
import UIKit
class GitTestViewController: UIViewController {
@IBOutlet private weak var statusLabel: UILabel!
@IBOutlet private weak var imageView: UIImageView!
@IBOutlet private weak var loadingView: UIActivityIndicatorView!
@IBOutlet private weak var getImageButton: UIButton!
//取得したい画像のURL
private let url = URL(string: "<#表示させたい画像のURL#>")
private let noImage = UIImage(named: "<#Assetsに入れた画像名#>") //画像取得に失敗した時の代用画像
override func viewDidLoad() {
super.viewDidLoad()
setupView()
}
private func setupView() {
statusLabel.text = "初期画像だよ"
imageView.image = UIImage(named: "<#Assetsに入れた画像名#>") //初期表示画像
getImageButton.layer.cornerRadius = 18.0 //ボタンを角丸にする
loadingView.isHidden = true //ActivityIndicatorを非表示にしておく
}
@IBAction func getImageAction(_ sender: Any) {
animationDuringDownloading() //スピナーを回す & テキストを変更
guard let imageURL = url else { return }
DispatchQueue.global().async { [weak self] in //非同期処理
do {
let imageData: Data = try Data(contentsOf: imageURL) //URLをData型に変換
DispatchQueue.main.async { [weak self] in
self?.imageView.image = UIImage(data: imageData) //取得したURLの画像を表示する
self?.statusLabel.text = "画像取得成功"
self?.stopAnimation() //スピナーを止める & 非表示にする
}
print("Display Cat Image Successful")
} catch { //画像取得失敗時
DispatchQueue.main.async { [weak self] in
self?.imageView.image = self?.noImage //代用画像を表示する
self?.statusLabel.text = "画像取得に失敗しました"
self?.stopAnimation()
}
print("Display Cat Image failed")
}
}
}
private func animationDuringDownloading() {
statusLabel.text = "画像取得中..."
imageView.image = nil
loadingView.isHidden = false
loadingView.startAnimating()
}
private func stopAnimation() {
loadingView.stopAnimating()
loadingView.isHidden = true
}
}