0

I want to do something like this, I want each of my JSON data (from PHP) show in each cell of the table. The JSON data includes text and images. Now I am only able to show text but am unable to extract the images. For Example, I want to show the images in the Section:New Meter Details whereas I still able to show text in other cell. Any way to reuse the table view cell for both text and images? Please advice. This is my JSON data and I change it to swift dictionary already :

["cp_replacemeter": 1, "cp_current_l3": 3, "cp_voltage_l2": 2221, "cp_tktno": 3333, "ap_contact_no": 998, "cpremark": , "cp_voltage_l3": 2221, "cprefno": 17-0762, "cp_oldmeter_img": images/17-0762/222.jpg, "cpfaultyremark": , "co_id": 15, "cp_customer_signature": images/17-0762/17-0762-CustomerSign.jpg, "cp_meter_cover": Cover Broken, "error": 0, "cp_new_tariff": 1, "cp_service_type": CHANGE METER;, "cprtm_name": CONLOG, "cpi_no": 15670, "cp_meter_seal": Seals Broken, "cpcontact_no": 3331, "cpserviceremark": , "tag": search, "cptm_name": PRESSEY, "cplatitude": 3.12312, "cp_AddPhoto3": images/17-0762/other/17-0762-photo3.jpg, "cpt_of_meter": 3 Phase, "cplongitude": 110.86275, "cp_voltage_l1": 2221, "cp_AddPhoto2": images/17-0762/other/17-0762-photo2.jpg, "cp_AddPhoto5": images/17-0762/other/17-0762-photo5.jpg, "cpDistrict": KB, "cpc_name": 221, "cp_newmeter_img": images/17-0762/1.jpg, "cpaddress": 331, "cp_AddPhoto4": images/17-0762/other/17-0762-photo4.jpg, "cp_fault_type": METER HANG;, "cpr_tometer": 1 PHASE, "cp_old_tariff": 1, "cp_AddPhoto6": images/17-0762/other/17-0762-photo6.jpg, "cpic_no": 3331, "cp_current_l1": 1, "cp_AddPhoto1": images/17-0762/other/17-0762-photo1.jpg, "cpm_no": 222, "cp_current_l2": 2]

import UIKit

class MyTableViewController: UITableViewController {

struct Objects {
    var sectionName : String!
    var sectionObject : [String]!
}

var objectsArray = [Objects]()

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.rowHeight=UITableViewAutomaticDimension
    tableView.estimatedRowHeight = 100
    LoadJsonData()
}

func LoadJsonData () {


    let request = NSMutableURLRequest(url: NSURL(string:"http://<myphpaddress>appcpapi.php")! as URL)
    request.httpMethod = "POST"

    let poststring = "tag=search&refno=17-0762"

    request.httpBody = poststring.data(using: String.Encoding.utf8)

    let task = URLSession.shared.dataTask(with: request as URLRequest) { (data, response, error) in

        if error != nil
        {
            print("error= \(error)")
            return
        }
        else
        {
            do{
                let dictionary = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String : Any]

                let ticket = dictionary["cp_tktno"] ?? "No data" 
                let name = dictionary["cpc_name"] ?? "No data"
                let customerIC = dictionary["cpic_no"] ?? "No data"
                let district = dictionary["cpDistrict"] ?? "No data"
                let customercontact = dictionary["cpcontact_no"] ?? "No data"
                let address = dictionary["cpaddress"] ?? "No data"
                let latitudeGPS = dictionary["cplatitude"] ?? "No data"
                let longitudeGPS = dictionary["cplongitude"] ?? "No data"
                let om = dictionary["cpm_no"] ?? "No data"
                let omtariff = dictionary["cp_old_tariff"] ?? "No data"
                let ombrand = dictionary["cptm_name"] ?? "No data"
                let omtype = dictionary["cpt_of_meter"] ?? "No data"
                let omfaulty = dictionary["cp_fault_type"] ?? "No data"
                let omseal = dictionary["cp_meter_seal"] ?? "No data"
                let omcover = dictionary["cp_meter_cover"] ?? "No data"
                let nm = dictionary["cp_replacemeter"] ?? "No data"
                let nmtariff = dictionary["cp_new_tariff"] ?? "No data"
                let nmbrand = dictionary["cprtm_name"] ?? "No data"
                let nmtype = dictionary["cpr_tometer"] ?? "No data"
                let nmservice = dictionary["cp_service_type"] ?? "No data"
                let v1 = dictionary["cp_voltage_l1"] ?? "No data"
                let v2 = dictionary["cp_voltage_l2"] ?? "No data"
                let v3 = dictionary["cp_voltage_l2"] ?? "No data"
                let a1 = dictionary["cp_current_l1"] ?? "No data"
                let a2 = dictionary["cp_current_l2"] ?? "No data"
                let a3 = dictionary["cp_current_l3"] ?? "No data"
                let contractorID = dictionary["co_id"] ?? "No data"
                let contractorcontact = dictionary["ap_contact_no"] ?? "No data"
                let faultyremark = dictionary["cpfaultyremark"] ?? "No data"
                let serviceremark = dictionary["cpserviceremark"] ?? "No data"

                let newmeterimageurl = NSURL(string:"\(dictionary["cp_newmeter_img"]!)")!
                let newmeterimagedata = NSData(contentsOf: newmeterimageurl as URL)
                let MyWantedToShowImage = UIImage(data: newmeterimagedata! as Data)

                DispatchQueue.main.async {
                    self.objectsArray = [MyTableViewController.Objects(sectionName: "Customer Details",
                                                                       sectionObject:[
                                                                        "Ticket No \n\(ticket)",
                                                                        "Name \n\(name)",
                                                                        "Customer Contact \n\(customercontact)",
                                                                        "Customer IC \n\(customerIC)",
                                                                        "Address \n\(address)",
                                                                        "District:\n\(district)",
                                                                        "Latitude GPS\n\(latitudeGPS)",
                                                                        "Longitude GPS \n\(longitudeGPS)"]),
                                         MyTableViewController.Objects(sectionName: "Old Meter Details",
                                                                       sectionObject:[
                                                                        "Old Meter Number \n\(om)",
                                                                        "Old Meter Tariff \n\(omtariff)",
                                                                        "Old Meter Brand \n \(ombrand)",
                                                                        "Old Meter Type \n\(omtype)",
                                                                        "Old Meter Faulty \n\(omfaulty)",
                                                                        "Old Meter Seal \n\(omseal)",
                                                                        "Old Meter Cover \n\(omcover)"]),
                                         MyTableViewController.Objects(sectionName: "New Meter Details",
                                                                       sectionObject:[
                                                                        "New Meter Number \n\(nm)",
                                                                        "New Meter Tariff \n\(nmtariff)",
                                                                        "New Meter Brand  \n\(nmbrand)",
                                                                        "New Meter Type \n\(nmtype)",
                                                                        "New Meter Service \n\(nmservice)",
                                                                        "L1 Voltage \n\(v1)",
                                                                        "L2 Voltage \n\(v2)",
                                                                        "L3 Voltage \n\(v3)",
                                                                        "L1 Ampere \n\(a1)",
                                                                        "L2 Ampere \n\(a2)",
                                                                        "L3 Ampere \n\(a3)",
                                                                        "New Meter Image \n\(MyWantedToShowImages?.images)"]),
                                         MyTableViewController.Objects(sectionName: "Customer Signature",
                                                                       sectionObject:[
                                                                        "Contrator ID \n\(contractorID)",
                                                                        "Contractor Contact \n\(contractorcontact)",
                                                                        "Faulty Remark \n\(faultyremark)",
                                                                        "Service Remark \n\(serviceremark)"])]

                    self.tableView.reloadData()
                }

            }//Catch Error

            catch let error{
                print(error)
            }
        }

    }
    task.resume()

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}



override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
    return objectsArray[section].sectionObject.count
}

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

    cell?.textLabel?.numberOfLines = 0
    cell?.textLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping
    cell?.textLabel?.text = objectsArray[indexPath.section].sectionObject[indexPath.row]
    cell?.textLabel?.font = UIFont.systemFont(ofSize: 13, weight: 0.2)
       return cell!
}

override func numberOfSections(in tableView: UITableView) -> Int{
    return objectsArray.count
}

override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?{

    return objectsArray[section].sectionName
}


}
Fahim
  • 3,466
  • 1
  • 12
  • 18
Yuan
  • 107
  • 2
  • 13

1 Answers1

0

If you want to display text separately from images, then you'd have to set up another cell prototype in your storyboard for the images. Assign a different cell identifier to it and when you need an image cell, create it using the new cell identifier, similar to what you do here:

let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as UITableViewCell!

If you want both the text and the image in one table cell, then you simply have to modify your existing prototype to accommodate both. Do let me know if you need additional information.

Fahim
  • 3,466
  • 1
  • 12
  • 18
  • I would like to try it out by my own first with you suggestion/advice. I will let you know again after trying. – Yuan Mar 24 '17 at 04:03
  • Sure thing :) Post a reply here if you want me any help and I'll respond. – Fahim Mar 24 '17 at 04:07
  • Hi, I've search over the net regarding set up another cell identifier to distinguish Text and Images. However, I don't know how to Reload() my table. because theres two different cell in the table, how would swift know which struct var to implement? For example, I want to display the text accordingly as written in the code, however,in the section "New Meter Details", I want to add in image at the last row in that section. Afterward, just continue to another section which start with Text. How am I gonna tell swift whether Text or Image is coming? – Yuan Mar 24 '17 at 09:16
  • You'd check to see what the section is and then depending on the section, create either a text cell or an image cell. Does that make sense? – Fahim Mar 24 '17 at 09:17
  • In one section there are cells for both text and image. How do I tell swift : oh please hold on, before you go to next Text Cell, there is an Image Cell coming, and please proceed with the Image Cell call first before go to next Text Cell? – Yuan Mar 24 '17 at 09:20
  • In cellForRowAt, you have to figure out what data you have to display. So there, when you know which data you are going to display, you create either a text cell or an image cell. If you don't know which type of cell you are going to display at that point, you can't make this work anyway. I can't really tell you how to detect which row you are going to display since I don't know about your data ... – Fahim Mar 24 '17 at 09:27
  • Hi, I just wonder how can I do something like this. In cellForRowAt, I need to check the coming is: if text { run dequeueReusableCell(with identifier : "Text") cell?.TextLabel?.text = ...... } else if image{ run dequeueReusableCell(with identifier : "Image") cell?.ImageView?.image = ...... } else{ default: } for this scenario, will there be separate or different index path for text and image? – Yuan Mar 24 '17 at 09:50
  • It's the same indexPath for both since the indexPath is for the current row to display. What you are doing is deciding which type of row to display for the current row :) – Fahim Mar 24 '17 at 09:53
  • Hi, I've being trying for one day long and still couldn't get to do so, can you guide me a little bit more? – Yuan Mar 25 '17 at 06:04
  • Perhaps this thread will help since it has detailed steps - http://stackoverflow.com/questions/30774671/uitableview-with-more-than-one-custom-cells-with-swift Otherwise, unless you can share the project, I'm afraid that I don't know how else to help :( – Fahim Mar 25 '17 at 06:55
  • I finally roughly got the idea after searching over the web, conclusion: I still need to create an empty row for the image right starting on? later on in the cellForRowAt side, I need to call "if indexPath.session == 2" then inside the if statement, make another "if indexPath.row == 11, then do something with the new cell identify? Is this correct idea/concept behind? – Yuan Mar 25 '17 at 07:58