shravan.sukumar shravan.sukumar - 4 months ago 6
iOS Question

Showing optional value as 'nil' while changing the viewController from UITableView

I'm trying to display details from a table row onto another viewController, there are three entities which I want to display on the second VC. Two UILabel and one UIImageView. While in the first VC I'm able to view, when in the second VC, it says 'Optional("")', And don't know how to unwrap it.

import UIKit


class ViewController: UIViewController, UITextFieldDelegate, UITableViewDelegate,UITableViewDataSource, UICollectionViewDataSource, UICollectionViewDelegate {

@IBOutlet var nameForUser: UITextField!
@IBOutlet var loginButton: UIButton!

@IBOutlet var tableView: UITableView!




let allEvents = Events.allEvents
var nextScreenRow: Events!



override func viewDidLoad() {
super.viewDidLoad()
//nameForUser.text! = "Please Enter Name Here"
// Do any additional setup after loading the view, typically from a nib.

//let userName = nameForUser.text

}

func textFieldDidBeginEditing(textField: UITextField) {
textField.text = ""
}



func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.allEvents.count
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCellWithIdentifier("eventsCell")!
let event = self.allEvents[indexPath.row]
//print(" row \(indexPath.row)")

cell.textLabel?.text = event.eventName
cell.imageView?.image = UIImage(named: event.imageName)
cell.detailTextLabel?.text = event.entryType
//cell.textLabel?.text = allEvents[indexPath.row]

return cell
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {


nextScreenRow = allEvents[indexPath.row]

let view : DetailedEventViewController = self.storyboard?.instantiateViewControllerWithIdentifier("trytry") as! DetailedEventViewController
self.navigationController?.pushViewController(view, animated: true)

print("Selected section \(indexPath.section), row \(indexPath.row)")
print(nextScreenRow.eventName)

view.eventDetails = nextScreenRow.eventName
print(view.eventDetails)

view.typeOfEvent = nextScreenRow.entryType
view.myImage = UIImage(named: nextScreenRow.imageName)
//even the 'print' is used, it is displaying here, but not in the next VC

}

func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.allEvents.count
}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let sec = collectionView.dequeueReusableCellWithReuseIdentifier("eventsSec", forIndexPath: indexPath) as! GridCollectionViewCell

let event = self.allEvents[indexPath.row]

sec.imageView.image = UIImage(named: event.imageName)

sec.caption.text = event.entryType

return sec
}
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
performSegueWithIdentifier("tryToConnect2", sender: self)
}






override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "successfulLogin"){
segue.destinationViewController as! TabController
//let userName = nameForUser.text
//controller.userName = userName

}

}



@IBAction func loginButtonWhenPressed(sender: UIButton) {
let userName = nameForUser.text

if userName == "" {
let nextController = UIAlertController()
nextController.title = "Error!"
nextController.message = "Please enter a name"

let okAction = UIAlertAction(title: "okay", style: UIAlertActionStyle.Default) {
action in self.dismissViewControllerAnimated(true, completion: nil)
}

nextController.addAction(okAction)
self.presentViewController(nextController, animated: true, completion: nil)
}
}


}

And here is my second VC:

import UIKit

class DetailedEventViewController: UIViewController {

@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var deatiledEvent: UILabel!
@IBOutlet weak var eventType: UILabel!

var eventDetails = ""
var typeOfEvent = ""
var myImage: UIImage?

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.
}

@IBAction func viewTheElemnts(sender: AnyObject) {

deatiledEvent.text = eventDetails
print(deatiledEvent.text)

eventType.text = typeOfEvent
imageView.image = myImage
}

}


Help would be appreciated greatly. Thank you.

Answer

You are creating an instance of DetailedEventViewController in the didSelectRowAtIndexPath and setting the value there. But actually you are moving to DetailedEventViewController using segue. So you should add those values in the prepareForSegue: method.

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
   if (segue.identifier == "trytry")
   {
       let selectedIndex = self.tableView.indexPathForCell(sender as! UITableViewCell)
       nextScreenRow     = allEvents[selectedIndex.row]
       let view          = segue.destinationViewController as! DetailedEventViewController    
       view.eventDetails = nextScreenRow.eventName
       view.typeOfEvent  = nextScreenRow.entryType
       view.myImage      = UIImage(named: nextScreenRow.imageName)
   }
}
Comments