There are two ViewControllers in the app. The first one has a WebView and a Navigation Bar on top, the second one is a TableView to show URLs visited. Please see screenshots and codes. After I clicked Save button to save current URL user is visiting, the TableView is empty. I have tested the TableView first, it is set up fine. Please help to find out the problem. By the way, var savedURLs = [String]( I didn't put the other half of bracket as it won't show correctly if I put it.)
import UIKit
class BrowserViewController: UIViewController {
#IBOutlet weak var browser: UIWebView!
#IBAction func saveButtonPressed(sender: AnyObject) {
if let currentURL = browser.request?.URL?.absoluteString {
savedURLs.append(currentURL)
NSUserDefaults.standardUserDefaults().setObject(savedURLs, forKey: "savedURLs")
}
}
override func viewDidLoad() {
super.viewDidLoad()
let url = NSURL(string: "https://www.google.com")!
let request = NSURLRequest(URL: url)
browser.loadRequest(request)
}
}
import UIKit
var savedURLs = [String](
class SavingViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var savingTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
savingTableView.delegate = self
savingTableView.dataSource = self
if NSUserDefaults.standardUserDefaults().objectForKey("savedURLs") != nil {
savedURLs = NSUserDefaults.standardUserDefaults().objectForKey("savedURLs") as! [String]
}
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return savedURLs.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("SavingCell")
cell!.textLabel?.text = savedURLs[indexPath.row]
return cell!
}
override func viewDidAppear(animated: Bool) {
savingTableView.reloadData()
}
}
Please check the currentURL is not nil. Because of empty currentURL your tableview is empty.
I suggest you to Saved the urls in NSuserdefault after webview loading finished completely. Hope this will help you.
I think you should add this function:
func reloadTable() {
if NSUserDefaults.standardUserDefaults().objectForKey("savedURLs") != nil {
savedURLs = NSUserDefaults.standardUserDefaults().objectForKey("savedURLs") as! [String]
}
savingTableView.reloadData()
}
And call that one instad of savingTableView.reloadData()
Also debug the code by printing the value of variables at some points. For example the new data when you read from NSUserDefaults and the value of savedURLs in viewDidAppear.
If that doesn't work make sure you're using the right cell identifier:
let cell = tableView.dequeueReusableCellWithIdentifier("SavingCell")
Try passing the data to the next view controller when you click on send button rather than using NSUserDefaults.
Maintain an array by appending the URLs that you visit, then pass it to the next view controller when you click on send.
Related
I am trying to create a program on Xcode that allows the user to enter multiple data into a table view through a text field (when a button is clicked). When the data is added I would like it to be stored and not be deleted after the app is closed - for this part I believe that I would have to use NSUserDefaults, however, I am unsure how I would save an array of strings? (I'm only familiar with storing a single string).
This is what my view controller currently looks like.
I have not done much on my view controller at all but this is what it currently has.
import UIKit
class NewViewController: UIViewController {
#IBOutlet weak var text: UITextField!
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
Let's tackle this step-by-step...
TL;DR - For your convenience, I've put the final code into a sample project on Github. Feel free to use any or all of the code in your apps. Best of luck!
Step 1 - Conform to UITableView Protocols
"...enter multiple data into a table view..."
At a minimum, UITableView requires you to conform to two protocols in order to display data: UITableViewDelegate and UITableViewDataSource. Interface Builder handles the protocol declaration for you if you use the built-in UITableViewController object, but in your case you cannot use that object because you only want the UITableView to take up a portion of the view. Therefore, you must implement the protocols yourself by adding them to ViewController's signature:
Swift 4
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
}
Step 2 - Implement UITableView Protocol Required Methods
Now that you have the protocols declared, Xcode displays an error until three required methods are implemented inside of your ViewController class. The bare minimum implementation for these methods is:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
return UITableViewCell()
}
You'll implement these methods later, but at this point your code should compile.
Step 3 - Connect UITableView's Protocols to ViewController
Since you are using a standard UITableView object, ViewController is not connected by default to the code you just implemented in the protocol methods. To make a connection, add these lines to viewDidLoad():
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
Alternatively, you could use the CONTROL + DRAG technique in Interface Builder to connect the delegate and data source from your UITableView to ViewController.
NOTE: In this case, self refers to the ViewController since you're inside of the ViewController class.
Step 4 - UITextField Setup
"...through a text field..."
You previously added an IBOutlet for your UITextField that is connected to Interface Builder, so there is nothing more to do here.
Step 5 - IBAction for the Add Button
(when a button is clicked)."
You need to add an IBAction to your ViewController class and connect it to your Add Button in Interface Builder. If you prefer to write code and then connect the action, then add this method to your ViewController:
#IBAction func addButtonPressed(_ sender: UIButton) {
}
If you use Interface Builder and the CONTROL + DRAG technique to connect the action, the method will be added automatically.
Step 6 - Add an Array Property to Store Data Entries
"...save an array of strings..."
You need an array of strings to store the user's entries. Add a property to ViewController that is initialized as an empty array of strings:
var dataArray = [String]()
Step 7 - Finish Implementing UITableView Protocol Methods
At this point you have everything you need to finish implementing UITableView's protocol methods. Change the code to the following:
//1
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//Do nothing
}
//2
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataArray.count
}
//3
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = dataArray[indexPath.row]
return cell
}
In the future, if you want to do something when the user taps a cell, you will want to add code to tableView(_:didSelectRowAt:).
You now create the same number of rows as the number of values in dataArray.
To make this work with Interface Builder, make sure you go to the Attributes Inspector for your UITableViewCell and set the Cell Identifier to Cell. Check out the documentation for more on Dequeuing Cells.
Step 8 - Finish Implementing addButtonPressed(_:)
As suggested in #dani's answer, in the action you need to implement code that appends the user's text to the array, but only if the text is not blank or empty. It is also a good idea to check if dataArray already contains the value you entered using dataArray.contains, depending on what you want to accomplish:
if textField.text != "" && textField.text != nil {
let entry = textField.text!
if !dataArray.contains(entry) {
dataArray.append(entry)
textField.text = ""
}
tableView.reloadData()
}
Step 9 - Persist Data with UserDefaults
"When the data is added I would like it to be stored and not be deleted after the app is closed."
To save dataArray to UserDefaults, add this line of code after the line that appends an entry inside of the addButtonPressed(_:) action:
UserDefaults.standard.set(dataArray, forKey: "DataArray")
To load dataArray from UserDefaults, add these lines of code to viewDidLoad() after the call to super:
if let data = UserDefaults.standard.value(forKey: "DataArray") as? [String] {
dataArray = data
}
Try the following:
Create an array that will store all the text entered via the UITextField (ie. var array = [String]()
In the action of that add button, append the text the user has entered in the text field to the array.
if text.text != "" && !text.text.isEmpty {
// append the text to your array
array.append(text.text!)
text.text = "" // empty the `UITextField`
}
In your tableView methods, make the numberOfRows return array.count and just add a UILabel for your custom UITableViewCell that will display each entered item from the array in a separate cell.
if you want to display your data in tableview you need to implement tableview delegates. add a table view cell with a label on it
#IBOutlet weak var text: UITextField!
#IBOutlet weak var tableView: UITableView!
let NSUD_DATA = "dataarray_store"
var dataArray : NSMutableArray!
var userDefault = UserDefaults.standard
override func viewDidLoad() {
super.viewDidLoad()
dataArray = NSMutableArray()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK:- create a button for adding the strings to array and while clicking that button
func onClickButton(){
let string = text.text
dataArray.add(string)
userDefault.set(dataArray, forKey: NSUD_DATA)
}
for getting array stored in userdefault
func getData() -> NSMutableArray?{
if userDefault.object(forKey: NSUD_DATA) != nil{
return userDefault.array(forKey: NSUD_DATA) as! NSMutableArray
}
return nil
}
class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
#IBOutlet weak var entertxt: UITextField!
#IBOutlet weak var save: UIButton!
#IBOutlet weak var tableview: UITableView!
var names = [String]()
override func viewDidLoad() {
super.viewDidLoad()
if let data = UserDefaults.standard.object(forKey: "todolist") as?[String]
{
names = data
}
}
#IBAction func submit(_ sender: Any) {
if entertxt.text != "" {
names.append(entertxt.text!)
UserDefaults.standard.set(names, forKey: "todolist")
tableview.reloadData()
entertxt.text = ""
}
else
{
print("data not found")
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return names.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! myTableViewCell
cell.namelable.text = names[indexPath.row]
return cell
}
I'm creating a quiz app with custom cells that include a label of questions and then an answer coming from a UISegmentedControl.
The values of the segmentedcontrols get changed when scrolling and this leads to an inaccurate score. I understand that this is due to UITableView reusing cells.
My tableview's datasource in my main vc is simply the labels for all my questions coming from a plist file.
The code for my custom tableviewcell class is
class QuestionsTableViewCell: UITableViewCell {
#IBOutlet weak var questionLabel: UILabel!
#IBOutlet weak var selection: UISegmentedControl!
var question: String = "" {
didSet {
if (question != oldValue) {
questionLabel.text = question
}
}
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
//Just for testing
#IBAction func segmentChanged(_ sender: UISegmentedControl) {
print("value is ", sender.selectedSegmentIndex);
}
}
where the View is stored in an .XIB file.
And the code for my main vc is
class ViewController: UIViewController, UITableViewDataSource {
let questionsTableIdentifier = "QuestionsTableIdentifier"
#IBOutlet var tableView:UITableView!
var questionsArray = [String]();
var questionsCellArray = [QuestionsTableViewCell]();
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let path = Bundle.main.path(forResource:
"Questions", ofType: "plist")
questionsArray = NSArray(contentsOfFile: path!) as! [String]
tableView.register(QuestionsTableViewCell.self,
forCellReuseIdentifier: questionsTableIdentifier)
let xib = UINib(nibName: "QuestionsTableViewCell", bundle: nil)
tableView.register(xib,
forCellReuseIdentifier: questionsTableIdentifier)
tableView.rowHeight = 108;
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return questionsArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(
withIdentifier: questionsTableIdentifier, for: indexPath)
as! QuestionsTableViewCell
let rowData = questionsArray[indexPath.row]
cell.question = rowData
return cell
}
#IBAction func calculate(_ sender: UIButton) {
var score = 0
for cell in tableView.visibleCells as! [QuestionsTableViewCell] {
score += cell.selection.selectedSegmentIndex
}
let msg = "Score is, \(score)"
print(msg)
}
#IBAction func reset(_ sender: UIButton) {
for cell in tableView.visibleCells as! [QuestionsTableViewCell] {
cell.selection.selectedSegmentIndex = 0;
}
}
}
What I'd like to do is just keep track of all 'selection' changes of the Questions cells in an array, and then use that array in cellForRowAt. I'm just confused as to how i can dynamically keep track of changes from a view in another class. I'm new to Swift and would like to solve this is a proper MVC fashion. Thanks
Instead of a simple string array as data source create a class holding the text and the selected index
class Question {
let text : String
var answerIndex : Int
init(text : String, answerIndex : Int = 0) {
self.text = text
self.answerIndex = answerIndex
}
}
Declare questionArray as
var questions = [Question]()
Populate the array in viewDidLoad with
let url = Bundle.main.url(forResource: "Questions", withExtension: "plist")!
let data = try! Data(contentsOf: url)
let questionsArray = try! PropertyListSerialization.propertyList(from: data, format: nil) as! [String]
questions = questionsArray.map {Question(text: $0)}
In the custom cell add a callback and call it in the segmentChanged method passing the selected index, the property question is not needed, the label is updated in cellForRow of the controller
class QuestionsTableViewCell: UITableViewCell {
#IBOutlet weak var questionLabel: UILabel!
#IBOutlet weak var selection: UISegmentedControl!
var callback : ((Int) -> ())?
#IBAction func segmentChanged(_ sender: UISegmentedControl) {
print("value is ", sender.selectedSegmentIndex)
callback?(sender.selectedSegmentIndex)
}
}
In cellForRow add the callback and update the model in the closure
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: questionsTableIdentifier, for: indexPath) as! QuestionsTableViewCell
let question = questions[indexPath.row]
cell.questionLabel.text = question.text
cell.selection.selectedSegmentIndex = question.answerIndex
cell.callback = { index in
question.answerIndex = index
}
return cell
}
To reset the segmented controls in the cells set the property in the model to 0 and reload the table view
#IBAction func reset(_ sender: UIButton) {
questions.forEach { $0.answerIndex = 0 }
self.tableView.reloadData()
}
Now you could calculate the score directly from the model instead of the view.
Don't try to use cells to hold information. As the user scrolls through your table view, cells that scroll out of view will get recycled and their field settings will be lost. Also, newly dequeued cells will have the settings from the last time they were used.
You need to refactor your code to read/write information into a data model. Using an array of Structs as a data model is a reasonable way to go. (Or, as vadian suggests in his answer, and array of Class objects, so you get reference semantics.)
You have an IBAction segmentChanged() in your custom cell class. The next trick is to notify the view controller when the user changes the selection, and to update cells when you set them up in cellForRowAt.
I suggest defining a protocol QuestionsTableViewCellProtocol, and have the view controller conform to that protocol:
protocol QuestionsTableViewCellProtocol {
func userSelected(segmentIndex: Int, inCell cell: UITableViewCell)
}
}
Add a delegate property to your QuestionsTableViewCell class:
class QuestionsTableViewCell: UITableViewCell {
weak var delegate: QuestionsTableViewCellProtocol?
//The rest of your class goes here...
}
Update your cell's segmentChanged() method to invoke the delegate's userSelected(segmentIndex:inCell:) method.
In your view controller's cellForRowAt, set the cell's delegate to self.
func userSelected(segmentIndex: Int, inCellCell cell: UITableViewCell) {
let indexPath = tableView.indexPath(for: cell)
let row = indexPath.row
//The code below assumes that you have an array of structs, `dataModel`, that
//has a property selectedIndex that remembers which cell is selected.
//Adjust the code below to match your actual array that keeps track of your data.
dataModel[row].selectedIndex = segmentIndex
}
Then update cellforRowAt() to use the data model to set the segment index on the newly dequeued cell to the correct index.
Also update your calculate() function to look at the values in your dataModel to calculate the score, NOT the tableView.
That's a rough idea. I left some details out as "an exercise for the reader." See if you can figure out how to make that work.
There's a button in another ViewController, if I press on it, I should see the time when I pressed on the button.
The button works, but the table won't refresh after I click on a refresh button, place the refresh on the ViewDidAppear function doesn't work as well.
I need to quit the app, close it from multitasking and open it again, then the time that I pressed on the button shows. What should I do to make the refresh button work?
(Both View Controllers are in the same storyboard, the second one extends the first one)
First View Controller:
class Tracking: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var activity: UITableView!
var activities = [String]()
var userData = false
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return activities.count
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "cell")
cell.textLabel?.text = activities[indexPath.row]
return(cell)
}
#IBAction func Reload(_ sender: AnyObject) {
activity.reloadData()
}
.
.
.
}
Second view controller:
class Activity: Tracking {
.
.
.
#IBAction func playButton(_ sender: AnyObject) {
isPlayed += 1
userData = true
UserDefaults.standard.set(userData, forKey: "userData")
let playElm = playStr + " בשעה: " + getTime()
activities.append(playElm)
UserDefaults.standard.set(activities, forKey: "activities")
}
.
.
.
}
You need to fetch from user defaults your new date in activities array and after that you can reloadData
#IBAction func Reload(_ sender: AnyObject) {
self.activities = UserDefaults.standard.get( forKey: "activities")
activity.reloadData()
}
When you call activity.reloadData(), you're telling the table view to update its rows and what they display based solely on the contents of your activities property that you defined with the line:
var activities = [String]()
When you're loading the app from a fresh start, that activities array of strings hasn't been filled with anything. I see you save data to UserDefaults, but I don't see anywhere from which you read it.
Put this next code in your viewDidLoad(). viewDidAppear() isn't what you want to use for this purpose.
activities = UserDefaults.standard.get(forKey: "activities")
activity.reloadData()
I managed to get this working automaticlly without the refresh button. The code that Svetoslav Bramchev wrote works when I place it in viewDidAppear. Thanks for your help!
override func viewDidLoad() {
super.viewDidLoad()
userData = UserDefaults.standard.bool(forKey: "userData")
if(userData == true){
activities = UserDefaults.standard.object(forKey: "activities") as! [String]
} else {
activities.append("no data")
UserDefaults.standard.set(activities, forKey: "activities")
if(activities[0] == "no data"){
activities.remove(at: 0)
UserDefaults.standard.set(activities, forKey: "activities")
}
}
}
override func viewDidAppear(_ animated: Bool) {
activities = UserDefaults.standard.object(forKey: "activities") as! [String]
activity.reloadData()
}
and thanks in advance for helping me out if you can. I'm still very new to Swift but looking forward to learning quickly so I can help others here on the forum.
For now, I have a problem that I need to solve and I have no idea where to start. Hypothetically, my goal is to achieve something like the following:
First View: User enters names of cities they have visited
Second View: User enters names of museums they saw in that city
Then, each time the user selects a city on the first View, the stored 'museum' information will be displayed.
So far, I've managed to get NSUserDefaults functional, but the same data is shown regardless of the cell that I select from the list on the initial View.
I am using the specific name of the array throughout the app to store, display and read data from NSUserDefaults, and I want to know the best way to edit this so that the app will check which cell I select and then display the appropriate information (or none if there hasn't been any entered for that cell).
I hope that was a good explanation, I know it was long - sorry. Below is my code so far. Any input or suggestions are welcome. Thank you!
import UIKit
import Foundation
class DetailViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {
#IBOutlet weak var titleLabel: UILabel!
#IBOutlet weak var detailTextField: UITextField!
#IBOutlet weak var detailTableView: UITableView!
var receivedString:String = ""
var cell0Array:[NSString] = []
override func viewDidLoad() {
super.viewDidLoad()
detailTextField.delegate = self
detailTableView.delegate = self
detailTableView.dataSource = self
titleLabel.text = receivedString
if NSUserDefaults.standardUserDefaults().objectForKey("cell0Array") != nil {
cell0Array = NSUserDefaults.standardUserDefaults().objectForKey("cell0Array") as! [NSString]
} else {
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
let now = NSDate()
let formatter = NSDateFormatter()
formatter.dateStyle = .MediumStyle
formatter.timeStyle = .NoStyle
let date = formatter.stringFromDate(now)
let detailTextFieldContents = detailTextField.text
let token = "\(date): \(detailTextFieldContents!)lb"
cell0Array.insert(token, atIndex: 0)
NSUserDefaults.standardUserDefaults().setObject(cell0Array, forKey: "cell0Array")
NSUserDefaults.standardUserDefaults().synchronize()
detailTextField.text = ""
detailTextField.resignFirstResponder()
self.detailTableView.reloadData()
return true
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return cell0Array.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let detailCell = tableView.dequeueReusableCellWithIdentifier("detailCell", forIndexPath: indexPath)
let detailItem = cell0Array[indexPath.row]
detailCell.textLabel!.text = detailItem as String
detailCell.textLabel!.textAlignment = .Center
self.view.layoutIfNeeded()
return detailCell
}
}
One obvious problem is this line:
func textFieldShouldReturn(textField: UITextField) -> Bool {
// ...
cell0Array.insert(token, atIndex: 0)
// ...
}
Instead of figuring out which row of the table this text field's cell is in, and placing the value at that index, you are always inserting token at index 0. Thus there is no correspondence between rows and entries in cell0Array.
So, I have trouble - can't reloadData of TableView, in command line I see good data - when I click button idMeet is changed, but in Simulator I don't see refresh table view after click on the button, and idMeet is changed and my query is changed too. I understand that I must use tableView.reloadData(), but don't understand where write it for correct working?
var x = true;
#IBOutlet weak var myButton: UIButton!
#IBOutlet var tbRouteData: UITableView!
#IBAction func act(sender: UIButton) {
x = !x
getInfo()
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(animated: Bool) {
self.getTmp()
}
func getInfo() -> NSMutableArray {
sharedInstance.database!.open()
var idMeet: Int
if x {
idMeet = 1
} else {
idMeet = 2
}
print(idroute)
let selectInfo: FMResultSet! = sharedInstance.database!.executeQuery("SELECT * FROM t1 AS one JOIN t2 AS two ON (one.id = two.id AND two.line_id = ?) ORDER BY two.position ASC", withArgumentsInArray: [idMeet])
...
return tmp
}
func getTmp(){
infoTmp = NSMutableArray()
infoTmp = getInfo()
}
// MARK: - Table view data source
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return infoTmp.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! PrivateCell
let my:Info = infoTmp.objectAtIndex(indexPath.row) as! Info
cell.listOfStop.text = my.Name.uppercaseString
return cell
}
There are a few issues here:
The getTmp function should reload the data:
func getTmp(){
infoTmp = getInfo()
tbRouteData.reloadData()
}
Now that you have a function that populates the property and reloads the table, act should call that, rather than getInfo:
#IBAction func act(sender: UIButton) {
x = !x
getTmp()
}
When you call getInfo, that doesn't set infoTmp. And by calling getTmp that centralizes the population of infoTmp and reloading of the table in one place.
If you're not seeing any data in your table view, make sure that you've set the delegate of the table view accordingly. You can do that either in IB, or programmatically:
override func viewDidLoad() {
super.viewDidLoad()
tbRouteData.delegate = self
}
This assumes, of course, that you defined your view controller to conform to UITableViewDataSource and have implemented the appropriate methods. Without seeing those methods, we can't tell if there might be some further issue there.
func getTmp(){
infoTmp = NSMutableArray()
infoTmp = getInfo()
tbRouteData.reloadData()
}
Write this code and this will reload your tableview with new data after the array fills up
The reload data should be completed within the button but after the getInfo() has been completed. The following should work:
#IBAction func act(sender: UIButton) {
x = !x
getInfo()
tbRouteData.reloadData()
}
Usually when tableView data array become changed then tableView should reload. In this case at the end of the button action method reload tableview.
#IBAction func act(sender: UIButton) {
x = !x
getInfo()
tbRouteData.reloadData()
}