Issue with passing proper image to tableviewcell

2019-08-22 04:53发布

This is my struct...

struct ProductImage {
   let id : String
   let url : URL
   let isDefault : Bool
}

struct Product {
    let name : String
    let id : String
    var images = [ProductImage]()

    init(name : String, id: String) {
        self.name = name
        self.id = id
    }

    mutating func add(image: ProductImage) {
        images.append(image)
    }
}

Now I have an image loaded on the collectionview and on the click of a button, I want to pass this image to a tableviewcell. The collectionview does have a couple of labels with name and id which is passed successfully...But how the image can be passed that I'm not able to figure out. Below is what happens so far on the click of the sell button...

func SellBtnTapped(_ sender: UIButton) {

   let indexPath = collectionView?.indexPath(for: ((sender.superview?.superview) as! RecipeCollectionViewCell))

   let myVC = storyboard?.instantiateViewController(withIdentifier: "productSellIdentifier") as! sellTableViewController
   let productObject = productData1[(indexPath?.row)!]

   if selectedItems == nil {
       //selectedItems is an array which will hold all struct items.
       selectedItems = [Product(name:productObject.name, id: productObject.id)]
   } else {
       selectedItems?.append(productObject)
   }

   myVC.arrProduct = selectedItems
   navigationController?.pushViewController(myVC, animated: true)
}

This is how I'm assigning the images and other data in the tableviewcell. This is the code of cellForRow..(of the tableview from where the cells are loaded..)

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
             let cell: sellTableViewCell = tableView.dequeueReusableCell(withIdentifier: "sellProductIdentifier") as! sellTableViewCell

    //cell.prdImgView?.image =.... by doing this, the images are displayed in the tableviewcell in the same order as they are displayed in the collectionview cells irresoective of which cell was clicked. i.e clicking on btn on 1st collection view item shows the image on that collection view item on the tableviewcell.And when I click on the btn on the 4th collectionview item the image shown on the tableview cell will be that of the 2nd collectionview item...     
             cell.prdImgView?.image = self.appDelegate.commonArrayForURLImages[indexPath.row]                              

             let product = arrProduct?[indexPath.row]
             cell.produvtNameLabel.text = product?.name
             cell.rateTextField.text = product?.theRate

             return cell
        }

This is how the array(which is passed to the tableview cell) gets the images...

var theProduct = Product(name: name, id: id, theRate: rate, quantity: qty, sku: skuCode, prdCateg: prodCat, prodDescr: description)
if let images1 = anItem["product_images"] as? [[String:String]] {
    for image in images1 {
        guard let imageId = image["id"],
            let url1 = image["image"],
            let isDefault = image["is_default"] else { continue }
        let productImage = ProductImage(id: imageId, url: URL(string: url1)!, isDefault: isDefault == "1")
        theProduct.add(image: productImage)
        self.productData1.append(theProduct)
        self.imgData.append(productImage)
        let url = URL(string: url1)
        if let data = try? Data(contentsOf: url!) {
            let img = UIImage(data: data)
            print(img!)
            self.arrayOfURLImages.append(img!)
        }

        self.appDelegate.commonArrayForURLImages = self.arrayOfURLImages
    }
}

1条回答
贼婆χ
2楼-- · 2019-08-22 05:06

Structs provide you with member wise initialiser, so in most cases you don't need one of your own.In your code your product initialiser is only holding name and id, and not array of productImage, You seem to be having a separate function for holding that data, which i think is not needed here.So what I did is just created a array type for [ProductImages] and sticked with default initialiser.

import Foundation

struct ProductImage {
    let id        : String?
    let url       : String? // Keep this string
    let isDefault : Bool?
}

struct Product {
    let name   : String?
    let id.    : String?
    var images : [ProductImage]?
}

ControllerClass(with collection view getting initial data)-:

In your controller class I created 2 arrays -:

1) That holds data for images .

2) That holds data for entire product information.

For saving data I am just passing constant values for now. In viewDidLoad I called initialiser for each object -:

1) Holding images object data.

2) ProductObject data .

3) Append both object to appropriate arrays.

import UIKit
class MyViewController: UIViewController {

    @IBOutlet weak var mainCollectionView: UICollectionView!

    // ARRAY OBJECT OF TYPE PRODUCT AND PRODUCT IMAGE

    var imageData   = [ProductImage]()
    var productData = [Product]()


    //viewDidLoad
    override func viewDidLoad() {
        super.viewDidLoad()
        modelDataForCollectionView()
        }

    func modelDataForCollectionView(){

        // GET IMAGE DATA

        let imageObject = ProductImage(id: "1", url: "your url", isDefault: true)
        imageData.append(imageObject)

        // MODEL FOR PRODUCTS

        let productObject = Product(name: "", id: "", images: imageData)
        productData.append(productObject)
    }

    //didReceiveMemoryWarning
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

// MyViewController extending collection view

extension MyViewController :UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout{
    //numberOfItemsInSection
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int{
        return productData.count
    }


    //dequeueReusableCell
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell{
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionCell
        cell.sendButton.addTarget(self, action: #selector(sendDataToTable), for: UIControlEvents.touchUpInside)
        return cell
    }

    //numberOfSections

    func numberOfSections(in collectionView: UICollectionView) -> Int{
        return 1
    }

    // sizeForItemAt for each row
    public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize{
        return CGSize(width: view.frame.width, height: 200)
    }

    func sendDataToTable(sender:UIButton){
        let index = mainCollectionView.indexPath(for: sender.superview?.superview as! CollectionCell)
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let Controller = storyboard.instantiateViewController(withIdentifier: "tableData") as! ViewController1
        Controller.dataForTableView = productData[(index?.row)!].images
        self.navigationController?.pushViewController(Controller, animated: true)
    }

}

Now when you tap on a button in UICollectionViewCell , get the tapped index , and read product object present at that index from Product array.After that you can easily pass required data to table view(Second class).

Second controller class-:

 import UIKit

    class ViewController1: UIViewController {

// ARRAY TO HOLD IMAGE DATA FOR TAPPED COLLECTION CELL

        var dataForTableView:[ProductImage]?
        var name            : String?
        var id              : String?

        @IBOutlet weak var secondTable: UITableView!

        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view.

            // CHECK FOR DATA

            print(dataForTableView?[0].url as Any) // Optional("your url")
        }

        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }

    }

    extension ViewController1 : UITableViewDelegate,UITableViewDataSource{
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
            return 1
        }


        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
            let cell = tableView.dequeueReusableCell(withIdentifier: "cell1") as! testingCell2
            return cell
        }

        // Number of sections in table

        func numberOfSections(in tableView: UITableView) -> Int {
            return 1
        }// Default is 1 if not implemented

        public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat{
            return 50
        }

    }

Once you get image URL and any other required information in second class, you can present that on table easily. To get images make api call to server. I hope that helps you.

Code for parsing-:

var imageUrl:String?
var imageId:String?
var isDefaults:String?
var productId:String?
var productIdTitle:String?
var productIdImageWithPath:String?

//MARK : Call Back Delegate Methods

    func apiSuccessResponse(_ response: Dictionary<String, AnyObject>) {

        print(response)
        if let actualStyleData = response["Productdata"]  as? [Dictionary<String, AnyObject>]{

            for object in actualStyleData{

                if let id = object["product_id"] as? String{
                    productId = id
                }else{
                    productId = ""
                }
                if let title = object["product_name"] as? String{
                    productIdTitle = title
                }

                if let imageDetails = object["product_images"] as? [Dictionary<String, AnyObject>]{
                    for details in imageDetails{
                        if let id = details["id"] as? String{
                            imageId = id
                        }
                        if let url = details["image"] as? String{
                            imageUrl = url
                        }
                        if let isDefault = details["is_default"] as? String{
                           isDefaults = isDefault
                        }
                        let saveImageObject = ProductImage(id: imageId, url: imageUrl, isDefault: isDefaults)
                        imageData.append(saveImageObject)
                    }
                }
                        let saveProductObject = Product(name: productIdTitle, id: productId, images: imageData)
                        productData.append(saveProductObject)
            }
        }
    }
查看更多
登录 后发表回答