How to pass the data from table view to another view controller - ios

Im a newbie in Swift Language.. i want to pass the price from Table View controller to Payment View controller
Here my code for table view controller
import UIKit
class MainMenuViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
let labeltitle = ["ADLV Black Tee", "ASSC Black Hoodie", "CDG Play Gold Black Tee"]
let labelprice = [("RM 250"), ("RM 305"), ("RM 418")]
let myImage = [UIImage(named: "adlv1"), UIImage(named: "assc"), UIImage(named: "cdg1")]
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
//here got error
override func prepare(for segue: UIStoryboardSegue, sender: (Any)?){
var DestinationViewController : PaymentViewController = segue.destination as! PaymentViewController
if let lText = labelprice.text {
DestinationViewController.price = lText
}
}
#IBAction func BuyNowbutton(_ sender: Any) {
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return labeltitle.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MainMenuTableViewCell
cell.label11?.text = labeltitle[indexPath.row]
cell.label2?.text = labelprice[indexPath.row]
cell.myImage.image = self.myImage[indexPath.row]
return cell
}
}
Here my Payment view controller
import UIKit
class PaymentViewController: UIViewController {
var items = [item]()
var price : String = ""
#IBOutlet weak var paymentdetails: UILabel!
#IBOutlet weak var cardnametextfield: UITextField!
#IBOutlet weak var validthrutextfield: UITextField!
#IBOutlet weak var cardnumbertextfield: UITextField!
#IBOutlet weak var cvcnumbertextfield: UITextField!
#IBOutlet weak var labelprice: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
labelprice.text = price
// Do any additional setup after loading the view.
}
#IBAction func paybutton(_ sender: Any) {
if cardnametextfield.text == "" {
alertMessage(titleInput: "Error, Payment Unsuccessful!", messageInput: "Please Fill all the fields")
} else if validthrutextfield.text == "" {
alertMessage(titleInput: "Error, Payment Unsuccessful!", messageInput: "Please Fill all the fields")
} else if cardnumbertextfield.text == "" {
alertMessage(titleInput: "Error, Payment Unsuccessful!", messageInput: "Please Fill all the fields")
} else if cardnumbertextfield.text == "" {
alertMessage(titleInput: "Error, Payment Unsuccessful!", messageInput: "Please Fill all the fields")
} else {
alertMessage(titleInput: "Success!", messageInput: "Payment Successful!")
self.transitionToHomePage()
}
}
func alertMessage(titleInput: String, messageInput: String){
let alert = UIAlertController(title: titleInput, message: messageInput, preferredStyle: UIAlertController.Style.alert)
let paybutton = UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil)
alert.addAction(paybutton)
self.present(alert, animated: true, completion: nil)
}
func transitionToHomePage(){
let TabHomeViewController = storyboard?.instantiateViewController(identifier: Constrants.Storyboard.TabHomeViewController) as? UITabBarController
view.window?.rootViewController = TabHomeViewController
view.window?.makeKeyAndVisible()
}
}

First you should make a struct
struct Item {
let title,price,imageName:String
}
instead of the 3 arrays make 1
var arr = [Item]()
and fill it
Second
override func prepare(for segue: UIStoryboardSegue, sender: (Any)?){
var des = segue.destination as! PaymentViewController
if let row = tableView.indexPathForSelectedRow?.row {
des.price = arr[row].price
}
}
Finally connect the segue from the tableView not from the cell and dragged it to the destination vc , then inside didSelectRowAt delegate method of table dp
self.performSegue(withIdentifier:"SegueNameHere",sender:nil)

Related

Passing data from Table view cell using button delegate

I want to pass the data from one view controller to another view controller when the user clicked the button . I am using button with delegate to pass the table view cell values into different view controller view . In second view controller I have two labels and one image to display the fields but the problem is when I clicked the button it is empty.
Here is the cell code .
import UIKit
protocol CellSubclassDelegate: AnyObject {
func buttonTapped(cell: MovieViewCell)
}
class MovieViewCell: UITableViewCell {
weak var delegate:CellSubclassDelegate?
static let identifier = "MovieViewCell"
#IBOutlet weak var movieImage: UIImageView!
#IBOutlet weak var movieTitle: UILabel!
#IBOutlet weak var movieOverview: UILabel!
#IBOutlet weak var someButton: UIButton!
#IBAction func someButtonTapped(_ sender: UIButton) {
self.delegate?.buttonTapped(cell: self)
}
override func prepareForReuse() {
super.prepareForReuse()
self.delegate = nil
}
func configureCell(title: String?, overview: String?, data: Data?) {
movieTitle.text = title
movieOverview.text = overview
if let imageData = data{
movieImage.image = UIImage(data: imageData)
// movieImage.image = nil
}
}
}
Here is the first view controller code .
import UIKit
class MovieViewController: UIViewController, UISearchBarDelegate {
#IBOutlet weak var userName: UILabel!
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var searchBar: UISearchBar!
private var presenter: MoviePresenter!
var finalname = ""
var movieTitle = ""
var movieOverview = ""
var movieImage : UIImage?
override func viewDidLoad() {
super.viewDidLoad()
userName.text = "Hello: " + finalname
setUpUI()
presenter = MoviePresenter(view: self)
searchBarText()
}
private func setUpUI() {
tableView.dataSource = self
tableView.delegate = self
}
private func searchBarText() {
searchBar.delegate = self
}
#IBAction func selectSegment(_ sender: UISegmentedControl) {
if sender.selectedSegmentIndex == 0{
setUpUI()
presenter = MoviePresenter(view: self)
presenter.getMovies()
}
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchText == ""{
presenter.getMovies()
}
else {
presenter.movies = presenter.movies.filter({ movies in
let originalTitle = movies.originalTitle.lowercased().range(of: searchText.lowercased())
let overview = movies.overview.lowercased().range(of: searchText.lowercased())
let posterPath = movies.posterPath.lowercased().range(of: searchText.lowercased())
return (originalTitle != nil) == true || (overview != nil) == true || (posterPath != nil) == true}
)
}
tableView.reloadData()
}
}
extension MovieViewController: MovieViewProtocol {
func resfreshTableView() {
tableView.reloadData()
}
func displayError(_ message: String) {
let alert = UIAlertController(title: "Error", message: message, preferredStyle: .alert)
let doneButton = UIAlertAction(title: "Done", style: .default, handler: nil)
alert.addAction(doneButton)
present(alert, animated: true, completion: nil)
}
}
extension MovieViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
presenter.rows
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: MovieViewCell.identifier, for: indexPath) as! MovieViewCell
let row = indexPath.row
let title = presenter.getTitle(by: row)
let overview = presenter.getOverview(by: row)
let data = presenter.getImageData(by: row)
cell.delegate = self
cell.configureCell(title: title, overview: overview, data: data)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let dc = storyboard?.instantiateViewController(withIdentifier: "MovieDeatilsViewController") as! MovieDeatilsViewController
let row = indexPath.row
dc.titlemovie = presenter.getTitle(by: row) ?? ""
dc.overview = presenter.getOverview(by: row) ?? ""
dc.imagemovie = UIImage(data: presenter.getImageData(by: row)!)
self.navigationController?.pushViewController(dc, animated: true)
}
}
extension MovieViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
}
extension MovieViewController : CellSubclassDelegate{
func buttonTapped(cell: MovieViewCell) {
guard (self.tableView.indexPath(for: cell) != nil) else {return}
let customViewController = storyboard?.instantiateViewController(withIdentifier: "MovieDeatilsViewController") as? MovieDeatilsViewController
customViewController?.titlemovie = movieTitle
customViewController?.imagemovie = movieImage
customViewController?.overview = movieOverview
self.navigationController?.pushViewController(customViewController!, animated: true)
}
}
Here is the details view controller code .
class MovieDeatilsViewController: UIViewController {
#IBOutlet weak var movieImage: UIImageView!
#IBOutlet weak var movieTitle: UILabel!
#IBOutlet weak var movieOverview: UILabel!
var titlemovie = ""
var overview = ""
var imagemovie :UIImage?
override func viewDidLoad() {
super.viewDidLoad()
movieTitle.text = titlemovie
movieOverview.text = overview
movieImage.image = imagemovie
}
}
Here is the result when I clicked the button .
The problem is you don't update you're global properties when selecting each of you're row,
If you pass data over cell delegate and pass you're cell through delegate, you can pass data from cell like:
customViewController?.titlemovie = cell.movieTitle.text ?? ""
customViewController?.imagemovie = cell.movieImage.image
customViewController?.overview = cell.movieOverview.text ?? ""
of course it would be better to pass you're data model to you're cell. and then share that through you're delegate not share you're cell, like:
protocol CellSubclassDelegate: AnyObject {
func buttonTapped(cell: MovieModel)
}

Why is nothing being sent to my tableview?

I am creating a news feed, but nothing is being sent to it. I am currently just testing the gamertag (username), body text, and timestamp. Here are my classes:
1) NewPost (create a new post that is sent to the table view)
import Foundation
import UIKit
import Firebase
import FirebaseDatabase
class NewPost: UIViewController, UITextViewDelegate {
#IBOutlet var enterGamertag: UITextField!
#IBOutlet var enterMessage: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
//ADDTOLIST BUTTON
#IBAction func addToList(_ sender: UIButton) {
// guard let userProfile = UserService.currentProfile else {
return }
let postRef =
Database.database().reference().child("posts").childByAutoId()
let postObject = [
// "Gametag": [
//// "uid": userProfile.id,
//// "gamertag": userProfile.gamerTag
// ],
"gamerTag": enterGamertag.text as Any,
"bodytext": enterMessage.text as Any,
"timestamp": [".sv":"timestamp"]
] as [String:Any]
postRef.setValue(postObject, withCompletionBlock: { error, ref in
if error == nil {
self.dismiss(animated: true, completion: nil)
} else {
// Handle the error
}
})
// UserService.sharedInstance.validateUsername("Ninja")
}
//dismiss keyboard
#IBAction func dismissKeyboard(_ sender: UITextField) {
self.resignFirstResponder()
}
#IBAction func micPressed(_ sender: UIButton) {
if sender.isSelected {
sender.isSelected = false
} else {
sender.isSelected = true
}
}
#IBAction func logOutPressed(_ sender: UIButton) {
try! Auth.auth().signOut()
// performSegue(withIdentifier: "logOut", sender: self)
}
}
2) feedTable (shows the table view)
import UIKit
import Firebase
class FeedTable: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet var tableFeedView: UITableView!
var posts = [Post]()
//VIEWDIDLOAD
override func viewDidLoad() {
super.viewDidLoad()
// Hide the navigation bar on the this view controller
tableFeedView.delegate = self
tableFeedView.dataSource = self
tableFeedView.register(UINib(nibName: "PostTableViewCell", bundle: nil), forCellReuseIdentifier: "customTableCell")
// self.tableFeedView?.backgroundColor = UIColor.black
tableFeedView.tableFooterView = UIView()
configureTableView()
}
func observePosts() {
let postRef = Database.database().reference().child("posts")
postRef.observe(.value, with: { snapshot in
var tempPosts = [Post]()
for child in snapshot.children {
if let childSnapshot = child as? DataSnapshot,
let dict = childSnapshot.value as? [String:Any],
let gamerTag = dict["gamerTag"] as? String,
let bodytext = dict["bodytext"] as? String,
let timestamp = dict["timestamp"] as? Double {
let post = Post(id: childSnapshot.key, gamerTag: gamerTag, bodyText: bodytext, timestamp: timestamp)
tempPosts.append(post)
}
}
self.posts = tempPosts
self.tableFeedView.reloadData()
})
}
#IBAction func refreshTable(_ sender: UIButton) {
tableFeedView.reloadData()
}
//Cell For Row At
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:PostTableViewCell = tableView.dequeueReusableCell(withIdentifier: "customTableCell", for: indexPath) as! PostTableViewCell
cell .set(post: posts[indexPath.row])
return cell
}
//Number Of Rows
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
//Automatic Row Height
func configureTableView() {
tableFeedView.rowHeight = UITableViewAutomaticDimension
tableFeedView.estimatedRowHeight = 120.0
}
}
3) PostTableViewCell (the cell that contains the text labels)
import UIKit
class PostTableViewCell: UITableViewCell {
#IBOutlet weak var customMessageBody: UILabel!
#IBOutlet weak var customConsole: UILabel!
#IBOutlet weak var ifMicUsed: UIImageView!
#IBOutlet weak var timeAdded: UILabel!
#IBOutlet weak var gameMode: UILabel!
#IBOutlet weak var customGamerTag: 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
}
func set(post:Post){
customGamerTag.text = post.gamerTag
customMessageBody.text = post.bodyText
customMessageBody.text = "\(post.timestamp) minutes ago."
}
}

Get values from a view controller's text field

I have 2 view controllers and a swift file. I wish to pass the data from one view controller to the other without using segue or presenting the other view controller.
View controller:
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
var questions:[Question] = []
var sub = ""
var send = ""
var det = ""
#IBOutlet weak var questionsender: UISegmentedControl!
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.tableView.reloadData()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return questions.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 50
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "forumcell", for: indexPath) as! ForumTableViewCell
cell.questionsubject.text = questions[indexPath.row].subject
cell.sender.text = questions[indexPath.row].sender
return cell
}
}
Swift file:
import Foundation
class Question
{
var subject = ""
var descript = ""
var sender = ""
init(subject : String, descrip: String,sender : String)
{
self.sender=sender
self.descript=descrip
self.subject=subject
}
}
Second view controller:
import UIKit
class AddVC: UIViewController,UITextFieldDelegate {
var qsender = ""
var subject = ""
var details = ""
#IBAction func postBttn(_ sender: Any) {
if questiondetails.text == "" || question_sender.text == "" || question_subject.text == ""
{
let alert = UIAlertController(title: "Invalid!", message: "One of the fields has not been entered", preferredStyle: .alert)
let bttn = UIAlertAction(title: "Ok", style: .cancel, handler: nil)
alert.addAction(bttn)
}
else
{
qsender = question_sender.text
subject = question_subject.text
details = questiondetails.text
let q=Question(subject: subject, descrip: details, sender: qsender)
let v = ViewController()
v.send = qsender
v.sub = subject
v.det = details
dismiss(animated: true, completion: nil)
}
}
#IBAction func closeBttn(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
#IBOutlet weak var question_subject: UITextView!
#IBOutlet weak var question_sender: UITextView!
#IBOutlet weak var closeBttn: UIButton!
#IBOutlet weak var questiondetails: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
question_subject.placeholderText="Sender"
question_subject.placeholderText="Subject"
questiondetails.placeholderText="Description"
let swipeDown = UISwipeGestureRecognizer(target: self, action: #selector(swiped(_ :)))
swipeDown.direction = .down
self.view.addGestureRecognizer(swipeDown)
}
func swiped(_ gesture:UISwipeGestureRecognizer)
{
dismiss(animated: true, completion: nil)
}
}
The object v I created for View Controller cannot update the data members through the AddVC class.
in ViewController:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let destination = segue.destination as! AddVC
destination.callbackFromAddVC = { stringData in
// use stringData
}
}
in AddVC:
var callbackFromAddVC: ((String) -> Void)? = nil
func swiped(_ gesture:UISwipeGestureRecognizer)
{
self.callbackFromAddVC?("myStringData that needs to be transferred")
dismiss(animated: true, completion: nil)
self.callbackFromAddVC = nil
}
Add this line to ViewController:
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
static let viewControllerSegueIdentifier: String = "ViewController"
Make sure that the viewControllerSegueIdentifier string matches your segue identifier.
Then make these edits to AddVC:
#IBAction func postBttn(_ sender: Any) {
if questiondetails.text == "" || question_sender.text == "" || question_subject.text == ""
{
let alert = UIAlertController(title: "Invalid!", message: "One of the fields has not been entered", preferredStyle: .alert)
let bttn = UIAlertAction(title: "Ok", style: .cancel, handler: nil)
alert.addAction(bttn)
}
else
{
qsender = question_sender.text
subject = question_subject.text
details = questiondetails.text
dismiss(animated: true, completion: {
goToAddScreen(segueIdentifier: ViewController.viewControllerSegueIdentifier)
})
}
}
Then add these 2 methods:
func goToAddScreen(segueIdentifier: String) {
performSegue(withIdentifier: segueIdentifier, sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == ViewController.viewControllerSegueIdentifier {
guard let controller = segue.destination as? ViewController else {
return
}
let q=Question(subject: subject, descrip: details, sender: qsender)
controller.questions.append(q)
}
}

How to pass label data that is already passed to another view controller using navigation bar item add action?

addQuestionViewTableView Controller (This view controller is segued(push) to SubViewController)
import UIKit
class SubjectsTableViewCell: UITableViewCell {
#IBOutlet weak var subjectImage: UIImageView!
#IBOutlet weak var subjectName: UILabel!
}
class AddQuestionTableViewController: UITableViewController {
var Subjects = ["Geology", "Mathematics", "Computer", "English", "History", "Science"]
override func viewDidLoad() {
super.viewDidLoad()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (Subjects.count)
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "pickedSubjectSegue", sender: Subjects[indexPath.row])
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let next = segue.destination as! SubViewController
next.text = sender as! String
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! SubjectsTableViewCell
cell.subjectName?.text = Subjects[indexPath.row]
cell.subjectImage?.image = UIImage(named: (Subjects[indexPath.row] + ".jpeg"))
return cell
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
My Second View Controller (i added nav bar + button and ctrl drag to segue(modally) to nav bar controller of addViewController). I am using navigation bar item action to pass data(is this okay?)
import UIKit
class SubViewController: UIViewController {
#IBOutlet weak var subImage: UIImageView!
#IBOutlet weak var subTitle: UILabel!
#IBOutlet weak var subCount: UILabel!
var text = "hi"
override func viewDidLoad() {
super.viewDidLoad()
subTitle.text = text // name of the subject - success
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func add(_ sender: Any) {
self.performSegue(withIdentifier: "addQuestion", sender: text)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let next2 = segue.destination as? AddViewController{
next2.text2 = sender as! String
}
}
}
My Third View Controller
import UIKit
import Firebase
import FirebaseDatabase
class AddViewController: UIViewController {
#IBOutlet weak var subjectLabel: UILabel!
#IBOutlet weak var questionField: UITextField!
#IBOutlet weak var correctField: UITextField!
#IBOutlet weak var optionAField: UITextField!
#IBOutlet weak var optionBField: UITextField!
#IBOutlet weak var optionCField: UITextField!
var text2 = "hello"
var ref: FIRDatabaseReference!
override func viewDidLoad() {
super.viewDidLoad()
ref = FIRDatabase.database().reference()
self.hideKeyboard()
subjectLabel.text = text2 // i want this to be the name of subject also
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func cancel(_ sender: Any) {
self.dismiss(animated: true, completion: nil)
}
#IBAction func add(_ sender: Any) {
if questionField.text != "" && correctField.text != "" && optionAField.text != "" && optionBField.text != "" && optionCField.text != "" {
//saving to firebaseDB
self.ref?.child("\(text2)").childByAutoId().setValue(["Question": questionField.text, "Answer": correctField.text, "optionA": optionAField.text, "optionB": optionBField.text, "optionC": optionCField.text]) //text2 should be the name of the subject
alert(title: "Success!", message: "Question has been added to database.")
questionField.text = ""
correctField.text = ""
optionAField.text = ""
optionBField.text = ""
optionCField.text = ""
}
else
{
alert(title: "Error", message: "Missing fields. Please input")
}
}
func alert(title: String, message: String)
{
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
let action = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(action)
self.present(alertController, animated: true, completion: nil)
}
}
You just pass text as sender in SubViewController.
#IBAction func add(_ sender: Any) {
self.performSegue(withIdentifier: "addQuestion", sender: text)
}

Not able to display values in another viewcontroller from TableView in Swift

I want to display the details of one one table row onto another viewController. But it shows an error saying ' fatal error: unexpectedly found nil while unwrapping an Optional value'
The code for my VC is as follows:
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.
}
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]
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) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
nextScreenRow = allEvents[indexPath.row]
performSegueWithIdentifier("tryToConnect", sender:self)
}
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
}
else if (segue.identifier == "tryToConnect"){
let dest = segue.destinationViewController as! DetailedEventViewController
dest.deatiledEvent.text = nextScreenRow.eventName
dest.eventType.text = nextScreenRow.entryType
dest.imageView.image = UIImage(named: nextScreenRow.imageName)
}
}
#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)
}
}
}
When I run this, it shows the error. I have also assigned the delegates for the table view. The code for 'DetailedEventVC' is:
import UIKit
class DetailedEventViewController: UIViewController {
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var deatiledEvent: UILabel!
#IBOutlet weak var eventType: UILabel!
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 prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
Why does it show that the values are nil?
Help would be greatly appreciated.
Thanks in advance.
The 'EventsDetails.swift' file which has the details of events are a structure. Is there anything wrong in the way I'm calling the values?
import Foundation
import UIKit
struct Events {
let eventName: String
let entryType: String
let imageName: String
static let EventKey = "NameKey"
static let EntryTypeKey = "EntryType"
static let ImageNameKey = "ImageNameKey"
init(dictionary:[String : String]) {
self.eventName = dictionary[Events.EventKey]!
self.entryType = dictionary[Events.EntryTypeKey]!
self.imageName = dictionary[Events.ImageNameKey]!
}
}
extension Events {
static var allEvents: [Events] {
var eventsArray = [Events]()
for d in Events.localEventsData(){
eventsArray.append(Events(dictionary: d))
}
return eventsArray
}
static func localEventsData()-> [[String: String]] {
return [
[Events.EventKey:"Metallica Concert in Palace Grounds", Events.EntryTypeKey: "Paid Entry", Events.ImageNameKey:"Metallica"],
[Events.EventKey:"Saree Exhibition in Malleswaram Grounds", Events.EntryTypeKey: "Free Entry", Events.ImageNameKey:"SareeExhibition"],
[Events.EventKey:"Wine tasting event in Links Brewery", Events.EntryTypeKey: "Paid Entry", Events.ImageNameKey:"WineTasting"],
[Events.EventKey:"Startups Meet in Kanteerava Stadium", Events.EntryTypeKey: "Paid Entry", Events.ImageNameKey:"StartupMeet"],
[Events.EventKey:"Summer Noon Party in Kumara Park", Events.EntryTypeKey: "Paid Entry", Events.ImageNameKey:"SummerNoonParty"],
[Events.EventKey:"Rock and Roll nights in Sarjapur Road", Events.EntryTypeKey: "Paid Entry", Events.ImageNameKey:"RockNRollNight"],
[Events.EventKey:"Barbecue Fridays in Whitefield", Events.EntryTypeKey: "Paid Entry", Events.ImageNameKey:"BBQFriday"],
[Events.EventKey:"Summer workshop in Indiranagar", Events.EntryTypeKey: "Free Entry", Events.ImageNameKey:"SummerWorkshop"],
[Events.EventKey:"Impressions & Expressions in MG Road", Events.EntryTypeKey: "Free Entry", Events.ImageNameKey:"ImpressionAndExpression"],
[Events.EventKey:"Italian carnival in Electronic City", Events.EntryTypeKey: "Free Entry", Events.ImageNameKey:"ItalianCarnival"]
]
}
}
Create properties in your destination viewController and use them like below
import UIKit
class DetailedEventViewController: UIViewController {
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var deatiledEvent: UILabel!
#IBOutlet weak var eventType: UILabel!
var myImage = UIImage?
var eventDetails = ""
var typeOfEvent = ""
override func viewDidLoad() {
super.viewDidLoad()
imageView.image = myImage
deatiledEvent.text = eventDetails
eventType.text = typeOfEvent
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
and then in your first viewController you can access them like
let dest = segue.destinationViewController as! DetailedEventViewController
dest.eventDetails = nextScreenRow.eventName
dest.typeOfEvent = nextScreenRow.entryType
dest.myImage = UIImage(named: nextScreenRow.imageName)

Resources