Append array from another Controller - ios

I want to append new element to array. I'm using container view. I call addItem function to tableviewcontroller. But I clicked button nothing happen.
My TableViewController
import UIKit
class TableViewController: UITableViewController {
var myArray = ["1"]
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func addItem () {
myArray.append("asd")
tableView.reloadData()
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return myArray.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath)
// Configure the cell...
cell.textLabel?.text = myArray[indexPath.row]
return cell
}
}
My TableViewController
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func addButton(sender: AnyObject) {
TableViewController().addItem()
}
}

The line TableViewController().addItem() means create a brand new instance of TableViewController and then call addItem() on it. You need to find a reference to the specific instance of TableViewController you want to manipulate. How does that ViewController relate to the one calling addItem?

It should be something like this:
class ViewController: UIViewController {
let tableViewController = TableViewController()
..
#IBAction func addButton(sender: AnyObject) {
tableViewController.addItem()
}
}

Related

Swift - table is empty after moving between controllers

I'm updating existing Objective-C app.
There is a structure:
AppDelegate
- creates mainBackgroundView and adding subview with UITabBarController
I have in one "Tab" HistoryViewController:
#objc class HistoryViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let historyTableViewController = HistoryTableViewController()
self.view.addSubview(historyTableViewController.view)
}
}
And HistoryTableViewController:
import UIKit
#objc class HistoryTableViewController: UITableViewController {
// Mark: properties
var historyCalls = [HistoryItem]()
// Mark: private methods
private func loadSimpleHistory() {
let hist1 = HistoryItem(personName: "Test", bottomLine: "text", date: "10:47")
let hist2 = HistoryItem(personName: "Test 2", bottomLine: "text", date: "10:47")
let hist3 = HistoryItem(personName: "Test 3", bottomLine: "text", date: "10:47")
historyCalls += [hist1, hist2, hist3]
}
override func viewDidLoad() {
super.viewDidLoad()
self.loadSimpleHistory()
self.tableView.register(UINib(nibName: "HistoryCallTableViewCell", bundle: nil), forCellReuseIdentifier: "HistoryCallTableViewCell")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return historyCalls.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "HistoryCallTableViewCell", for: indexPath) as? HistoryCallTableViewCell else {
fatalError("Coulnd't parse table cell!")
}
let historyItem = historyCalls[indexPath.row]
cell.personName.text = historyItem.personName
cell.bottomLine.text = historyItem.bottomLine
cell.date.text = historyItem.date
return cell
}
}
When I open the navigation tab with HistoryViewController for the first time, table appers with data. When I click into the table or switch navTab and then go back, table is not there anymore.
When I switch to another app and then go back, table is there again.
How to fix this?
Thank you
Call data method in viewwillappear and reload the table..
override func viewWillAppear() {
super.viewWillAppear()
self.loadSimpleHistory()
self.tableview.reloadData()
}

Swift- passing data from a multiple-section tableview to ViewController

I have a two-section tableview (see image below)
When I click row "A", another tableview shows up with letter "A"
When I click row "B", another tableview shows up with letter "B"
How can I pass the letter "C" to another tableview when I click row C ?
Here's my code in TableView:
import UIKit
class manhinh1: UITableViewController {
var UserDefault:NSUserDefaults!
var array:[[String]]!
override func viewDidLoad() {
super.viewDidLoad()
UserDefault = NSUserDefaults()
array = [["A","B"],["C","D","E"]]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Potentially incomplete method implementation.
// Return the number of sections.
return array.count
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete method implementation.
// Return the number of rows in the section.
if section == 0 {
return array[0].count
}
if section == 1 {
return array[1].count
}
return 1
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell
if indexPath.section == 0 {
cell.textLabel?.text = array[0][indexPath.row]
}
if indexPath.section == 1 {
cell.textLabel?.text = array[1][indexPath.row]
}
// Configure the cell...
return cell
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var row = self.tableView.indexPathForSelectedRow()!.row
UserDefault.setObject(array[0][row], forKey: "selected")
}
}
Here's the code in second view:
import UIKit
class ViewController: UIViewController {
var UserDefault:NSUserDefaults!
#IBOutlet weak var lbldata: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
UserDefault = NSUserDefaults()
// Do any additional setup after loading the view, typically from a }
lbldata.text = UserDefault.objectForKey("selected") as! String
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I did try a few code in prepareForSegue, but it didn't work. I hope you guys can show me a way. Thanks
You have to get the row and the section to access your multidimensional array. Then get the destination view controller of your segue and assign the corresponding value from the array to the UserDefault property:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var row = self.tableView.indexPathForSelectedRow()!.row
var section = self.tableView.indexPathForSelectedRow()!.section
var destinationViewController = segue.destinationViewController as! ViewController
destinationViewController.UserDefault.setObject(array[section][row], forKey: "selected")
}

Swift UITableView subview appears but controller never called

I'm building a simple swift iOS app with a TableView that only takes up part of the screen. I have a FirstViewController that handles a long of info on the page and is the default landing page (it works as expected). A section of the page is a table view which I have created a new controller for BucketViewController.swift. That file looks like:
import UIKit
class BucketViewController: UITableViewController {
var buckets = [String]()
var newBucket: String = ""
override func viewDidLoad() {
print("INSIDE BUCKET")
super.viewDidLoad()
buckets = ["A", "B", "C"]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return buckets.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
print("TABLEVIEW")
let cell = tableView.dequeueReusableCellWithIdentifier("bucketCell", forIndexPath: indexPath) as! UITableViewCell
cell.textLabel!.text = buckets[indexPath.row]
return cell
}
}
In the storyboard, there is a Table View with the class bucketViewController. There is a prototype cell called bucketCell with a textLabel.
When I run the app the tableView appears, but it is blank. INSIDE BUCKET is never printed which makes me think the controller is never called. Any idea why this is?
import UIKit
class FirstViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

delegate modal view swift

I have tried the other methods for delegation and protocols for passing data between modal views and the parent view button they aren't working for me. This is obviously because I am implementing them wrong.
What I have is a parent view controller which has a tableviewcell which in the right detail will tell you your selection from the modal view. The modal view is another table view which allows you to select a cell, which updates the right detail and dismisses the modal view. All is working except the actual data transfer.
Thanks in advance!! :)
Here is my code for the parent view controller:
class TableViewController: UITableViewController, UITextFieldDelegate {
//Properties
var delegate: transferData?
//Outlets
#IBOutlet var productLabel: UILabel!
#IBOutlet var rightDetail: UILabel!
override func viewWillAppear(animated: Bool) {
println(delegate?.productCarrier)
println(delegate?.priceCarrier)
if delegate?.productCarrier != "" {
rightDetail.text = delegate?.productCarrier
productLabel.text = delegate?.productCarrier
}
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Potentially incomplete method implementation.
// Return the number of sections.
return 5
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete method implementation.
// Return the number of rows in the section.
return 1
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
}
The code for the model view controller and protocol is:
protocol transferData {
var priceCarrier: Double { get set }
var productCarrier: String { get set }
}
class ProductsDetailsViewController: UITableViewController, transferData {
//Properties
var priceCarrier = 00.00
var productCarrier = ""
//Outlets
//Actions
#IBAction func unwindToViewController(segue: UIStoryboardSegue) {
self.dismissViewControllerAnimated(true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
populateDefaultCategories()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Potentially incomplete method implementation.
// Return the number of sections.
return Int(Category.allObjects().count)
}
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return (Category.allObjects()[UInt(section)] as Category).name
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete method implementation.
// Return the number of rows in the section.
return Int(objectsForSection(section).count)
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:ProductListCell = tableView.dequeueReusableCellWithIdentifier("productCell", forIndexPath: indexPath) as ProductListCell
let queriedProductResult = objectForProductFromSection(indexPath.section, indexPath.row)
cell.name.text = queriedProductResult.name
cell.prices.text = "$\(queriedProductResult.price)"
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let indexPath = self.tableView.indexPathForSelectedRow()!
let product = objectForProductFromSection(indexPath.section, indexPath.row)
let PVC: TableViewController = TableViewController()
println("didSelect")
productCarrier = product.name
priceCarrier = product.price
println(productCarrier)
println(priceCarrier)
self.dismissViewControllerAnimated(true, completion: nil)
}
I think for passing data, you should use segue like:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let indexPath = self.tableView.indexPathForSelectedRow()!
let product = objectForProductFromSection(indexPath.section, indexPath.row)
println("didSelect")
productCarrier = product.name
priceCarrier = product.price
println(productCarrier)
println(priceCarrier)
self.performSegueWithIdentifier("displayYourTableViewControllerSegue", sender: self)
}
and then override the prepareForSegue function:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var controller = segue.destinationViewController as TableViewController
controller.rightDetail.text = "\(self.priceCarrier)"
controller.productLabel.text = self.productCarrier
}

DynamicCastClassUnconditional with Custom Cell Class

I want to use a custom cell class which contains a textfield. But I always get the DynamicCastClassUnconditional error for each cell. How do I get rid of this error? And is my Custom Cell class correct?
Table-Class
import UIKit
class SettingsEndpointCreateViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// Return the number of sections.
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of rows in the section.
return 3
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let cellId:String = "EndPointName";
var cell:TextCell = tableView.dequeueReusableCellWithIdentifier(cellId) as TextCell;
return cell;
}
#IBAction func returnToPrevious(){
self.dismissViewControllerAnimated(true, completion: nil);
}
}
Custom-Cell-Class
import UIKit
class TextCell: UITableViewCell {
var textField:UITextField = UITextField(frame: CGRectMake(0, 0, 100, 100))
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
addSubview(textField)
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
You need to register your custom cell class with the table view for that reuse identifier. In your view controller's viewDidLoad, add the following:
class SettingsEndpointCreateViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
tableView.registerClass(TextCell.self, forCellReuseIdentifier: "EndPointName")
}
// ...
}
Also, note that the method you're using to dequeue a cell returns an optional value. You can either handle that or call the newer, non-optional returning method:
let cell = tableView.dequeueReusableCellWithIdentifier(cellId, forIndexPath: indexPath) as TextCell
(Finally, the reuse identifier should really be a constant set somewhere.)

Resources