I have a button action in one viewcontroller connect to another tableviewcontroller. I need to pass a few textfields value to show in another tableview via click the button. In the first view, I have a global array:
var estRent = [AnyObject]()
Append value within the buttonAction:
#IBAction func calculateButtonAction(sender: UIButton) {
...
estRent.append(weekRent)
estRent.append(monthRent)
estRent.append(yearRent)
estRent.append(interestRate)
estRent.append(loanAmount)
estRent.append(monthInterest)
}
Overwrite prepareForSegue:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "Load View") {
let svc = segue.destinationViewController as! NextTableViewController
svc.rentArray = self.estRent
}
}
In the NextTableViewController, there is a global array:
var rentArray = [AnyObject]()
The next table view could not see the values in the array. Appreciate any help.
First View Controller:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var nameTextField: UITextField!
#IBOutlet weak var ageTextField: UITextField!
#IBOutlet weak var classTextField: UITextField!
var estRent = [AnyObject]()
#IBAction func goButtonAction(sender: UIButton) {
estRent.append(nameTextField.text!)
estRent.append(ageTextField.text!)
estRent.append(classTextField.text!)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
[estRent .removeAll()]
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
print(estRent)
if (segue.identifier == "LoadView") {
let svc = segue.destinationViewController as! RentTableViewController
svc.rentArray = self.estRent
}
}
}
RentTableViewController:
import UIKit
class RentTableViewController: UITableViewController {
var rentArray = [AnyObject]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return rentArray.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "studentCell")
let tableCell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("studentCell", forIndexPath: indexPath)
let rentLabel: UILabel = UILabel.init(frame: CGRectMake(10, 10, 100, 25))
rentLabel.text = rentArray[indexPath.row] as? String
tableCell.addSubview(rentLabel)
return tableCell
}
}
Click here for Main.storyboard image
You must give a segue identifier as "LoadView" in storyboard
Click here to view screen short for "How to give segue identifier"
Related
I am trying to segue data from my "create a party" form into my second "Find Parties" tab.
Here is a screen shot of my main story board:
my code for the create a party controller:
import UIKit
struct party {
var name: String
var location: String
var description: String
}
class FirstViewController: UIViewController {
#IBOutlet weak var nameField: UITextField!
#IBOutlet weak var locationField: UITextField!
#IBOutlet weak var descriptionField: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
var newParty = party(name: "", location: "", description: "")
#IBAction func create(_ sender: AnyObject) {
newParty = party(name: nameField.text!, location: locationField.text!, description: descriptionField.text!)
nameField.text = ""
locationField.text = ""
descriptionField.text = ""
performSegue(withIdentifier: "toPartyList", sender: newParty)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let destinationViewController : SecondViewController = segue.destination as! SecondViewController
destinationViewController.parties.append(newParty)
}
}
Code for the find parties tab:
import UIKit
class SecondViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var partyTable: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
partyTable.delegate = self
partyTable.dataSource = self
// updates the table of users everytime submit is clicked
DispatchQueue.main.async{
self.partyTable.reloadData()
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
var parties = [party]()
// creates the number of cells in the table
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return parties.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Make table cells the show the user name
let cell = UITableViewCell()
cell.textLabel?.text = parties[indexPath.row].name
return cell
}
// Allows the user to swipe and delete people from the table and also the users array
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// delete the person in users array
parties.remove(at: indexPath.row)
// delete the cell from the table
partyTable.deleteRows(at: [indexPath], with: .fade)
}
}
}
currently my segue just takes me directly to the "Find Parties" view controller with no way back, and not to the tab. what do I need to change in my segue to do this?
Rather than use a segue in this case, just switch tabs programatically:
#IBAction func create(_ sender: AnyObject) {
newParty = party(name: nameField.text!, location: locationField.text!, description: descriptionField.text!)
nameField.text = ""
locationField.text = ""
descriptionField.text = ""
tabBarController?.selectedIndex = 1 // 2nd tab
}
To pass information along, you can do something like this:
let navVC = tabBarController.viewControllers[1] as! UINavigationController
let rootVC = navVC.viewControllers[0] as! SomeViewController
rootVC.someData = myData
Right now im following a tutorial. And i notice when i click a table cell and redirect to a new view, i found there is no detail for each cell.
ViewController.swift:
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
var itemsArray: [ToDoItem] = []
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return itemsArray.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as UITableViewCell!
let tempItem = itemsArray[indexPath.row]
cell.textLabel?.text = tempItem.itemName
return cell!
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "detailsegue" {
let destVC = segue.destinationViewController as! DetailViewController
let selectedIndex = tableView.indexPathForSelectedRow
destVC.myItem = itemsArray[selectedIndex!.row] as? ToDoItem
}
}
override func viewDidLoad() {
super.viewDidLoad()
let item1 = ToDoItem(name: "Eat", desc: "Eat until i am full. I prefer local food though!", place: "Food Court")
itemsArray.append(item1)
let item2 = ToDoItem(name: "Drink", desc: "Drink until i am full. I prefer local drink though!", place: "Drink Court")
itemsArray.append(item2)
let item3 = ToDoItem(name: "Jump", desc: "Jump until i am tired. I prefer local jump though!", place: "Sport Center")
itemsArray.append(item3)
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
ToDoItem.swift:
import UIKit
class ToDoItem: NSObject {
var itemName: String
var itemDescription: String?
var itemPlace : String?
var completed: Bool
init(name: String, desc: String?, place:String?) {
self.itemName = name
self.itemDescription = desc
self.itemPlace = place
self.completed = false
}
}
my detailviewcontroller.swift
import UIKit
class DetailViewController: UIViewController {
var myItem: ToDoItem?
#IBOutlet weak var nameLabel: UILabel!
#IBOutlet weak var placeLabel: UILabel!
#IBOutlet weak var descLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
nameLabel.text = myItem?.itemName
placeLabel.text = myItem?.itemDescription
// 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 prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
and here is my storyboard:
storyboard
Im creating an app where different buttons in a ViewController load different menu's into the tableViewController. The buttons are linked by a prepare for segue and the menu's (arrays) are linked by a contentMode. 1: breakfast menu & 2: lunch menu. I had allot of help from someone setting this up but now the table is not loading any data... The cell has 3 labels which display an item, info and price. It changes value within the code when a contentMode is selected. Does anyone see the problem in my code? thanks a lot!
import UIKit
class foodMenuController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let foodMenuController = segue.destinationViewController as! foodTableViewController
if segue.identifier == "showBreakfast" {
foodMenuController.contentMode = 1
} else if segue.identifier == "showLunch" {
foodMenuController.contentMode = 2
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
import UIKit
class foodTableViewCell: UITableViewCell {
#IBOutlet weak var foodItem: UILabel!
#IBOutlet weak var foodDescription: UILabel!
#IBOutlet weak var foodPrice: UILabel!
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
}
}
import UIKit
class foodTableViewController: UITableViewController {
//Content Mode Selection in menu
var contentMode = 0
// THIS SHOULD BE LOADED WHEN CONTENT MODE is "1" --> BREAKFAST
let breakfastItems = ["Bread", "Coffee", "Nada"]
let breakfastInfo = ["Good", "Nice", "Nothing"]
let breakfastPrice = ["$1", "$100", "$12,40"]
// THIS SHOULD BE LOADED WHEN CONTENT MODE IS "2" --> LUNCH
let lunchItems = ["Not bread", "Not Coffee", "Something"]
let lunchInfo = ["Not good", "Not nice", "Yes"]
let lunchPrice = ["$1", "$100", "$12,40"]
var foodItems: [String] = []
var foodInfo: [String] = []
var foodPrice: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(true)
switch (contentMode){
case 1: contentMode = 1
foodItems = breakfastItems
foodInfo = breakfastInfo
foodPrice = breakfastPrice
case 2: contentMode = 2
foodItems = lunchItems
foodInfo = lunchInfo
foodPrice = lunchPrice
default:
break
}
tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section:
Int) -> Int {
return foodItems.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "Cell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! foodTableViewCell
cell.foodItem.text = foodItems[indexPath.row]
cell.foodDescription.text = foodInfo[indexPath.row]
cell.foodPrice.text = foodPrice[indexPath.row]
return cell
}
}
There isn't anything apparently wrong with the snippet you shared. You can check what is returned in the tableView:numberOfRowsInSection: method and see if it is returning a value > 0
Also, this is a given but we've all done it at some point of time - check to make sure the tableview delegate and datasource are set to your viewcontroller.
I have made slight modifications in your project.
1. make the UINavigationController the InitialViewController
2. make the FoodMenuController the root of UINavigationController
Now modify your FoodMenuController
#IBOutlet weak var bakeryButton: UIButton!
#IBOutlet weak var breakfastButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBarHidden = true //hide navigationBar in first ViewController
self.bakeryButton.addTarget(self, action: "bakeryButtonAction:", forControlEvents: .TouchUpInside)
self.breakfastButton.addTarget(self, action: "breakfastButtonAction:", forControlEvents: .TouchUpInside)
}
func bakeryButtonAction(sender: UIButton) {
performSegueWithIdentifier("showLunch", sender: self)
}
func breakfastButtonAction(sender: UIButton) {
performSegueWithIdentifier("showBreakfast", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let foodTableViewController: FoodTableViewController = segue.destinationViewController as! FoodTableViewController
if segue.identifier == "showBreakfast" {
foodTableViewController.contentMode = 1
} else if segue.identifier == "showLunch" {
foodTableViewController.contentMode = 2
}
}
Also you can make UINavigationBar visible in FoodTableViewController
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBarHidden = false
}
PS: It is always better not to add segue directly to a UIButton. Alternatively you can add it from the yellow button on top of your FoodMenuController and specify the segue to be fired in UIButtonAction using performSegueWithIdentifier
I can no where see you setting the datasource and delegate of the tableView, please cross check these are both setup.
I am trying to setup a popover view containing a textfield and a tableview, but I couldn't make the tableview to show the data. It would be much appreciated if you could help me on this.
On the main ViewController, I put a label to trigger the segue of popover,
import UIKit
class ViewController: UIViewController, UIPopoverPresentationControllerDelegate {
#IBOutlet weak var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func popover(sender: AnyObject) {
self.performSegueWithIdentifier("ShowDetails", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "ShowDetails" {
if let controller = segue.destinationViewController as? UIViewController {
controller.popoverPresentationController!.delegate = self
controller.preferredContentSize = CGSize(width: 320, height: 50)
}
}
}
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
return .None
}
}
A PopoverCell is setup for the prototype cell,
import UIKit
class PopoverCellTableViewCell: UITableViewCell {
#IBOutlet weak var AreaCellLabel: UILabel!
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
}
}
A PopoverControllerView is set for the popover itself.
import UIKit
class PopoverViewController: UIViewController, UITextFieldDelegate, UITableViewDataSource, UITableViewDelegate {
var areas = [Area]()
// #IBOutlet weak var NewArea: UITextField!
// #IBOutlet weak var SaveNewArea: UIButton!
#IBOutlet weak var subtableView: UITableView!
override func viewDidLoad() {
subtableView.dataSource = self
subtableView.delegate = self
super.viewDidLoad()
LoadsampleArea()
// Do any additional setup after loading the view.
}
func LoadsampleArea () {
let area1 = Area(AreaName:"Moountain")!
let area2 = Area(AreaName:"ByHill")!
let area3 = Area(AreaName:"Yard")!
areas += [area1, area2, area3]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return areas.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// Table view cells are reused and should be dequeued using a cell identifier.
let cellIdentifier = "AreaCell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! PopoverCellTableViewCell
let area = areas[indexPath.row]
cell.AreaCellLabel.text = area.AreaName
dismissViewControllerAnimated(true, completion:nil)
return cell
}
}
and a simple data file to put the data.
import UIKit
class Area {
var AreaName: String
init? (AreaName: String) {
self.AreaName = AreaName
if AreaName.isEmpty {
return nil
}
}
}
Where is your UITableView object in your PopoverViewController class ? I can't see any reference to it.
Maybe your didn't copy-paste it since the textfield is commented too, in this case I'll suggest to check if the delegate an datasource are set property.
I am really struggling to pass data from SecondViewController to ActivityFormTableViewController.
get this error: 'NSInvalidArgumentException', reason: 'Receiver () has no segue with identifier 'MajorActivity''
Code for two classes follow:
Any help would be received with gratitude.
//
// SecondViewController.swift
// LinkByActivity
//
// Created by Jeremy Andrews on 2015/06/10.
// version update 23/06/2015
// Copyright (c) 2015 Jeremy Andrews. All rights reserved.
//
import UIKit
class SecondViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet var tableView: UITableView!
let textCellIdentifier = "TextCell"
var catRet = XnYCategories.mainCats("main")
var activityDictionary = [String : [String]]()
var key1:String!
#IBAction func ActivityMainCats(segue:UIStoryboardSegue) {
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
// MARK: UITextFieldDelegate Methods
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return catRet.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(textCellIdentifier, forIndexPath: indexPath) as! UITableViewCell
let row = indexPath.row
cell.textLabel?.text = catRet[row]
return cell
}
// MARK: UITableViewDelegate Methods
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
var row = indexPath.row
let key1 = catRet[row]
println(key1)
performSegueWithIdentifier("MajorActivity", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "MajorActivity") {
var svc = segue.destinationViewController as! ActivityFormTableViewController;
svc.key2 = key1
println(key1)
}
}
}
//
// ActivityFormTableViewController.swift
// LinkByActivity
//
// Created by Jeremy Andrews on 2015/07/24.
// Copyright (c) 2015 Jeremy Andrews. All rights reserved.
//
import UIKit
class ActivityFormTableViewController: UITableViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet var tableView2: UITableView!
var key2:String!
var catRet2 = XnYCategories.mainCats("Sport")
let textCellIdentifier = "TextCell2"
var activityDictionary = [String : [String]]()
override func viewDidLoad() {
super.viewDidLoad()
println(key2)
var catRet2 = XnYCategories.mainCats(key2)
println(catRet2)
tableView.delegate = self
tableView.dataSource = self
}
// MARK: UITextFieldDelegate Methods
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//var catRet2 = XnYCategories.mainCats(key2)
return catRet2.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(textCellIdentifier, forIndexPath: indexPath) as! UITableViewCell
let row = indexPath.row
cell.textLabel?.text = catRet2[row]
return cell
}
// MARK: UITableViewDelegate Methods
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
var row = indexPath.row
let activityKey = "CellNo_" + "famNam_" + key2
activityDictionary = [activityKey: ["TheForm", "l1", "etc"]]
//println(activityDictionary)
}
}
You need to create a UINavigationController in your prepareForSegue method because it appears as that's what you have on your storyboard. Then you need to create an instance of the controller that you want the navigation controller to show and assign your properties to that.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "MajorActivity") {
let activityFormNavController = segue.destinationViewController as! UINavigationController
let svc = activityFormNavController.topViewController as! ActivityFormTableViewController
svc.key2 = key1
println(key1)
}
}
Storyboard Example:
ViewController.swift
import UIKit
class ViewController: UIViewController {
var someString : String?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func fireSegueBttnTouched(sender: AnyObject) {
// set my local instance variable to some value to pass
someString = "Stack Overflow Is Great!"
performSegueWithIdentifier("next", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "next" {
// Create a UINavigationController instance first b/c that's where the segue goes
let nextNavVc = segue.destinationViewController as! UINavigationController
// Create an instance of the top view controller belonging to the above crated navigation controller
let nextVc = nextNavVc.topViewController as! SecondViewController
// Assign the instance variable from this view controller to the variable on the view controller nextVc
nextVc.passedString = someString
}
}
}
SecondViewController.swift
import UIKit
class SecondViewController: UIViewController {
#IBOutlet weak var outputLabel: UILabel!
var passedString : String?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func viewDidLayoutSubviews() {
if passedString != nil {
outputLabel.text = passedString!
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Simulator Screenshots: