How can I ignore the first item in an array when display in a TableView?
What I want is to ignore the first item when presented in a UITableView, I DON'T want remove it just not show it in the TableView.
The following code show all items from the array in the TableView.
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return lists.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "listCell", for: indexPath)
let data = lists[indexPath.row]
cell.textLabel!.text = data.listName
return cell
}
Your data source methods are using lists as their basis, and you don't want to do anything that mess that up. The numberOfRowsInSection and the cellForRowAt need to stay in sync.
I can think of two possibilities:
Keep the real model elsewhere, and keep in lists only the part of the model that you want to include in the table.
Or (a whole different approach) implement heightForRowAt to give the undesired row a zero height.
Related
Im a complete beginner to swift and iOS and I'm trying to write some code which will take some json and put it into an array of objects and then use that array to populate the tableview.
The problem is when I try to populate the tableview it just prints the first one so it looks like this:
here is the code
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "comicCell", for: indexPath) as! ComicCell
cell.title.text = comics?[indexPath.row].title
cell.dateOnSale.text = comics?[indexPath.row].dateOnSale
return cell
}
I tried to print the array of objects in a simple for loop and it works fine which led me to believe my problem is in the function above
The cellForRowAt method seems OK, I think you're having trouble with the numberOfSections and numberOfRowsInSection methods of tableView, the former must return 1 and the latter must return comics.count in your case.
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return comics.count
}
Hello,
i have created a UITableView in which it has two different cells DynamicFormCell and StaticFormCell, so the DynamicFormCell can be displayed number of times i have a data from a server telling me how many forms i need for the DynamicFormCell and the StaticFormCell is always the same and doesn't change so i am having difficulty giving different number of rows for each cell.i tried giving the two cell a tag of 0 and 1 respectively and used this code:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if(tableView.tag == 0){
return 5//return five dynamic cells
}
if(tableView.tag == 1){
return 1//return one static cell
}
}
but this doesn't work and i also tried removing all the tags and if statements in the above code and just doing this return 5 this just gave me one DynamicFormCell and five StaticFormCells.
i also gave different classes for the two cells so i can assign them separately:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if(indexPath.row == 0){
//firstRow make dynamic
let cell = tableView.dequeueReusableCell(withIdentifier: "DynamicFormsCell") as! DynamicFormsCell
return cell
}else{
//static form data
let cell = tableView.dequeueReusableCell(withIdentifier: "StaticFormsCell") as! StaticFormsCell
return cell
}
}
so my question is, is it possible to do this using table views and how can i do it? if not what other options do i have?
Yes it is possible to have multiple types of cell in single tableview. It has nothing to do with function
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
You should return there cells as,
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (count of dynamic cells + count of static cells)
}
I assume, you only have to display static cells in the bottom. So if there are total 5 cells then 4 cells are dynamic and 5th cell would be static.
So code for, cellForRowAt indexPath: will be,
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if(indexPath.row < (count for dynamic cells)){
//first 4 Rows make dynamic
let cell = tableView.dequeueReusableCell(withIdentifier: "DynamicFormsCell") as! DynamicFormsCell
return cell
}else{
//last row static form data
let cell = tableView.dequeueReusableCell(withIdentifier: "StaticFormsCell") as! StaticFormsCell
return cell
}
}
What you're doing right now is checking if the TableView's tag is 0 or 1. Which is not you want to do, since you're using only one TableView.
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (amount of DynamicCellsYouWant + amount of StaticCellsYouWant)
}
The second part of your code only works when you want the first cell to be a DynamicFormsCell and the rest to be a StaticFormsCell.
I have a list of custom objects [Species] displayed in the table view, which is sorted alphabetically. Table has one section with no headers, it's one continuous list.
What I would like to achieve is, when a user selects the option to sort the data "by country", to do the following:
to sort array to find out how many sections I will need by - "Species.country"
to create sections with header titles of the country
to sort countries (Sections) alphabetically
reload table view to display sections
remove sections on the reversed action (sort entire list A-Z)
Is it possible to create dynamically sections when filtering/sorting? Can you please point me the right direction? Many thanks
A.
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 120
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.genusArr.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: CustomMenuCell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomMenuCell
//genusArr is type of [Species]
let genus = self.genusArr[indexPath.row]
cell.populate(with: genus)
return cell
}
It's all in your data model. You always have sections with rows. But you only have one section. Modify your data model and your data source methods to always support multiple sections. Just sometimes this data model will only have one section.
Update your data model to be an array of dictionary where the dictionary contains a title and an array. The top level array is your sections (may just be one at times). The inner arrays (in each dictionary) are the rows of each section. Or define a struct with a title and array instead of using a dictionary.
With this in place, and your table view data source and delegate methods written to always work with multiple sections, your table will also work just fine when you happen to have just one section worth of data.
Now it's just a matter of populating your array of dictionary as needed depending on how you wish to organize the data for display.
To answer the question of section headers. You could try using:
tableView(_ tableView: UITableView, titleForHeaderInSection section: Int)
or
tableView(tableView: UITableView, viewForHeaderInSection section: Int)
I have two table views containing data, the first one is completely okay. I want to push from this table view to another view to another table view, but I cannot set the rows for it. How can I navigate through a multidimensional array in
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
Basically, my problem is about setting the right text for a row and getting from a multidimensional array :) (P.S. I have a different number of Strings in each subarray)
You just need to check on which tableView you are setting the values.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
if tableView == myFirstTableView {
// put the data for the first tableView
} else {
// put the data for the second tableview
}
}
i have the dictionary - dictTime: [Int:[Int]] and I'd like to show it in tableView in cell.
To show key in every cell - not a problem, but I'd like to show every element of value of dictionary in "own" UILabel, so I created [UILabel] and understand that count of UILabel in array must be equal count of elements in value of dictionary, but how to do it in func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell for showing for every row (row - it's key-[value])?
Assuming your dictionary is like [Int1: [Int2]], that means:
dictTime.allKeys will give you array of all Int1
dictTime[Int1] will give you respective [Int2]
Example:
var dictTime = [1: [1,2], 2: [2,3], 3: [3,4]]
For showing these in a tableView:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dictTime.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("MyCell", forIndexPath: indexPath)
let keys = Array (dictTime.keys)
cell.textLabel?.text = String (keys[indexPath.row])
cell.detailTextLabel?.text = String (dictTime[indexPath.row])
return cell
}
In func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell call an other function and pass your dictionary value to that function for example [1,2,3] also pass your tbaleviewcell to that function. Now in that function run a loop on your dictionary array [1,2,3] and one by one UILabel into your tableviewcell programmatically.
I am not sure I understand the problem. If you want to have as many rows as dictionary entries, use the following:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dictTime.count
}
If you want to have as many labels in your cell, as entries for each key in your dictionary, you need to implement a complicated solution.
I would suggest creating a "super cell" which has the maximum amount of labels, put them in a stach view, and hide them according to the number of entries.