I have implemented a tableView using PLIST to set properties.
I would like to add three sections at specific row. (row 12, row24, row 35)
I have tried with following code but it will be too much code and not working well.
Images and code are added below.
import UIKit
class HomeViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet var tblStoryList: UITableView!
var array = PLIST.shared.mainArray
var array = PLIST.shared.mainArray
let sections: [String] = ["First stage","Second Stage","Third Stage"]
let s1Data : [String] = ["Row1","Row2","Row3"]
let s2Data : [String] = ["Row4","Row5","Row6"]
let s3Data : [String] = ["Row7","Row8","Row9"]
var sectionData: [Int: [String]] = [:]
override func viewDidLoad() {
super.viewDidLoad()
sectionData = [0: s1Data, 1: s2Data, 2: s3Data]
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (sectionData[section]?.count)!
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sections[section]
}
func numberOfSections(in tableView: UITableView) -> Int {
return 3
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) ->
UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "StoryTableviewCell", for: indexPath) as! StoryTableviewCell
//making plist file
let dict = self.array[indexPath.row]
let title = dict["title"] as! String
let imageName = dict["image"] as! String
let temp = dict["phrases"] as! [String:Any]
let arr = temp["array"] as! [[String:Any]]
let detail = "progress \(arr.count)/\(arr.count)"
//property to plist file
cell.imgIcon.image = UIImage.init(named: imageName)
cell.lblTitle.text = title
cell.lblSubtitle.text = detail
cell.selectionStyle = UITableViewCellSelectionStyle.none
return cell
}
The indexPath.row you are getting in the tableView's cellForRowAt is relative to the section. You cannot use it directly as the index of your main array (which has all the rows).
You will need to perform a simple calculation to convert the indexPath.row to an index of that array (by offsetting the row with the total item count of previous sections) :
let index = [0,12,36][indexPath.section] + indexPath.row
let dict = array[index]
The same thing applies to the response you give to numberOfRowsInSection:
return [12,24,35][section]
I find it a bit odd that the data structure (PLIST) would be so rigid that it always contains exactly those number of entries and will never change. I would suggest a more generalized approach if only to avoid spreading hard coded numbers (e.g. 12,24,35,36) all over the place.
for example:
// declare section attributes in your class
let sectionTitles = ["First stage","Second Stage","Third Stage"]
let sectionSizes = [12,24,35] // central definition, easier to maintain (or adjust to the data)
let sectionOffsets = sectionSizes.reduce([0]){$0 + [$0.last!+$1] }
// and use them to respond to the table view delegate ...
let index = sectionOffsets[indexPath.section] + indexPath.row
let dict = array[index]
// ...
return sectionSizes[section] // numberOfRowsInSection
Using this approach, you shouldn't need to create sectionData (unless you're using it for other purposes elsewhere).
BTW, in your sample code, the sectionData content is hard coded with data that is not consistent with the expected section sizes so it would not work even with a correct index calculation.
you can try to use switch case in tableView:cellForRowAtIndexPath:
Related
Currently Im able to get cells to add up their total in the sections Footer Cell. But it calculates the total for every cell no matter what section its in, inside the all the sections footer.
I still can't get it to add up the different prices(Price1 - 3) for the cells that have a different prices selected passed into it the Section
code im using to add up total in the CartFooter for the Cells in the sections cartFooter.cartTotal.text = "\(String(cart.map{$0.cartItems.price1}.reduce(0.0, +)))"
PREVIOUSLY:
im trying to get the Cells in each section to add up their total in footer cell for each section that they're in.
The data in the CartVC is populated from another a VC(HomeVC). Which is why there is 3 different price options in the CartCell for when the data populates the cells.
Just kind of stuck on how I would be able to get the total in the footer for the cells in the section
Adding specific data for each section in UITableView - Swift
Thanks in advance, Your help is much appreciated
extension CartViewController: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return brands
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let brand = brands[section]
return groupedCartItems[brand]!.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cartCell = tableView.dequeueReusableCell(withIdentifier: "CartCell") as! CartCell
let brand = brands[indexPath.section]
let cartItemsToDisplay = groupedCartItems[brand]![indexPath.row]
cartCell.configure(withCartItems: cartItemsToDisplay.cartItems)
return cartCell
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let cartHeader = tableView.dequeueReusableCell(withIdentifier: "CartHeader") as! CartHeader
let headerTitle = brands[section]
cartHeader.brandName.text = "Brand: \(headerTitle)"
return cartHeader
}
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let cartFooter = tableView.dequeueReusableCell(withIdentifier: "FooterCell") as! FooterCell
let sectionTotal = cart[section].getSectionTotal()
let calculate = String(cart.map{$0.cartItems.price1}.reduce(0.0, +))
cartFooter.cartTotal.text = "$\(calculate)"
return cartFooter
}
}
Update: these are the results that I am getting using this in the CartFooter
let calculate = String(cart.map{$0.cart.price1}.reduce(0.0, +))
cartFooter.cartTotal.text = "$\(calculate)"
which calculates the overall total (OT) for all the sections and places the OT in all all Footer Cells(as seen below ▼) when im trying to get the total for each section in their footers (as seen in image above ▲ on the right side)
Update2:
this what ive added in my cellForRowAt to get the totals to add up in the section footer. it adds up the data for the cells but it doesn't give an accurate total in the footer
var totalSum: Float = 0
for eachProduct in cartItems{
productPricesArray.append(eachProduct.cartItem.price1)
productPricesArray.append(eachProduct.cartItem.price2)
productPricesArray.append(eachProduct.cartItem.price3)
totalSum = productPricesArray.reduce(0, +)
cartFooter.cartTotal.text = String(totalSum)
}
There's a lot of code, and I'm not too sure where your coding error lies. With that said:
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let cartFooter = tableView.dequeueReusableCell(withIdentifier: "FooterCell") as! FooterCell
let sectionTotal = cart[section].getSectionTotal()
let calculate = String(cart.map{$0.cart.price1}.reduce(0.0, +))
cartFooter.cartTotal.text = "$\(calculate)"
return cartFooter
}
Your code seems to say let sectionTotal = cart[section].getSectionTotal() is the total you are looking for (i.e. the total within a section), while you are displaying the OT in a section, by summing up String(cart.map{$0.cart.price1}.reduce(0.0, +)).
In other words, if cartFooter is the container that will display the total within a section, one should read cartFooter.cartTotal.text = "$\(sectionTotal)" instead, no?
If that's not the answer, I suggest that you set a breakpoint each time the footerView is instantiated, and figure out why it output what it outputs (i.e. the OT, instead of the section total).
#Evelyn Try calculation directly in footer. Try below code.
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let cartFooter = tableView.dequeueReusableCell(withIdentifier: "FooterCell") as! FooterCell
let brand = brands[indexPath.section]
let arrAllItems = groupedCartItems[brand]!
var total: Float = 0
for item in arrAllItems {
if item.selectedOption == 1 {
total = total + Float(item.price1)
} else item cartItems.selectedOption == 2 {
total = total + Float(item.price2)
} else if item.selectedOption == 3 {
total = total + Float(item.price3)
}
}
cartFooter.cartTotal.text = "$\(total)"
return cartFooter
}
If you want to correct calculate total price in each section you need filter items for every section. now i think you sum all of your section.
For correct section you need yous snipper from your cellForRow method:
let brand = brands[indexPath.section]
let cartItemsToDisplay = groupedCartItems[brand]![indexPath.row]
cartCell.configure(withCartItems: cartItemsToDisplay.cart)
inside this:
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let cartFooter = tableView.dequeueReusableCell(withIdentifier: "FooterCell") as! FooterCell
let sectionTotal = cart[section].getSectionTotal()
let brand = brands[section]
let catrItemsToDisplay = // now you need to get associated items with this brand (cart)
// I think it is can looks like this = cartItemsToDisplay[brand]
let calculate = String(cartItemsToDisplay.cart.reduce(0.0, +))
cartFooter.cartTotal.text = "$\(calculate)"
return cartFooter
}
Modify your Model structure and the way values set to through TableViewDelegate. Giving a short hint. Please see if it helps:
class Cart {
var brandWiseProducts: [BrandWiseProductDetails]!
init() {
brandWiseProducts = [BrandWiseProductDetails]()
}
initWIthProducts(productList : [BrandWiseProductDetails]) {
self.brandWiseProducts = productList
}
}
class BrandWiseProductDetails {
var brandName: String!
var selectedItems: [Items]
var totalAmount: Double or anything
}
class SelectedItem {
var image
var name
var price
}
Sections:
Cart.brandWiseProducts.count
SectionTitle:
Cart.brandWiseProducts[indexPath.section].brandName
Rows in section
Cart.brandWiseProduct[indexPath.section].selectedItem[IndexPath.row]
Footer:
Cart.brandWiseProduct.totalAmount
I have a data source in this form:
struct Country {
let name: String
}
The other properties won't come into play in this stage so let's keep it simple.
I have separated ViewController and TableViewDataSource in two separate files. Here is the Data source code:
class CountryDataSource: NSObject, UITableViewDataSource {
var countries = [Country]()
var filteredCountries = [Country]()
var dataChanged: (() -> Void)?
var tableView: UITableView!
let searchController = UISearchController(searchResultsController: nil)
var filterText: String? {
didSet {
filteredCountries = countries.matching(filterText)
self.dataChanged?()
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredCountries.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let country: Country
country = filteredCountries[indexPath.row]
cell.textLabel?.text = country.name
return cell
}
}
As you can see there is already a filtering mechanism in place.
Here is the most relevant part of the view controller:
class ViewController: UITableViewController, URLSessionDataDelegate {
let dataSource = CountryDataSource()
override func viewDidLoad() {
super.viewDidLoad()
dataSource.tableView = self.tableView
dataSource.dataChanged = { [weak self] in
self?.tableView.reloadData()
}
tableView.dataSource = dataSource
// Setup the Search Controller
dataSource.searchController.searchResultsUpdater = self
dataSource.searchController.obscuresBackgroundDuringPresentation = false
dataSource.searchController.searchBar.placeholder = "Search countries..."
navigationItem.searchController = dataSource.searchController
definesPresentationContext = true
performSelector(inBackground: #selector(loadCountries), with: nil)
}
The loadCountries is what fetches the JSON and load the table view inside the dataSource.countries and dataSource.filteredCountries array.
Now, how can I get the indexed collation like the Contacts app has without breaking all this?
I tried several tutorials, no one worked because they were needing a class data model or everything inside the view controller.
All solutions tried either crash (worst case) or don't load the correct data or don't recognise it...
Please I need some help here.
Thank you
I recommend you to work with CellViewModels instead of model data.
Steps:
1) Create an array per word with your cell view models sorted alphabetically. If you have data for A, C, F, L, Y and Z you are going to have 6 arrays with cell view models. I'm going to call them as "sectionArray".
2) Create another array and add the sectionArrays sorted alphabetically, the "cellModelsData". So, The cellModelsData is an array of sectionArrays.
3) On numberOfSections return the count of cellModelsData.
4) On numberOfRowsInSection get the sectionArray inside the cellModelsData according to the section number (cellModelsData[section]) and return the count of that sectionArray.
5) On cellForRowAtindexPath get the sectionArray (cellModelsData[indexPath.section]) and then get the "cellModel" (sectionArray[indexPath.row]). Dequeue the cell and set the cell model to the cell.
I think that this approach should resolve your problem.
I made a sample project in BitBucket that could help you: https://bitbucket.org/gastonmontes/reutilizablecellssampleproject
Example:
You have the following words:
Does.
Any.
Visa.
Count.
Refused.
Add.
Country.
1)
SectionArrayA: [Add, Any]
SectionArrayC: [Count, Country]
SectionArrayR: [Refused]
SectionArrayV: [Visa]
2)
cellModelsData = [ [SectionArrayA], [SectionArrayC], [SectionArrayR], [SectionArrayV] ]
3)
func numberOfSections(in tableView: UITableView) -> Int {
return self.cellModelsData.count
}
4)
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let sectionModels = self.cellModelsData[section]
return sectionModels.count
}
5)
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let sectionModels = self.cellModelsData[indexPath.section]
let cellModel = sectionModels[indexPath.row]
let cell = self.sampleCellsTableView.dequeueReusableCell(withIdentifier: "YourCellIdentifier",
for: indexPath) as! YourCell
cell.cellSetModel(cellModel)
return cell
}
I have a tableView on mainStoryboard with two custom cells.
I would like to set two more cells at different row. I was trying to find the answer but could not find out.
I have image and code added below.
class HomeViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, MFMailComposeViewControllerDelegate {
#IBOutlet var tblStoryList: UITableView!
var array = PLIST.shared.mainArray
override func viewDidLoad() {
super.viewDidLoad()
//spacing between header and cell
self.tblStoryList.contentInset = UIEdgeInsetsMake(-20, 0, 0, 0)
//delete separator of UITableView
tblStoryList.separatorStyle = .none
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.array.count + 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "HeaderCell", for: indexPath) as! HeaderCell
cell.headerTitle.text = "First Stage"
return cell
}
let cell = tableView.dequeueReusableCell(withIdentifier: "StoryTableviewCell", for: indexPath) as! StoryTableviewCell
//making plist file
let dict = self.array[indexPath.row - 1]
let title = dict["title"] as! String
let imageName = dict["image"] as! String
let temp = dict["phrases"] as! [String:Any]
let arr = temp["array"] as! [[String:Any]]
let detail = "progress \(arr.count)/\(arr.count)"
//property to plist file
cell.imgIcon.image = UIImage.init(named: imageName)
cell.lblTitle.text = title
cell.lblSubtitle.text = detail
cell.selectionStyle = UITableViewCellSelectionStyle.none
return cell
}
Update your conditions for HeaderCell and use ternary operator to set headerTitle
if indexPath.row == 0 || indexPath.row == 3 || indexPath.row == 5 {
let cell = tableView.dequeueReusableCell(withIdentifier: "HeaderCell", for: indexPath) as! HeaderCell
cell.headerTitle.text = indexPath.row == 0 ? "First Stage" : indexPath.row == 3 ? "Second Stage" : "Third Stage"
return cell
}
Instead of using Stages as a row, use them as a section header. You can put custom view in header section.
Main Idea :
section-ize your row along with stages, put the cell's data in an array and add them in a dictionary with the section value as their key. To visualise your case the dictionary will look like following.
#{
#"First Stage" : #[object_for_basic_grammar_1,
object_for_basic_grammar_2
],
#"Second Stage": #[object_for_basic_grammar3],
...
...
}
And Another array is needed to store the order of the dictionary keys, which will visualise to following
#[#"First Stage", #"Second Stage"
]
Now step by step follow the list:
Use numberOfSections(in:) for providing that how many stages here. return the count of the array which stores the sections.
Use tableView(_:numberOfRowsInSection:) for providing the number of rows in that section. get the section string object from the section list array declared later and search for the rows in the dictionary. You'll find a array of grammars here, return the count of that array.
Use tableView(_:cellForRowAt:) for providing the particular cell for that row as you've done for the grammar's cell.
Use tableView(_:heightForHeaderInSection:) for providing the height for the section header.
Now implement tableView(_:viewForHeaderInSection:) and return the view for specifying the section view, which in your case is the stages.
hope it helps you, best of luck.
I am creating an app where it uses custom cells. I also have these UITextView's where if you input a word, that word should then go to one of the four labels I created in the custom cell. I am still coding it however I got an error saying "Error: Index Out of Range".
Here is the code, and I also commented where it is giving that error
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) ->
UITableViewCell{
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! TableView
cell.lbl.text = todolist[indexPath.row]
cell.lbl2.text = todolist2[indexPath.row] // This is the error code
cell.lbl3.text = todolist3[indexPath.row]
cell.lbl4.text = todolist4[indexPath.row]
return cell
}
Here is where I append my texts
#IBAction func ClickedforSelection(sender: AnyObject) {
todolist.append(txt.text!)
todolist2.append(txt1.text!)
todolist3.append(txt2.text!)
todolist4.append(txt3.text!)
self.view.endEditing(true)
txt.text = ""
txt1.text = ""
txt2.text = ""
txt3.text = ""
NSUserDefaults.standardUserDefaults().setObject(todolist, forKey: "list")
NSUserDefaults.standardUserDefaults().setObject(todolist2, forKey: "list2")
NSUserDefaults.standardUserDefaults().setObject(todolist3, forKey: "list3")
NSUserDefaults.standardUserDefaults().setObject(todolist4, forKey: "list4")
Here is my NumberofRowsInSection
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return todolist.count
}
I have a conjecture that it may be the reuse of indexPath.row. Any solution?
If numberOfRowsInSection is returning todolist.count, you are accessing todolist2 in your cell. If todolist has 2 items and todolist2 has 1 item, it will do this because you are trying to access an item in a list that doesn't exist. Put a breakpoint at the first call of cell.lbl.text and check each array (todolist, todolist1, etc...). You should see that todolist2 does not have have a record at whatever "row" it's calling. If that is the case, you should just test it prior to calling it. (verify todolist2.count has enough items in it - or better yet, change the code to not have 4 arrays tracking 1 row (convert to a struct of some type with all 4 values, or something similar).
First, change the following code by commenting out lines:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) ->
UITableViewCell{
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! TableView
cell.lbl.text = todolist[indexPath.row]
// cell.lbl2.text = todolist2[indexPath.row] // This is the error code
// cell.lbl3.text = todolist3[indexPath.row]
// cell.lbl4.text = todolist4[indexPath.row]
return cell
}
And test to verify existing code (should work but of course it will not update the labels.)
Then add code to print the number of items in each array:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) ->
UITableViewCell{
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! TableView
cell.lbl.text = todolist[indexPath.row]
// cell.lbl2.text = todolist2[indexPath.row] // This is the error code
// cell.lbl3.text = todolist3[indexPath.row]
// cell.lbl4.text = todolist4[indexPath.row]
print("Row: \(indexPath.row)")
print("List 1: \(todolist.count)") //this will print to the console
print("List 2: \(todolist2.count)")
print("List 3: \(todolist3.count)")
print("List 4: \(todolist4.count)")
return cell
}
What you will likely see is that they don't have the same number of items, and as soon as it his a "row" that is equal to or greater than the number of items, it will break. Remember that Row's start at Zero, while count starts at 1.
If this is what you find, then there is problem something wrong with the code where you are adding the values to the todolist arrays. If you want to see how to convert that to a struct, I can post that for you.
Converting to struct
The code that is executing when something is clicked:
#IBAction func ClickedforSelection(sender: AnyObject) {
shows that a value is written to each of the 4 todolists every time. While I don't have the full requirements, if this is what you want to do, then you could implement a struct. Put this code in it's own ToDoList.swift file (ideally):
struct ToDoListItem {
var listItem: String?
var list1Item: String?
var list2Item: String?
var list3Item: String?
}
Then replace where you define your todolislt arrays (all 4 of them) with a single:
var listItems = [ToDoListItem]() //creates an array of ToDoListItems and initializes it with no values
Then in the ClickedForSelection function, change it to:
let listItem = ToDoListItem(listItem: txt.text, list1Item: txt1.text, list2Item: txt2.text, list3Item: txt3.text)
listItems.append(listItem) //add it to your array
//todolist.append(txt.text!)
//todolist2.append(txt1.text!)
//todolist3.append(txt2.text!)
//todolist4.append(txt3.text!)
self.view.endEditing(true)
txt.text = ""
txt1.text = ""
txt2.text = ""
txt3.text = ""
// This routine will need to be updated. Leaving that for you to figure out :)
// NSUserDefaults.standardUserDefaults().setObject(todolist, forKey: "list")
// NSUserDefaults.standardUserDefaults().setObject(todolist2, forKey: "list2")
// NSUserDefaults.standardUserDefaults().setObject(todolist3, forKey: "list3")
// NSUserDefaults.standardUserDefaults().setObject(todolist4, forKey: "list4")
...then numberOfRowsInSection changes to:
return listItems.count
...then cellForRowAtIndexPath changes to:
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! TableView
let listItem = listItems[indexPath.row]
cell.lbl.text = listItem.listItem ?? "" // Since listItems.listItem is an optional value, ?? unwraps it safely. If it is nill, it uses "" instead
cell.lbl2.text = listItem.list1Item ?? ""
cell.lbl3.text = listItem.list2Item ?? ""
cell.lbl4.text = listItem.list3Item ?? ""
return cell
Again...I would strongly consider how you are storing a value for a todolist for all 4 lists every time (if it is a todo list app, it seems like this may not be ideal?)
I would like to show all the values of this loop in the tableview. The code is to calculate an Amortization Table for loans. I tried saving the data of the loop in the array, but it always gives me the last values. I really got stuck on this. So how can I do that, please? This is my code:
import UIKit
class tableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet var tableView: UITableView!
var arr = [Int]()
var cell:tableCell!
var TPayment: float_t! // calls value of 59600 from main controller
var years1: float_t! // number of months = 180 ( 15 years)
var monthlyPayment: float_t! // 471
var interest: float_t! // 5%
var principil: float_t! //222
var interestrate: float_t! // 249
var initil: float_t!
var data = Array<float_t>()
var data2: NSMutableArray = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
let c = Int(years1)
arr += 0...c
tableCalculation()
// Register custom cell
let nib = UINib(nibName: "table", bundle: nil)
tableView.registerNib(nib, forCellReuseIdentifier: "cell")
}
func tableCalculation() {
let years = Int(years1)
initil = TPayment - 0
for i in 0..<years {
initil = initil - principil
interest = initil * interestrate
principil = monthlyPayment - interest
print("Month : \(monthlyPayment), principil: \(principil),interest: \(interest), initi: \(initil)")
data = [interest]
self.data2 = [initil]
}
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arr.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! tableCell
cell.lbl1.text = "\(arr[indexPath.row])"
cell.lbl2.text = "\(monthlyPayment)"
cell.lbl3.text = "\(data[indexPath.row % data.count])"
cell.lbl4.text = "\(principal)"
cell.lbl5.text = "\(self.data2[indexPath.section])"
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("Row \(indexPath.row) selected")
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 40
}
}
Table View with UITableView
Table view with print()
The main issue is with your data array.
In your loop where you populate your data array, in tableCalculation, there's this:
data = [interest]
It means that for each iteration you set the data array to [interest] instead of appending the new item to the array.
What you should do instead:
data.append(interest)
Note that you make the same mistake with self.data2. But now you know how to fix this kind of error.
In the cellForRowAtIndexPath method you are giving the same data to print that looks like the issue
I don't get much for all the labels but you can change it based on the requirement
for lbl2 and lbl4 you are passing a same single float variable for all the rows that's why it show the same value, if you want to show the different value for each row you should store it in array and at cellForRowAtIndexPath get it like you are doing for lbl1
cell.lbl2.text = currencyFormatter(monthlyPayment)
cell.lbl4.text = currencyFormatter(principil)
for lbl5 Your code cell code should be like this
cell.lbl5.text = "\(self.data2[indexPath.row])"
For the lbl 3 & lbl 5 when i execute this code with static value to get interest it only stores one value in the array
for i in 0..<years {
let interest = 5.0 * 4.0
data = [interest]
}
to store every value you calculated in array you should use append
data.append(interest)
self.data2.append(initil)
as there is only 1 value in the array for every index path it gives 0th value in the array as per your modulo operation so it shows same value in each row