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)
}
}
Related
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)
I have table where I can add some empty cells. Using protocol I can send some data to each cell. When I am looking into the table I can see all the information I sent. My problem happens when try to save date using realm, only save last sent data to cell.
// model:
import UIKit
import RealmSwift
class HITActionModel: Object {
#objc dynamic var seconds: Int = 0
#objc dynamic var color: String = ""
#objc dynamic var name: String = ""
#objc dynamic var id: Int = 0
var parentWorkout = LinkingObjects(fromType: WorkoutModel.self, property: "actionsArray")
}
class WorkoutModel: Object {
#objc dynamic var title: String?
#objc dynamic var rounds: Int = 0
var actionsArray = List<HITActionModel>()
}
//protocol
protocol HITActionCellDelegate {
func action(sec: Int, name: String, id: Int)
}
//custom cell
class HITActionCell: UITableViewCell {
//MARK: - Properties
#IBOutlet weak var changeColorBtn: UIButton!
#IBOutlet weak var actionLabel: UILabel!
#IBOutlet weak var actionNameTextField: UITextField!
var delegate: HITActionCellDelegate?
var numberOfSeconds = 0
var id = 0
//MARK: - Lifecycle
override func awakeFromNib() {
super.awakeFromNib()
selectionStyle = .none
}
//MARK: - Elements setup
func setupElements() {
actionNameTextField.placeholder = "Add name for Action!"
changeColorBtn.backgroundColor = UIColor.neonYellow
actionLabel.text = "Entry seconds for action"
}
#IBAction func addActionSeconds(_ sender: Any) {
numberOfSeconds += 1
actionLabel.text = "\(numberOfSeconds) SECONDS"
delegate?.action(sec: numberOfSeconds, name: actionNameTextField.text ?? "", id: self.id)
}
#IBAction func reduceActionSeconds(_ sender: Any) {
if numberOfSeconds > 0 {
numberOfSeconds -= 1
actionLabel.text = "\(numberOfSeconds) SECONDS"
delegate?.action(sec: numberOfSeconds, name: actionNameTextField.text ?? "", id: self.id)
}
}
}
// From here I send data using Protocol to viewController :
import UIKit
import RealmSwift
class AddActionViewController: UIViewController {
//MARK: - Properties
let workout = WorkoutModel()
let action = HITActionModel()
let realm = try! Realm()
var numberOfRounds = 0
#IBOutlet weak var workoutNameTextField: UITextField!
#IBOutlet weak var workoutNameLabel: UILabel!
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var roundsLabel: UILabel!
#IBOutlet weak var addRounds: UIButton!
#IBOutlet weak var reduceRounds: UIButton!
#IBOutlet weak var saveButton: UIButton!
#IBOutlet weak var cancelButton: UIButton!
#IBOutlet weak var addActionButton: UIButton!
//MARK:- Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
print(Realm.Configuration.defaultConfiguration.fileURL)
tableView.delegate = self
tableView.dataSource = self
tableView.separatorStyle = .none
tableView.register(UINib(nibName: Const.UI.NibName.hiActionCell, bundle: nil), forCellReuseIdentifier: Const.UI.CellIdentifier.hiActionCell)
}
//MARK:- Elements setup
func setupUI() {
view.backgroundColor = UIColor.black
title = Const.NameString.workouts
addActionButton.setTitle(Const.NameString.addAction, for: .normal)
addActionButton.tintColor = UIColor.black
addActionButton.titleLabel?.font = UIFont.textStyle9
workoutNameLabel.text = Const.NameString.workoutName
workoutNameLabel.font = UIFont.textStyle7
workoutNameLabel.textColor = UIColor.white
workoutNameTextField.textColor = UIColor.black
workoutNameTextField.font = UIFont.textStyle8
roundsLabel.text = Const.NameString.startingRounds
roundsLabel.font = UIFont.textStyle9
roundsLabel.textColor = UIColor.black
roundsLabel.textAlignment = .center
}
#IBAction func saveButtonAction(_ sender: Any) {
if workoutNameTextField.text != "" {
workout.title = workoutNameTextField.text!
workout.rounds = numberOfRounds
save(workout)
self.dismiss(animated: true, completion: nil)
} else {
let myalert = UIAlertController(title: "Message", message: "You forgot something to add ;) (name, rounds, seconds)", preferredStyle: UIAlertController.Style.alert)
myalert.addAction(UIAlertAction.init(title: "I'm guilty", style: .default, handler: nil))
self.present(myalert, animated: true)
}
}
func save(_ workout: WorkoutModel) {
do {
try realm.write {
realm.add(workout)
}
} catch {
print(error.localizedDescription)
}
}
#IBAction func cancelButtonAction(_ sender: Any) {
self.dismiss(animated: true, completion: nil)
}
#IBAction func addActionButtonPressed(_ sender: Any) {
workout.actionsArray.append(action)
tableView.beginUpdates()
tableView.insertRows(at: [IndexPath(row: workout.actionsArray.count - 1, section: 0)], with: .fade)
tableView.endUpdates()
}
#IBAction func addRoundsBtn(_ sender: Any) {
numberOfRounds += 1
roundsLabel.text = "\(numberOfRounds) ROUNDS"
}
#IBAction func reduceRoundsBtn(_ sender: Any) {
if numberOfRounds > 0 {
numberOfRounds -= 1
roundsLabel.text = "\(numberOfRounds) ROUNDS"
}
}
}
//MARK:- Setup TextFieldDelegate Method
extension AddActionViewController: UITextFieldDelegate {
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
view.endEditing(true)
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
workoutNameTextField.resignFirstResponder()
return true
}
}
//Quick guide implementation for showing and deleting cells
extension AddActionViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return workout.actionsArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: Const.UI.CellIdentifier.hiActionCell) as? HITActionCell else {
return UITableViewCell()
}
cell.delegate = self
cell.setupElements()
cell.id = indexPath.row
return cell
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == .delete) {
workout.actionsArray.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
}
if (editingStyle == .insert) {
print("test")
}
}
extension AddActionViewController: HITActionCellDelegate {
func action(sec: Int, name: String, id: Int) {
action.name = name
action.seconds = sec
action.id = id
}
}
If could someone help me, It would be greet for me :)
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."
}
}
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)
}
I have a tableView as initial controller and few labels in secondViewController.
When I create a cell with data I want, the idea is to display that data in the secondViewController labels. All works fine, BUT, the labels in the secondVC update only when I hit the back button, to go back to the table view and select the row again.
How can I update the data displayed in the secondVC on the first tap in the tableview cell?
enter code here
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
var titles = [String]()
var subjects = [String]()
var previews = [String]()
var textFieldsText = [UITextField!]()
var selectedTitle: String!
var selectedSubject: String!
var selectedPreview: String!
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Add, target: self, action: "addTitle")
}
override func viewDidAppear(animated: Bool) {
tableView.reloadData()
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
cell.textLabel?.text = titles[indexPath.row]
cell.detailTextLabel?.text = subjects[indexPath.row]
return cell
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return titles.count
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
selectedTitle = self.titles[indexPath.row]
selectedSubject = self.subjects[indexPath.row]
selectedPreview = self.previews[indexPath.row]
tableView.reloadData()
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showPreview" {
let dataToPass = segue.destinationViewController as! previewViewController
dataToPass.titlesString = selectedTitle
dataToPass.subjectsString = selectedSubject
dataToPass.previewsString = selectedPreview
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func addTitle() {
let addAlert = UIAlertController(title: "New Title", message: "Add new title, subject and a short preview", preferredStyle: .Alert)
addAlert.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))
addAlert.addTextFieldWithConfigurationHandler {[unowned self] textField in
textField.placeholder = "Add Title"
textField.textAlignment = .Center
self.textFieldsText.append(textField)
}
addAlert.addTextFieldWithConfigurationHandler { textField in
textField.placeholder = "Add Subject"
textField.textAlignment = .Center
self.textFieldsText.append(textField)
}
addAlert.addTextFieldWithConfigurationHandler { textField in
textField.placeholder = "Add Short Preview"
textField.textAlignment = .Center
self.textFieldsText.append(textField)
}
addAlert.addAction(UIAlertAction(title: "Done", style: .Default){ _ in
self.titles.append(self.textFieldsText[0].text!)
self.subjects.append(self.textFieldsText[1].text!)
self.previews.append(self.textFieldsText[2].text!)
self.tableView.reloadData()
self.textFieldsText.removeAll()
})
presentViewController(addAlert, animated: true, completion: nil)
}
}
class previewViewController: UIViewController {
#IBAction func readButton(sender: UIButton) {
}
#IBOutlet weak var titleLabel: UILabel!
#IBOutlet weak var subjectLabel: UILabel!
#IBOutlet weak var shortPreviewLabel: UITextView!
var titlesString: String!
var subjectsString: String!
var previewsString: String!
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Save, target: self, action: "saveChanges")
titleLabel.text = titlesString
subjectLabel.text = subjectsString
shortPreviewLabel.text = previewsString
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showDetail" {
let dataToDetail = segue.destinationViewController as! detailViewController
dataToDetail.textViewString = self.previewsString
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
If I understand your question right, this may help:
use this didSelectRowAtIndexPath:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
performSegueWithIdentifier("showPreview", sender: indexPath.row)
}
use this prepareForSegue:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showPreview" {
let destinationViewController = segue.destinationViewController as! previewViewController
if let index = sender as? Int {
destinationViewController.titlesString = self.titles[index]
destinationViewController.subjectsString = self.subjects[index]
destinationViewController.previewsString = self.previews[index]
}
}
}
And you need to have a segue from ViewController to previewViewController called "showPreview". Like this: