Reputation: 125
I have multiple label in tableview. Created an array for label left side. now i am trying to load data from array model for each label. But it says index out of range, cause it model array index is 0.
Here is my model :
class PrItemDetailModel {
var Material: String?
var Description: String?
var FixedVendor: String?
var VendorName: String?
var PurchOrg: String?
var PurchGroup: String?
var qtyUoM: String?
var valuationPrice: String?
var TotalValue: String?
var DeliveryDate: String?
var MatGrp: String?
var Plant: String?
var StorageLocation: String?
var ReqTrack: String?
var AAC: String?
var ItemCategory: String?
var GLAccount: String?
var CostCenter: String?
var Order: String?
var WBS: String?
var ProfitCenter: String?
init(Material: String?, Description: String?, FixedVendor: String?, VendorName:String?, PurchOrg: String?, PurchGroup: String?, qtyUoM: String?, valuationPrice: String?, TotalValue: String?, DeliveryDate: String?, MatGrp: String?, Plant: String?, StorageLocation: String?, ReqTrack: String?, AAC: String?, ItemCategory: String?, GLAccount: String?, CostCenter: String?, Order: String?, WBS: String?, ProfitCenter: String?){
self.Material = Material
self.Description = Description
self.FixedVendor = FixedVendor
self.VendorName = VendorName
self.PurchOrg = PurchOrg
self.PurchGroup = PurchGroup
self.qtyUoM = qtyUoM
self.valuationPrice = valuationPrice
self.TotalValue = TotalValue
self.DeliveryDate = DeliveryDate
self.MatGrp = MatGrp
self.Plant = Plant
self.StorageLocation = StorageLocation
self.ReqTrack = ReqTrack
self.AAC = AAC
self.ItemCategory = ItemCategory
self.GLAccount = GLAccount
self.CostCenter = CostCenter
self.Order = Order
self.WBS = WBS
self.ProfitCenter = ProfitCenter
}
}
Here is array created for label:
var PrItemTitleLblArray = ["Material#", "Description", "Fixed Vendor#","Vendor Name", "Purch Org", "Purch Group", "Qty | UoM", "valuation Price", "Total Value", "Delivery Date", "Mat Grp", "Plant", "Storage Location", "Req Track#", "AAC", "Item Category", "G/L Account", "Cost Center", "Order", "WBS", "Profit Center"]
Here is the array from model:
var prItemArray = [PrItemDetailModel(Material: "", Description: "Bottles", FixedVendor: "KP04", VendorName: "KP Suppliers", PurchOrg: "1000", PurchGroup: "002", qtyUoM: "40.000 EA", valuationPrice: "EUR 40.00", TotalValue: "EUR 1,600.00", DeliveryDate: "09/12/2014", MatGrp: "00807", Plant: "1100", StorageLocation: "", ReqTrack: "", AAC: "Cost Center", ItemCategory: "0", GLAccount: "000040000", CostCenter: "0000010000", Order: "", WBS: "0000000", ProfitCenter: "0000001402")]
Here is the code which i have used in tableview:
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! PrItemCellTableViewCell
cell.material.text = PrItemTitleLblArray[indexPath.row]
cell.materialvalue = prItemArray[indexPath.row]
return cell
Here is screenshot which i want to achieve:
here is my json response:
"results": [
{
"PoDocNo": "4500022400",
"Item": "00010",
"Material": "RMECC_MOB1",
"StorageLocation": "3001",
"MatGroup": "00107",
"Quantity": "2.000",
"OrderUnit": "KG",
"NetPrice": "1000.000",
"UnitofPrice": "1.000",
"ItemCat": "0",
"Requistor": ""
},
{
"PoDocNo": "4500022400",
"Item": "00020",
"Material": "RMECC_MOB1",
"StorageLocation": "3001",
"MatGroup": "00107",
"Quantity": "2.000",
"OrderUnit": "KG",
"NetPrice": "1000.000",
"UnitofPrice": "1.000",
"ItemCat": "0",
"Requistor": ""
}
]
Any help much appreciated pls...
Upvotes: 2
Views: 120
Reputation: 804
@Parameswaran V
Here below check my simple updated answer for Can you suggest me best way for above one while passing json
You can create the Structure to form your required record like below,
struct DemoItems {
var key: String?
var value: String?
}
fileprivate var demoItems: [DemoItems]?
fileprivate func loadDemoItems() -> [DemoItems] {
var tempItems = [DemoItems]()
let item1 = DemoItems.init(key: "Material#", value: "")
let item2 = DemoItems.init(key: "Description", value: "Bottles")
let item3 = DemoItems.init(key: "Fixed Vendor#", value: "KP04")
let item4 = DemoItems.init(key: "Vendor Name", value: "KP Suppliers")
let item5 = DemoItems.init(key: "Purch Org", value: "1000")
tempItems.append(item1)
tempItems.append(item2)
tempItems.append(item3)
tempItems.append(item4)
tempItems.append(item5)
return tempItems
}
In viewDidLoad like,
demoItems = loadDemoItems()
if let tempDemoItems = demoItems {
print(tempDemoItems)
print(tempDemoItems[0].key)
print(tempDemoItems[0].value)
}
Output:
[permisdesauver_dev.DemoItems(key: Optional("Material#"), value: Optional("")), permisdesauver_dev.DemoItems(key: Optional("Description"), value: Optional("Bottles")), permisdesauver_dev.DemoItems(key: Optional("Fixed Vendor#"), value: Optional("KP04")), permisdesauver_dev.DemoItems(key: Optional("Vendor Name"), value: Optional("KP Suppliers")), permisdesauver_dev.DemoItems(key: Optional("Purch Org"), value: Optional("1000"))]
Optional("Material#")
Optional("")
So your cell.material.text = tempDemoItems[indexPath.row].key & cell.materialvalue.text = tempDemoItems[indexPath.row].value
Hope it's help you!
Upvotes: 1
Reputation: 77476
The problem is that you are creating an array of Label Strings, and then you think you are creating an array of Values... but you're only creating an array of ONE PrItemDetailModel
object.
Consider this (I've simplified your class to make it easier to see):
class PrItemDetailModel {
var Material: String?
var Description: String?
var FixedVendor: String?
init(Material: String?, Description: String?, FixedVendor: String?) {
self.Material = Material
self.Description = Description
self.FixedVendor = FixedVendor
}
}
class ViewController: UIViewController {
// create array of Label Strings
var PrItemTitleLblArray = ["Material#", "Description", "Fixed Vendor#"]
// create array of PrItemDetailModel objects
var prItemArray = [PrItemDetailModel(Material: "", Description: "Bottles", FixedVendor: "KP04")]
override func viewDidLoad() {
super.viewDidLoad()
// this will print "3"
print(PrItemTitleLblArray.count)
// this will print "1"
print(prItemArray.count)
}
}
So when you try to fill rows in a table, your first row - indexPath.row
equals 0
- your codes says:
// get the "Label String" from the array of Label Strings
// at index 0, this will be "Material#"
cell.material.text = PrItemTitleLblArray[indexPath.row]
// get the "Value String" from the array of PrItemDetailModel objects
// at index 0, this will be AN OBJECT, not a String
cell.materialvalue = prItemArray[indexPath.row]
The next row - indexPath.row
equals 1
- your codes says:
// get the "Label String" from the array of Label Strings
// at index 1, this will be "Description"
cell.material.text = PrItemTitleLblArray[indexPath.row]
// get the "Value String" from the array of PrItemDetailModel objects
// at index 1 ... ERROR, because prItemArray has only one element
cell.materialvalue = prItemArray[indexPath.row]
You probably want to re-think your data structure... Where will you be getting these values? Via json from a server? From a database? You might be better off simply storing the data in an array of Dictionaries.
Or, and this is just one other way to approach it... modify your class to return values based on indexing:
class PrItemDetailModel {
var Material: String?
var Description: String?
var FixedVendor: String?
init(Material: String?, Description: String?, FixedVendor: String?) {
self.Material = Material
self.Description = Description
self.FixedVendor = FixedVendor
}
func getProperty(at index: Int) -> String {
switch index {
case 0:
return self.Material ?? ""
case 1:
return self.Description ?? ""
case 2:
return self.FixedVendor ?? ""
default:
return "Error"
}
}
}
You would then change your code to:
// create ONE PrItemDetailModel object
var prItem = PrItemDetailModel(Material: "", Description: "Bottles", FixedVendor: "KP04")
and in cellForRowAt
:
// get the "Label String" from the array of Label Strings
cell.material.text = PrItemTitleLblArray[indexPath.row]
// get the "Value String" from the array of PrItemDetailModel objects
// based on the index
cell.materialvalue.text = prItem.getProperty(at: indexPath.row)
Upvotes: 1