Master View Cell Labels Blank When Starting In Landscape - swift

The cell labels are blank in the master view of a default Master Detail View when starting in landscape orientation of an iPad 2 simulation. If I reload the master view in its controller's viewWillAppear function, everything is as it should be only after turning into portrait and back into landscape. I can't figure out what I am missing despite several hours of searching for help and trying to tableView.reloadData() in various places.
This is a UIDocument app and I have not yet implemented iCloud, although I have the code ready to go. Thus far, it just needs to fetch the local document URLs, file names, and display names (?) into an array from which the master view cell labels are created.
Here is most of the MasterViewController class:
class MasterViewController: UITableViewController, DetailViewControllerDelegate {
private var detailViewController: DetailViewController? = nil
// var objects = [AnyObject]()
internal lazy var notesController = NotesController()
internal override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
print("viewDidLoad")
// determine preferred storage location for documents
notesController.documentsInCloud = false
// discover documents
notesController.discoverDocuments()
// tableView.reloadData()
navigationItem.leftBarButtonItem = editButtonItem()
if let split = splitViewController {
let controllers = split.viewControllers
detailViewController =
(controllers[controllers.count-1] as! UINavigationController
).topViewController as? DetailViewController
detailViewController!.delegate = self
}
}
internal override func viewWillAppear(animated: Bool) {
print("viewWillAppear")
clearsSelectionOnViewWillAppear = splitViewController!.collapsed
super.viewWillAppear(animated)
tableView.reloadData()
}
// MARK: - Segues
internal override func prepareForSegue(segue: UIStoryboardSegue,
sender: AnyObject?) {
print("prepareForSegue")
if segue.identifier == "showDetail" {
if let indexPath = tableView.indexPathForSelectedRow {
let controller =
(segue.destinationViewController as! UINavigationController
).topViewController as! DetailViewController
let URL = notesController.notes.array[indexPath.row].URL
controller.delegate = self
controller.detailItem = Note(fileURL: URL)
controller.selectedItemIndex = indexPath.row
controller.navigationItem.leftBarButtonItem =
splitViewController?.displayModeButtonItem()
controller.navigationItem.leftItemsSupplementBackButton = true
splitViewController?.toggleMasterView()
} else {
let controller =
(segue.destinationViewController as! UINavigationController
).topViewController as! DetailViewController
controller.delegate = self
controller.configureView()
controller.navigationItem.leftBarButtonItem =
splitViewController?.displayModeButtonItem()
controller.navigationItem.leftItemsSupplementBackButton = true
}
}
}
// MARK: - Table View
internal override func numberOfSectionsInTableView(tableView: UITableView)
-> Int {
return 1
}
internal override func tableView(tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return notesController.notes.array.count
}
internal override func tableView(tableView: UITableView,
cellForRowAtIndexPath indexPath: NSIndexPath)
-> UITableViewCell {
print("cellForRowAtIndexPath")
let cell =
tableView.dequeueReusableCellWithIdentifier(
"Cell",
forIndexPath: indexPath)
let fileRepresentation = notesController.notes.array[indexPath.row]
if let title = fileRepresentation.displayName {
cell.textLabel?.text = title
} else {
cell.textLabel?.text = fileRepresentation.fileName
}
return cell
}
internal override func tableView(tableView: UITableView,
canEditRowAtIndexPath indexPath: NSIndexPath)
-> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
internal override func tableView(
tableView: UITableView,
commitEditingStyle
editingStyle: UITableViewCellEditingStyle,
forRowAtIndexPath indexPath: NSIndexPath) {
print("commitEditingStyle")
if editingStyle == .Delete {
let fileManager = NSFileManager.defaultManager()
let fileRepresentation = notesController.notes.array[indexPath.row]
let URL = fileRepresentation.URL
do {
try fileManager.removeItemAtURL(URL);
notesController.notes.delete(fileRepresentation);
tableView.deleteRowsAtIndexPaths([indexPath],
withRowAnimation: .Fade);
performSegueWithIdentifier("showDetail", sender: self)
} catch let error as NSError {
print(error.localizedDescription)
}
} // else if editingStyle == .Insert {
// Create a new instance of the appropriate class, insert it into
// the array, and add a new row to the table view.
// }
}
// MARK: - Delegate Functions
internal func reloadMasterViewData(sender: DetailViewController) {
tableView.reloadData()
}
}

For those who, like me, are new to the default Xcode Master-Detail view setup, yes, the Master view does start in landscape orientation populated with whatever labels it is set up to display. My problem was that the array I am using to populate the labels is constructed asynchronously from the views, and that array wasn't ready when the view loaded. I fixed this by setting up an NSNotification that told my master view when the array was finished discovering my UIDocuments. Andrew Bancroft's blog (https://www.andrewcbancroft.com/2014/10/08/fundamentals-of-nsnotificationcenter-in-swift/) was very helpful in that regard.

Related

Call the same view again so that another option can be selected in UITableViewController

Background:
Simple app that lets you select a currency from a UITableViewController, calls the same view again to make a second choice then takes user to a new view which displays the two selected currencies and exchange rate
So theoretically to me, this is only 2 views. The first being the currency list and the second is presenting chosen currencies/exchange rates. The first view is complete design wise. But I am struggling on how to make the connection between the first and second choice as it's calling the same view. How would I do this?
In my didSelectRowAt, I would typically performSegue but how do I call the same view and record the value selected from the first view? An idea I had was call a function that would record if an option is selected, and if so, call the new view else call the same view again but I'm not sure how I would implement this. Any help is appreciated!
My code thus far:
import UIKit
class SelectCurrencyTableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
// Get the JSON data to insert into the table
func parseJSONData()-> Array<Any> {
var finalArray = [Any]()
if let url = Bundle.main.url(forResource: "currencies", withExtension: "json") {
do {
let data = try Data(contentsOf: url)
let jsonResult = try JSONSerialization.jsonObject(with: data)
if var jsonArray = jsonResult as? [String] {
while jsonArray.count > 0 {
let result: [String] = Array(jsonArray.prefix(2))
finalArray.append(result)
jsonArray.removeFirst(2)
}
}
} catch {
print(error)
}
}
return finalArray
}
func checkOptionsCount()-> Int{
// somehow check if option selected?
return 1
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return parseJSONData().count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCellController
if let array = parseJSONData()[indexPath.row] as? [String]{
cell.countryCodeLabel.text = array[0]
cell.currencyLabel.text = array[1]
cell.countryFlag.image = UIImage(named: array[0])
}
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// if this is 1st time, present view again
if (checkOptionsCount() == 1){
// if this is 2nd time, show new view
} else if (checkOptionsCount() == 2){
// performSegue with new view
} else {
print("How did I get here")
}
}
/*
// 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.destination.
// Pass the selected object to the new view controller.
}
*/
}
Seeing your code, I am assuming you are using storyboards. One way to accomplish what you want can be like this:
In Interface Builder select your SelectCurrencyTableViewController and add Storyboard ID to it:
Add a property where you will store your selected currency to SelectCurrencyTableViewController, something along these lines:
class SelectCurrencyTableViewController: UITableViewController {
var selectedCurrency: Currency?
//...
}
Then in didSelectRow:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// if this is 2nd time, show new view
if let selected = selectedCurrency {
// performSegue with new view
// if this is 1st time, present view again
// these is no selected currency passed from previous view controller, so this is the first time
} else {
//get view controller from storyboard using storyboard id (replace "Main" with your storyboard's name
let vc = UIStoryboard(name: "Main", bundle: nil)
.instantiateViewController(withIdentifier: "SelectCurrencyTableViewController") as! SelectCurrencyTableViewController
vc.selectedCurrency = //place code for getting first currency based on indexPath.row here
show(vc, sender: self)
}
}

What identifier should I add for this optional?

I want to add this optional
var mapRegion : MKCoordinateRegion
It gives me an error that I need an identifier next to class:
class TableViewController: UITableViewController, NSFetchedResultsControllerDelegate,
What's that identifier?
The file looks like this:
import UIKit
import CoreData
import MapKit
class TableViewController: UITableViewController, NSFetchedResultsControllerDelegate, {
let moc = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
var frc : NSFetchedResultsController = NSFetchedResultsController()
var mapRegion : MKCoordinateRegion
func fetchRequest() -> NSFetchRequest {
let fetchRequest = NSFetchRequest(entityName: "Item")
let sortDescriptor = NSSortDescriptor(key: "name",
ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
return fetchRequest
}
func getFRC() -> NSFetchedResultsController {
frc = NSFetchedResultsController(fetchRequest: fetchRequest(), managedObjectContext: moc, sectionNameKeyPath: nil, cacheName: nil)
return frc
}
override func viewDidLoad() {
super.viewDidLoad()
frc = getFRC()
frc.delegate = self
do {
try frc.performFetch()
} catch {
print("Failed to perform initial fetch.")
return
}
self.tableView.rowHeight = 480
self.tableView.backgroundView = UIImageView( image: UIImage(named: "flatgrey2"))
self .tableView.reloadData()
}
override func viewDidAppear(animated: Bool) {
frc = getFRC()
frc.delegate = self
do {
try frc.performFetch()
} catch {
print("Failed to perform initial fetch.")
return
}
self .tableView.reloadData()
}
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 Incomplete implementation, return the number of sections
let numberOfSections = frc.sections?.count
return numberOfSections!
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
let numberofRowsInSection = frc.sections?[section].numberOfObjects
return numberofRowsInSection!
//return 0
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
if indexPath.row % 2 == 0 {
cell.backgroundColor = UIColor.clearColor()
} else {
cell.backgroundColor = UIColor.whiteColor().colorWithAlphaComponent(0.2)
cell.textLabel?.backgroundColor = UIColor.whiteColor().colorWithAlphaComponent(0.0)
cell.detailTextLabel?.backgroundColor = UIColor.whiteColor().colorWithAlphaComponent(0.0)
}
// Configure the cell...
cell.textLabel?.textColor = UIColor.darkGrayColor()
cell.detailTextLabel?.textColor = UIColor.darkGrayColor()
let item = frc.objectAtIndexPath(indexPath) as! Item
cell.textLabel?.text = item.name
cell.imageView?.image = UIImage(data: (item.image)!)
return cell
}
/*
// Override to support conditional editing of the table view.
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
*/
// Override to support editing the table view.
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
let managedObject : NSManagedObject = frc.objectAtIndexPath(indexPath) as! NSManagedObject
moc.deleteObject(managedObject)
do {
try moc.save()
} catch {
print ("Failed to save.")
return
}
}
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
tableView.reloadData()
}
/*
// Override to support rearranging the table view.
override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {
}
*/
/*
// Override to support conditional rearranging of the table view.
override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return false if you do not want the item to be re-orderable.
return true
}
*/
// 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.
if segue.identifier == "edit" {
let cell = sender as! UITableViewCell
let indexPath = tableView.indexPathForCell(cell)
let itemController : AddEditVC = segue.destinationViewController as! AddEditVC
let item : Item = frc.objectAtIndexPath(indexPath!) as! Item
itemController.item = item
}
}
}
The variable should have a value when it is declared otherwise it will show this error. Assign a value to your variable var mapRegion : MKCoordinateRegion. If the value is given at a later stage i.e., if it depends on any calculations then make it an optional like this var mapRegion : MKCoordinateRegion? But you have to unwrap the variable whenever you want to use mapRegion value by placing an exclamation mark at the end of the variable name.
You have declared var mapRegion : MKCoordinateRegion but don't have any initializers or default value. To make it an optional, just add ? to it, so declare:
var mapRegion : MKCoordinateRegion?

Transfer TableviewCell to AnotherTableView in swift

I have two tableView (FavouriteViewController and MainViewController) controllers in my project and the ViewController connected through segue with button. I have some data running in my MainViewController and the FavouriteViewController basically with no data in it.I am trying to transfer tableViewCell when the cell clicked from MainViewController to favouriteViewController using tableViewCell swipe action method or any another suggeste method.
my codes as below.
My MainViewController
var arrays = ["Alpha","Beta","Gamma","Phill","Below","Above","Clean",]
var sendSelectedData = NSString()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
title = "FavTV"
let titlebutton: UIButton = UIButton(frame: CGRectMake(0, 0, 100, 32))
titlebutton.setTitle("Quote", forState: UIControlState.Normal)
titlebutton.titleLabel?.font = UIFont(name: "PartyLetPlain", size: 35)
titlebutton.setTitleColor(UIColor.redColor(), forState: UIControlState.Normal)
titlebutton.addTarget(self, action: "titlePresed", forControlEvents: UIControlEvents.TouchUpInside)
self.navigationItem.titleView = titlebutton
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell1")
self.tableView.reloadData()
}
func titlePressed() {
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
self.performSegueWithIdentifier("ShowDetails", sender: nil)
segue.destinationViewController as! favTableViewController
}
self.performSegueWithIdentifier("ShowDetails", sender: nil)
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let indexPath = tableView.indexPathForSelectedRow!
let currentCell = tableView.cellForRowAtIndexPath(indexPath) as UITableViewCell!
sendSelectedData = (currentCell.textLabel?.text)! as String
//self.arrays.append(String(indexPath.row)
// performSegueWithIdentifier("ShowDetails", sender: self)
}
override func tableView(tableView: UITableView,commitEditingStyle editingStyle: UITableViewCellEditingStyle,forRowAtIndexPath indexPath: NSIndexPath) {
}
///////////////////////
override func tableView(tableView: UITableView,commitEditingStyle editingStyle: UITableViewCellEditingStyle,forRowAtIndexPath indexPath: NSIndexPath) {
switch editingStyle {
case .Delete:
// remove the deleted item from the model
self.arrays.removeAtIndex(indexPath.row)
performSegueWithIdentifier("ShowDetails", sender: self)
tableView.reloadData()
default:
return
}
}
/////////////////////
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "ShowDetails") {
// initialize new view controller and cast it as your view controller
let viewController = segue.destinationViewController as! favTableViewController
// your new view controller should have property that will store passed value
viewController.arrayx = [sendSelectedData as String]
///////////////////////
self.arrays.append(sendSelectedData as String)
/////////////////////
}
}
My FavouriteTableView:
var arrayx = []
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
title = "Fav"
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrayx.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
cell.textLabel?.text = arrayx[indexPath.row] as? String
return cell
}
}
Above code works in a simple way when i press the cell from MainViewController and then when the titlePressed() button pressed. it passing the pressed cell data to FavouriteTableView....
I need some suggetion how to transfer cell to my FavouriteTableView permanently.I am not sure about my logic is right. Please some one point me the right direction.
Thanks in Advance...
What shows up in a table is driven by :
var arrayx = [] // <-- CHANGE THE CONTENTS OF THIS ARRAY
Change the data in that array and then reload the table.
dispatch_async(dispatch_get_main_queue()) {
self.tableView.reloadData()
}
Here is your function that gets the data and puts it into the cells.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
// arrayx is the data that drives the table.
// changing the data in arrayx will cause the table to show different data.
// **********************************************
// ** The table will show whatever is in arrayx
// ** therefore, if you change arrayx then table
// ** will have that new data.
// **********************************************
cell.textLabel?.text = arrayx[indexPath.row] as? String
// **********************************************
return cell
}

creating searchviewcontroller in parse.com table

I have created a basic layout for searchViewcontroller in which I enter a data that I want to search inside parse table as a query and search is completed and the cell appears. I have tried searching but various errors are appearing. I have no clue to do this.
I'm trying to create an independent ViewController for search.
class SearchViewController: PFQueryTableViewController, UISearchBarDelegate {
// Table search bar
#IBOutlet weak var searchBar: UISearchBar!
// Initialise the PFQueryTable tableview
override init(style: UITableViewStyle, className: String!) {
super.init(style: style, className: className)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
// Configure the PFQueryTableView
self.parseClassName = "Countries"
self.textKey = "nameEnglish"
self.pullToRefreshEnabled = true
self.paginationEnabled = false
}
//override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("CustomCell") as! CustomTableViewCell!
if cell == nil {
cell = CustomTableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "CustomCell")
}
// Extract values from the PFObject to display in the table cell
if let nameEnglish = object?["nameEnglish"] as? String {
cell.customNameEnglish.text = nameEnglish
}
if let capital = object?["capital"] as? String {
cell.customCapital.text = capital
}
// Display flag image
var initialThumbnail = UIImage(named: "question")
cell.customFlag.image = initialThumbnail
if let thumbnail = object?["flag"] as? PFFile {
cell.customFlag.file = thumbnail
cell.customFlag.loadInBackground()
}
return cell
}
// 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].
var detailScene = segue.destinationViewController as! DetailViewController
// Pass the selected object to the destination view controller.
if let indexPath = self.tableView.indexPathForSelectedRow! {
let row = Int(indexPath.row)
detailScene.currentObject = objects?[row] as? PFObject
}
}
// Define the query that will provide the data for the table view
override func queryForTable() -> PFQuery {
// Start the query object
let query = PFQuery(className: "Countries")
// Add a where clause if there is a search criteria
if searchBar.text != "" {
query.whereKey("searchText", containsString: searchBar.text!.lowercaseString)
}
// Order the results
query.orderByAscending("nameEnglish")
// Return the qwuery object
return query
}
func searchBarTextDidEndEditing(searchBar: UISearchBar) {
// Dismiss the keyboard
searchBar.resignFirstResponder()
// Force reload of table data
self.loadObjects()
}
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
// Dismiss the keyboard
searchBar.resignFirstResponder()
// Force reload of table data
self.loadObjects()
}
func searchBarCancelButtonClicked(searchBar: UISearchBar) {
// Clear any search criteria
searchBar.text = ""
// Dismiss the keyboard
searchBar.resignFirstResponder()
// Force reload of table data
self.loadObjects()
}
override func viewDidAppear(animated: Bool) {
// Refresh the table to ensure any data changes are displayed
tableView.reloadData()
// Delegate the search bar to this table view class
searchBar.delegate = self
}
// Override to support conditional editing of the table view.
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return NO if you do not want the specified item to be editable.
return true
}
// Override to support editing the table view.
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
// Delete the row from the data source
let objectToDelete = objects?[indexPath.row] as! PFObject
objectToDelete.deleteInBackgroundWithBlock {
(success: Bool, error: NSError?) -> Void in
if (success) {
// Force a reload of the table - fetching fresh data from Parse platform
self.loadObjects()
} else {
// There was a problem, check error.description
}
}
} else if editingStyle == .Insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
}
If any clue is provided I'll be grateful.
This code is in reference with Bizzi-Body Parse Tutorial .

fatal error: unexpectedly found nil while unwrapping an Optional value: Swift, Core Data

I am getting error on the line:
let indexPath = self.menuTable.indexPathForSelectedRow()!.
Seems that I am not getting a value from indexPathForSelectedRow. I am parsing from a CSV file into Core Data. Not sure if it matters. I am new to coding, so not sure if I am missing something obvious.
import UIKit
import CoreData
class MenuTableViewController: UITableViewController {
#IBOutlet var menuTable: UITableView!
private var menuItems:[MenuItem] = []
var fetchResultController:NSFetchedResultsController!
override func viewDidLoad() {
super.viewDidLoad()
// Load menu items from database
if let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext {
let fetchRequest = NSFetchRequest(entityName: "MenuItem")
var e: NSError?
menuItems = managedObjectContext.executeFetchRequest(fetchRequest, error: &e) as! [MenuItem]
if e != nil {
println("Failed to retrieve record: \(e!.localizedDescription)")
}
}
// Make the cell self size
self.tableView.estimatedRowHeight = 66.0
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.layoutIfNeeded()
}
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 menuItems.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = menuTable.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! MenuTableViewCell
// Configure the cell...
cell.nameLabel.text = menuItems[indexPath.row].name
cell.detailLabel.text = menuItems[indexPath.row].detail
// cell.priceLabel.text = "$\(menuItems[indexPath.row].price as! Double)"
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
self.performSegueWithIdentifier("showFront", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
if (segue.identifier == "showFront")
{
var upcoming: CardFrontViewController = segue.destinationViewController as! CardFrontViewController
let indexPath = self.menuTable.indexPathForSelectedRow()!
let titleString = menuItems[indexPath.row].name
upcoming.titleStringViaSegue = titleString
self.menuTable.deselectRowAtIndexPath(indexPath, animated: true)
}
}
}
Since you have an implementation of tableView:didSelectRowAtIndexPath: and the cell is connected to the segue in the storyboard, the segue is happening twice. The second time the segue is performed there would be no selection because you deselect it during the first segue. You can fix this issue by deleting your implementation of tableView:didSelectRowAtIndexPath: or by creating the segue in the storyboard with the view controller itself as the source instead of the cell and leaving your manual invocation of the segue.
I don't know if this is the problem but why are u using self as sender if u need the indexPath?
Try:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
self.performSegueWithIdentifier("showFront", sender: indexPath)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
if (segue.identifier == "showFront")
{
var upcoming: CardFrontViewController = segue.destinationViewController as! CardFrontViewController
let titleString = menuItems[indexPath.row].name
upcoming.titleStringViaSegue = titleString
self.menuTable.deselectRowAtIndexPath(indexPath, animated: true)
}
}
I see you are using a UITableViewController. In a UITableViewController a UITableView is automatically created for you with the needed outlets. You can access it in code via self.tableView. My guess is that you do not connected the IBOutlet for your UITableView called menuTable. So the optional which is nil while unwrapping is not the indexPath but the UITableView.
Fix:
Delete your IBOutlet and everywhere you use the menuTable variable and use self.tableView instead.