Xcode tables refresh on button click - swift

I have a table which is populated with JSON. It works as a calendar. When the date is clicked, the table below should be populated with the events for that day.
These populate the tables after the data has been found but only does it once.
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return(GlobalVar.TodaysEvents.count)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "eventCell", for: indexPath) as! WhitelistTableViewCell
cell.startTime.adjustsFontSizeToFitWidth = true
print(GlobalVar.TodaysEventsTimes[indexPath.row])
cell.startTime.text = (GlobalVar.TodaysEventsTimes[indexPath.row] as! String)
cell.Summary.text = GlobalVar.TodaysEvents[indexPath.row] as? String
return(cell)
}
I have seen other posts like this and they use:
self.tableView.reload()
However, when i try this, it doesn't recognise "tableView" and simply doesn't work.
Any advice would be appreciated, thanks in advance

create a reference to your tableView ( New Referencing Outlet ) and then do this :
yourTableView.reloadData()

I don't know where you are reload the tableview but i think you reload the table view at different thread. That's why please reload the table view after inserting the data in array.

Related

Textfield values deleted when scrolling tableview?

I have tableview cell with a textfield but when I add new row and scroll tableview up or down disappeared textfield values deleted. I make lots of research about that previous question about that in 2015 and its not answered correctly. How can I fix this issue? How can I use textfield delegate method if it is working for this? Here my code:
var i = 0
while i <= taskArrForRead.count {
let indexPath = IndexPath(row: i, section: 0)
let cell = self.tableView.cellForRow(at: indexPath) as? taslakDuzenlemeCell
if let item = cell?.taslakTextField.text! {
arrayOfNames.append(item)
}
i = i + 1
}
In this code I get all textfield values from tableview but if tableview scroll disappeared values turn with default values. How can I fix it? Thanks.
Here my tableview code:
extension taslakOlusturmaController: UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return taskArrForRead.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "taslakCell", for: indexPath) as! taslakDuzenlemeCell
cell.taslakTextField.text = taskArrForRead[indexPath.item]
cell.taslakTextField.delegate = self
return cell
}
func textFieldDidEndEditing(_ textField: UITextField) {
print(textField.text!)
self.arrayOfNames.append(textField.text!)
}
func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let cell = tableView.dequeueReusableCell(withIdentifier: "taslakCell", for: indexPath) as! taslakDuzenlemeCell
cell.taslakTextField.text = taskArrForRead[indexPath.item]
print(arrayOfNames[indexPath.item])
}
}
With textfield delegate method I can get deleted textfield values but I can't bring it again to textfield. User can't see value after scroll again also I can get deleted values with didEndDisplaying cell method too.
You could use the method PrepareForReuse to set the text back when the cell recreated again.

Saving Data in UITableview

I have an app whereby a user can add books to a favourites list, by populating a tableview. Details on the book are displayed in a view and by tapping a 'favourites', a segue is performed inputting info on that book into a tableview cell.
At present only one book can appear in the table at a time adding a new book will remove the initial entry (so in effect only the first cell of the tableview is ever used)
Is there a way to save each entry in the tableview so in effect a list of favourites is created
saveButton
#IBAction func saveButton(_ sender: Any) {
let bookFormat = formatLabel.text
if (bookFormat!.isEmpty)
{
displayMyAlertMessage(userMessage: "Please Select a Book Format")
return
}
else{
self.performSegue(withIdentifier: "LibViewSegue", sender: self)
}
}
TableView
extension LibrarybookViewController: UITableViewDataSource, UITableViewDelegate{
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 115
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print(#function, dataSource.count)
return dataSource.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
print(#function, "indexPath", indexPath)
guard let bookCell = tableView.dequeueReusableCell(withIdentifier: "libCell", for: indexPath) as? LibrarybookTableViewCell else {
return UITableViewCell()
}
let libbook = dataSource[indexPath.row]
bookCell.cellTitleLabel.text = libbook.title
bookCell.cellReleaseLabel.text = libbook.release
bookCell.cellFormatLabel.text = bookFormat
return bookCell
}
I have been reading about defaults and CoreData but I'm not sure whether this should be implemented within the segue button action or within the tableview functions?
I see you have a dataSource array which contains list of books. At the simplest you could just append data to your dataSource, then reload your UITableView. But if you want persistent storage, you could look into local db solutions like SQLite, CoreData, or Realm. Then it would just be the matter of storing -> get data -> display on UITableView.
The general idea would be on add button tap (or whatever event listener you want to attach the action to), save it to persistent storage, reload your tableView, since the dataSource is from persistent storage, it'll update automatically. Suppose you load the data from persistent storage.
Also, don't store your array in UserDefaults, it's for bite sized data for things like user session etc.
Edit: as #Leo Dabus point out, indeed you can insert row without reloading the tableView by using
let index = IndexPath(row: items.count - 1, section: 0) // replace row with position you want to insert to.
tableView.beginUpdates()
tableView.insertRows(at: [index], with: .automatic)
tableView.endUpdates()

How to load tableview dynamically in swift 4

I have used Worm Tab Strip cocoapod to get tabs like android, the name of tabs are from server response, I need n number of view controllers based on the number of tab names.
For testing purpose, I have hardcoded tab names, and for each particular tab name, I have another array of sub names. My question is how do I change the tableview contents so that, I get an exact number of sub names according to the tab names
var tabNames = ["Brands", "Sports","Movies", "Mobile","Games"]
var brandsNames = ["Addidas", "Nike","Puma"]
var sportsName = ["Cricket","Fifa","Hockey","Baseball"]
var moviesName = ["Mission Impossible","Matrix","Avatar","Titanic"]
var mobileNames = ["Nokia","Redmi","Samsung"]
var gameNames = ["FIFA 19","PES 19","WWE 2K19","Max Payne"]
What should i try in
func tableView(_ tableView: UITableView, numberOfRowsInSection
section: Int) -> Int {
// return fruits.count
}
And
func tableView(_ tableView: UITableView, cellForRowAt indexPath:
IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell",
for: indexPath) as! Cell1
//cell.textLabel?.text = fruits[indexPath.row]
return cell
}
I need to get for Brands tab, I need brandsNames as tableview
contents.
The tableview contents must change according to the tab names.
Create a custom struct as data model for example
struct Category {
let name : String
let items : [String]
}
Declare a data source array and an index
var categories = [Category]()
var index = 0
In viewDidLoad populate the data source array and set index of the current index of the UISegmentedControl
categories = [Category(name:"Brands", items: ["Addidas", "Nike","Puma"]),
Category(name:"Sports", items: ["Cricket","Fifa","Hockey","Baseball"]),
Category(name:"Movies", items: ["Mission Impossible","Matrix","Avatar","Titanic"]),
Category(name:"Mobile", items: ["Nokia","Redmi","Samsung"]),
Category(name:"Games", items: ["FIFA 19","PES 19","WWE 2K19","Max Payne"])]
index = // current index of the segmented control
in the IBAction of the segmented control set the index and reload the table view
#IBAction func categorySelection(_ sender: UISegmentedControl) {
index = sender.selectedSegmentIndex
tableView.reloadData()
}
The data source methods are
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return categories[index].items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! Cell1
cell.textLabel?.text = categories[index].items[indexPath.row]
return cell
}
I used this enter link description here as a reference So that I can pass ID of particular tab to tableview in viewcontroller and load that Tablview, So now I can dynamically add new tabs and the corresponding Tablview also changes

Tableview creates five rows on one row?

I have a tableView with a custom cell that I have told should give me 5 cells in return of this custom cell. The question now is that I am running the app and getting five rows on one row. I have changed from default size of cell to custom but that is nearly the only thing I have done. So now I wonder what can create this kind of problem?
The code of my tableView looks like this.
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "theoryCell") as! theoryTVC
return cell
}
So the problem is you are using custom cell with custom height but you are not setting height for row in table view method.
Try this:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
return 100.0 //Choose your custom row height
}

TableView on simulator is not referencing correctly

Hello and how is everyone?
When I run the simulation of my application I go to select the first object in the table. Nothing happens. I then go and select the second object and it performs the action that the first object was supposed to. Basically the first object is not active until I select it and then select another object.
Maybe this will help:
I turn the simulator on. I select the first object nothing happens(I have a print("what row I selected") within the didSelect function to make sure it is working.). But again no printout until I hit the second object, the second object should print #1 row selected but it says #0 row selected and then performs the segue setup for 0#. After I come back from the segue the first object still performs the same.
Here is my tableView Code:
var objects: NSMutableArray! = NSMutableArray()
override func viewDidLoad() {
super.viewDidLoad()
self.objects.addObject("help")
self.objects.addObject("me")
self.objects.addObject("please")
self.objects.addObject("thankyou")
self.tableView.reloadData()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print(self.objects.count)
return self.objects.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! TableViewCell
cell.titleLabel.text = self.objects.objectAtIndex(indexPath.row) as? String
return cell
}
func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
print("You selected cell #\(indexPath.row)!")
Thanks for the help.