Duplicates in tableview section Swift - swift

I amm trying to put some datas into categories into a tableView. Pizzas into pizza category, burgers into burger etc, but i have every item duplicate ( Look here Picture . What can be the problem ?
Struct :
struct Food {
var photoKeyRestaurant: String
var foodName: String
var foodDescription: String
var restaurantName: String
var priceFood: Int
var typeFood: String
}
Table View
func numberOfSections(in tableView: UITableView) -> Int {
return food.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return food[section].foodName.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "FoodTableViewCell", for: indexPath) as! FoodTableViewCell
// cell.delegate = self
let mancare = food[indexPath.section]
let storageRef = Storage.storage().reference()
let photoRef = storageRef.child(mancare.photoKeyRestaurant)
cell.foodImage.sd_setImage(with: photoRef)
cell.descriptionLabel.text = mancare.foodDescription
cell.foodNameLabel.text = mancare.foodName
cell.priceLabel.text = "\(mancare.priceFood) lei"
cell.foodImage.layer.borderWidth = 1
cell.foodImage.layer.masksToBounds = false
cell.foodImage.layer.borderColor = UIColor.black.cgColor
cell.foodImage.layer.cornerRadius = cell.foodImage.frame.height/2
cell.foodImage.clipsToBounds = true
//Fac ca imaginea sa fie cerc - finish
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 120
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return food[section].typeFood
}
If somone will ask, im retrieving the data from the firestore, but there s no problem there, because the data is retrieved succesfuly.
Anyone know what can be the problem ? Thanks

It is interesting that your code for cellForRowAt never actually mentions the indexPath.row. It refers only to the indexPath.section. How can you get and display data corresponding to this row, which you are supposed to configure in cellForRowAt if you do not in some way refer to the question of what row this is?
Perhaps there is some other mechanism going on that I don't see, but it seems to me that this one fact alone explains why each section just shows the same data over and over rather than different data for each row.

You have 2 big problems with this code.
You have the wrong array of data fo sections.
in the func cellForRowAt you cant return indexPath.section.
With first. You need to use 2-dimensional arrays like:
var foodCategorys: [FoodCategory] = [[categoryName, Food],[categoryName, Food]]
So you need another struct to contain this 2-dimensional array:
struct FoodCategory {
var categoryName: String
var listFood: [Food] = [] // Food is the struct that you currently have
}
So the data will display in tableView is an array FoodCategory. With numberOfSections will return a count of an array FoodCategory. And numberOfRowsInSection will return a count of a listFood into FoodCatogory.
func numberOfSections(in tableView: UITableView) -> Int {
return foodCategorys.count //array of listFood
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return foodCategorys[section].listFood.count
}
And second, in cellForRowAt, when you want to get the index of list data. you need to call foods[indexPath.section].listFood[indexPath.row]. The func need row not section
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "FoodTableViewCell", for: indexPath) as! FoodTableViewCell
//cell.delegate = self
let mancare = foods[indexPath.section].listFood[indexPath.row] //Remeber that, the array food we are using in this line is array of FoodCategory
I think you need to research with key word "section in uitableview swift", or watch this video https://www.youtube.com/watch?v=AHY09z-XS9s
So, that all. I hope you will understand how tableview and section work

Related

How to display multiple attributes in a single table view? Swift

I want to display three different entitys from core data on a table view. I can do this with one entity and tried to carry that logic over to displaying three on the same table view. I used the same entity in the code below to test this. I am getting blank sections in my table view. I must have the cellForRowAt method wrong? Here is my code.
var word: [NSManagedObject] = []
let sections = ["Custom Library", "Mastered Words", "Library"]
var array = [
[NSManagedObject](),
[NSManagedObject](),
[NSManagedObject]()
]
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell2")
array = [
word,
word,
word
]}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return array[section].count
}
func numberOfSections(in tableView: UITableView) -> Int {
sections.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return self.sections[section]
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let customWord = array[indexPath.row][indexPath.section]
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell2", for: indexPath)
cell.textLabel?.text = customWord.value(forKeyPath: "title") as? String
return cell
Based on the code you've shown, your array property is an array of empty arrays as word is an empty array itself. If you're using array to determine the number of rows in each section based on the array at that section index, then you're going to get 0 rows for each section.

Swift calling a class from a view controller

I am a beginner in swift coming from java. I have a task class and a taskcollection class where it is a collection of tasks. I am trying to put the collection into a table view but I dont know how.
This is task class:
class Task{
private var description : String
init(description: String){
self.description = description
}
func getDescription() -> String{
return self.description
}
func setDescription(description: String){
self.description = description
}}
This is taskCollection class:
class TaskCollection{
private var tasks: Array<Task>
init(){
self.tasks = [Task]()
}
func getTasks() -> Array<Task>{
return self.tasks
}
func addTask(task: Task){
self.tasks.append(task)
}}
To get the taskcollection into the tableview what do i do? In java I know I have to make something like new TaskCollection(), but i dont know how to get it in the tableviews:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return ?
}
// create a cell for each table view row
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// create a new cell if needed or reuse an old one
let cell:UITableViewCell = self.tableviewTasks.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as UITableViewCell!
// set the text from the data model
cell.textLabel?.text = self.___?_____[indexPath.row]
return cell
}
// method to run when table view cell is tapped
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("You tapped cell number \(indexPath.row).")
}
You would create an instance of the TaskCollection class somewhere in your ViewController file scope. Then you populate it somewhere else (I did this is viewDidLoad as an example). Number of rows will simply be the number of tasks in the taskCollection instance. You can access each task by using indexPath.row to get the index of the array of tasks.
class TableViewController: UITableViewController {
let taskCollection = TaskCollection()
override func viewDidLoad() {
super.viewDidLoad()
let task = Task(description: "Some Description")
taskCollection.addTask(task: task)
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return taskCollection.getTasks().count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
let task = taskCollection.getTasks()[indexPath.row]
cell.textLabel?.text = task.getDescription()
return cell
}
}
First there is no need to create a TaskCollection class as it's functionality is already build in arrays so, you need to create an array of tasks
var tasksArr = [Task]()
//
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.tasksArr.count
}
// create a cell for each table view row
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// create a new cell if needed or reuse an old one
let cell:UITableViewCell = self.tableviewTasks.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as UITableViewCell!
// set the text from the data model
cell.textLabel?.text = self.tasksArr[indexPath.row].description
return cell
}
OR according to current implementation
var colc = TaskCollection()
//
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.colc.tasks.count
}
// create a cell for each table view row
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// create a new cell if needed or reuse an old one
let cell:UITableViewCell = self.tableviewTasks.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as UITableViewCell!
// set the text from the data model
cell.textLabel?.text = self.colc.tasks[indexPath.row].description
return cell
}

How to add select from map option in tableViewCell, Google map, Swift

I am using google map on my current project. To search places when I click on a textField a tableView appear below and I am populating the cell with GMSAutocompletePrediction object. So far its working fine and no problem so far. Now I want to add a cell like "Select From Map", when someone tap one the cell a marker will appear in the map. I can able to put the marker and additional map feature but how can I add that last cell "Select From Map" ? My code below:
var myFilterPredictions = [GMSAutocompletePrediction]()
Then:
func didAutocomplete(with predictions: [GMSAutocompletePrediction]) {
self.myFilterPredictions.removeAll()
print("GMSAutocompletePrediction *********")
for i in predictions {
self.myFilterPredictions.append(i)
}
tableView.reloadData()
}
The populating the tableView
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myFilterPredictions.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style:.subtitle, reuseIdentifier:"searchCell")
let predictions = myFilterPredictions[indexPath.row]
cell.textLabel?.attributedText = predictions.attributedPrimaryText
cell.detailTextLabel?.attributedText = predictions.attributedFullText
return cell
}
My search result looks similar to the image below:
I want to add "Select from map" in the last cell.
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0{
return myFilterPredictions.count
}
else{
return 1
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = UITableViewCell()
if indexPath.section == 1{
cell.textLabel = ""Select From Map""
return cell
}else{
cell = UITableViewCell(style:.subtitle, reuseIdentifier:"searchCell")
let predictions = myFilterPredictions[indexPath.row]
cell.textLabel?.attributedText = predictions.attributedPrimaryText
cell.detailTextLabel?.attributedText = predictions.attributedFullText
return cell
}
}
You also use Group table for that
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
// Removes extra padding in Grouped style
return CGFloat.leastNormalMagnitude
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
// Removes extra padding in Grouped style
return CGFloat.leastNormalMagnitude
}

How to remove items from an array when deselecting a row in a UITableView

I'm trying to capture the selected items from a UITableView and save them into a new array. The following code creates the new array by adding the items when the rows is tapped, what it doesn't do is remove the items when the rows are deselected.
How can I remove items from the newFruitList when a row in a UITableView is deselected?
Or better yet, what is the proper way to generate an array of only the selected items in a UITableView?
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
let fruits = ["Apples", "Oranges", "Grapes", "Watermelon", "Peaches"]
var newFruitList:[String] = []
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return fruits.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = fruits[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
newFruitList.append(fruits[indexPath.row])
print("New List: \(newFruitList)")
}
#IBAction func makeSelection(_ sender: Any) {
tableView.allowsMultipleSelectionDuringEditing = true
tableView.setEditing(true, animated: false)
}
}
You can just check whether the newFruitList contains the item you want to add by getting index of that item in your list.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
newFruitList.append(fruits[indexPath.row])
print("New List: \(newFruitList)")
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
if let index = newFruitList.index(of: fruits[indexPath.row]) {
newFruitList.remove(at: index)
}
print("New List: \(newFruitList)")
}
It is pretty much the same as adding an element when you select a row:
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath {
newFruitList.remove(at: indexPath.row)
print("New List: \(newFruitList)")
}
You just have to use the didDeselectRowAt delegate method instead.
Update
As mentioned in the comments, this solution does not work since newFruitList does not necessarily have all of the original array elements. See the accepted answer instead.

How to find particular position object from array in swift 3

I inserted some objects in my below finalArray array. Now I want to display them in tableList so that each position object I need to find. How can I write that statement can some one help me please?
My code:-
var forcast:Forecast?
var finalArray = [Forecast]()
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
forcast = finalArray.index(indexpath);
}
NSIndexPath has section and row
You need to access based on the indexPath.section or indexPath.row based on how you are categorising your data on tableView with the use tableView datasource
Ex:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
forcast = finalArray.index(indexpath.row);//
}
Try this :
var finalArray = [Forecast]()
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let forcast = finalArray[indexPath.row]
}
CollectionTypes documentation
var row: Int
The value of the row element of the index path.
var section: Int
The value of the section element of the index path.
IndexPath documentation