I have model which contain struct and array . Form Hit struct , I want to access tag property like this tagLabel.text = photoviewModel?.hits.tags
, so that I can display the value of the property into label . For example when I click the first collection view cell , it should return image and label properly but problem is I got the correct image but always return same values for tag into label . The screenshot is added into below..
Here is the model .
import Foundation
struct Photo: Codable {
let total, totalHits: Int
let hits: [Hit]
}
struct Hit: Codable {
let id: Int
let pageURL: String
let type, tags: String
let previewURL: String
let previewWidth, previewHeight: Int
let webformatURL: String
let webformatWidth, webformatHeight: Int
let largeImageURL: String
let imageWidth, imageHeight, imageSize, views: Int
let downloads, collections, likes, comments: Int
let userID: Int
let user: String
let userImageURL: String
enum CodingKeys: String, CodingKey {
case id, pageURL, type, tags, previewURL, previewWidth, previewHeight, webformatURL, webformatWidth, webformatHeight, largeImageURL, imageWidth, imageHeight, imageSize, views, downloads, collections, likes, comments
case userID = "user_id"
case user, userImageURL
}
}
Here is the view Model .
import Foundation
class PhotoViewModel {
private let networkManager: NetworkManagerProtocol
var hits = [Hit]()
private var cache = [String: Data]()
// var net = NetworkManager()
weak var delegate: PhotoViewable?
init(networkManager: NetworkManagerProtocol) {
self.networkManager = networkManager
}
var rows: Int {
return hits.count
}
func fecthPhotoRecord(){
let networkUrl = NetworkURLs.baseURL
networkManager.getModel(Photo.self, from: networkUrl) { [weak self] result in
switch result{
case.success(let photo):
self?.hits = photo.hits
self?.delegate?.refreshUI()
case.failure(let error):
print(error)
self?.delegate?.showError()
}
}
}
func downloadImage(row: Int, completion: @escaping (Data) -> Void) {
let hit = hits[row]
let hitpath = hit.previewURL
if let data = cache[hitpath] {
completion(data)
return
}
networkManager
.getData(from: hitpath) { result in
switch result {
case .success(let data):
self.cache[hitpath] = data
DispatchQueue.main.async {
completion(data)
}
case .failure(let error):
print(error)
}
}
}
Here is the code in view controller .
import UIKit
class PhtotoDetailsViewController: UIViewController {
var photoviewModel : PhotoViewModel?
var peopleDetailsViewModel:PeopleDetailsViewModel?
private var stackView: UIStackView = {
let stackView = UIStackView()
stackView.axis = .vertical
stackView.distribution = .fill
stackView.alignment = .fill
stackView.spacing = 5
stackView.translatesAutoresizingMaskIntoConstraints = false
return stackView
}()
private let imageView: UIImageView = {
let imageView = UIImageView(frame: .zero)
imageView.contentMode = .scaleAspectFill
imageView.translatesAutoresizingMaskIntoConstraints = false
return imageView
}()
private let tagLabel: UILabel = {
let label = UILabel(frame: .zero)
label.textAlignment = .center
label.numberOfLines = 0
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
view.addSubview(stackView)
view.addSubview(tagLabel)
view.addSubview(imageView)
setUpUI()
setPhoto()
setContrain()
}
private func setContrain(){
NSLayoutConstraint.activate([
stackView.topAnchor.constraint(equalTo: view.topAnchor,constant: 100),
stackView.bottomAnchor.constraint(equalTo: view.bottomAnchor,constant: -200),
stackView.leftAnchor.constraint(equalTo: view.leftAnchor , constant: 10),
stackView.rightAnchor.constraint(equalTo: view.rightAnchor,constant: 10),
stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor )
])
stackView.addArrangedSubview(imageView)
stackView.addArrangedSubview(tagLabel)
}
private func setUpUI(){
tagLabel.text = photoviewModel?.hits.first?.tags
}
var rowSelected = 0
private func setPhoto(){
photoviewModel?.downloadImage(row: rowSelected) { [weak self] data in
DispatchQueue.main.async {
let image = UIImage(data: data)
self?.imageView.image = image
}
}
}
}
I am having problem on this line ..
private func setUpUI(){
tagLabel.text = photoviewModel?.hits.first?.tags
}
Here is the screenshot when the app load first and it has image and label property ...
When I click the third cell form collection It has the correct image but correct label property .
CodePudding user response:
In your setupUI()
replace the line tagLabel.text = photoviewModel?.hits.first?.tags
with this
tagLabel.text = photoviewModel?.hits[rowSelected].tags