Home > database >  Swift Collection View always return first default value from Model
Swift Collection View always return first default value from Model

Time:05-25

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 ... enter image description here

When I click the third cell form collection It has the correct image but correct label property .

enter image description here

CodePudding user response:

In your setupUI() replace the line tagLabel.text = photoviewModel?.hits.first?.tags with this

tagLabel.text = photoviewModel?.hits[rowSelected].tags
  • Related