Prepare for segue delay. Information is lagging but being presented - swift

I'm pushing otherUserUid and otherUserFullName to another view controller but it isn't being call immediately. The information is lagging behind and it takes 2 clicks for the information to appear.
I think preparForSegue: is being called before didSelectRowAtIndexPath: Any solutions how to fix this?
Cheers!
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier("jsqDirectory", sender: self)
let indexPath = tableView.indexPathForSelectedRow!
let currentCell = tableView.cellForRowAtIndexPath(indexPath)! as UITableViewCell
self.otherUserFullName = (currentCell.textLabel?.text)!
print(self.otherUserFullName)
self.otherUserUid = (currentCell.detailTextLabel?.text)!
print(self.otherUserUid)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "jsqDirectory" {
if let viewController = segue.destinationViewController as? JSQViewController{
viewController.senderDisplayName = self.fullName
viewController.senderId = self.firebase.authData.uid
viewController.otherUid = self.otherUserUid
viewController.otherUser = self.otherUserFullName
}
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("directoryCell") as UITableViewCell!
let directoryItem = items[indexPath.row]
cell.textLabel?.text = directoryItem.fullName
cell.detailTextLabel!.text = directoryItem.key
cell.detailTextLabel!.hidden = true
return cell
}

in didSelectRowAtIndexPath you have to perform segue at the end of Function like thiss..
let indexPath = tableView.indexPathForSelectedRow!
let currentCell = tableView.cellForRowAtIndexPath(indexPath)! as UITableViewCell
self.otherUserFullName = (currentCell.textLabel?.text)!
print(self.otherUserFullName)
self.otherUserUid = (currentCell.detailTextLabel?.text)!
print(self.otherUserUid)
self.performSegueWithIdentifier("jsqDirectory", sender: self)

Related

Passing selected cell's label text, return nil when first time (delay in data sent)

I'm passing the selected cell's label text to another view controller but It will return nil when every first time I select. After that I go back and select again, I will get the previous selected cell's text.Why?
var jobDateValueB:String!
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return jobTime.count //JSON Data from server
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "jobCell", for: indexPath)
let unixTimestamp = Double(jobTime[indexPath.row])
let unixTimestamp2 = Double(jobEndTime[indexPath.row])
let date1 = Date(timeIntervalSince1970: unixTimestamp)
let date2 = Date(timeIntervalSince1970: unixTimestamp2)
dateFormatter.dateFormat = "h:mm a"
let strDate = dateFormatter.string(from: date1)
let endDate = dateFormatter.string(from: date2)
cell.textLabel?.text = "\(strDate) - \(endDate)"
return cell
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showEdit"{
let destinationB = segue.destination as? EditTimeTableVC
destinationB?.passedDataB = jobDateValueB
}
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.performSegue(withIdentifier: "showEdit", sender: self)
let indexPath = self.tableView.indexPathForSelectedRow;
let currentCell = self.tableView.cellForRow(at: indexPath!) as UITableViewCell!;
jobDateValueB = currentCell?.textLabel!.text!
}
EditTimeTableVC
var passedDataB: String!
override func viewDidLoad() {
super.viewDidLoad()
print(passedDataB)
}
In didSelectRowAt method you are calling self.performSegue first and then setting jobDateValueB. Try moving self.performSegue call to end of the function.
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let indexPath = self.tableView.indexPathForSelectedRow;
let currentCell = self.tableView.cellForRow(at: indexPath!) as UITableViewCell!;
jobDateValueB = currentCell?.textLabel!.text!
self.performSegue(withIdentifier: "showEdit", sender: self)
}
This should solve your problem but it's not the recommended way. Instead of assigning the selected text value to a class variable you pass it as sender. like this.
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let indexPath = self.tableView.indexPathForSelectedRow;
let currentCell = self.tableView.cellForRow(at: indexPath!) as UITableViewCell!;
if let value = currentCell?.textLabel?.text? {
self.performSegue(withIdentifier: "showEdit", sender: value)
}
}
And in your prepare method you can do.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showEdit"{
let destinationB = segue.destination as? EditTimeTableVC
if let selectedText = sender as? String {
destinationB?.passedDataB = selectedText
}
}
}

sending customCell label text to destination view

I am stuck on this problem. I am downloading a json file from Firebase and successfully displaying in a TableView. That TableView has a custom cell with two labels. I have set up a segue link from the custom cell to a Detail ViewController. That works fine, but now I want to take the text content of the cell labels and send to a destination ViewController.
I have had no trouble doing this in the past, but am having trouble implementing this from the label.text in a custom cell.
I am using label tags (label1 and label2, although I may change that to the label names sometime).
The question is, how do I get the text contents from the two labels from the row selected and pass those to the DetailViewController? All my attempts so far have failed. Is there something I should be doing in the:
valueToPass = currentCell?.textLabel?.text
Here is the code:
struct postStruct {
let property : String!
let propType : String!
}
class TableViewController: UITableViewController {
var posts = [postStruct]()
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.delegate = self
self.tableView.dataSource = self
let databaseRef = FIRDatabase.database().reference()
databaseRef.child("users").queryOrderedByKey().observe(.childAdded, with: {
snapshot in
let snapshotValue = snapshot.value as? NSDictionary
let property = snapshotValue!["property"] as? String
let propType = snapshotValue!["type"] as? String
self.posts.insert(postStruct(property: property, propType: propType), at: 0)
self.tableView.reloadData()
})
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")
let label1 = cell?.viewWithTag(1) as! UILabel
label1.text = posts[indexPath.row].property
let label2 = cell?.viewWithTag(2) as! UILabel
label2.text = posts[indexPath.row].propType
// print(posts)
// cell.setcell(valueToPass.label1)
return cell!
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
var valueToPass:String!
func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
// Get Cell Label
let indexPath = tableView.indexPathForSelectedRow;
let currentCell = tableView.cellForRow(at: indexPath!) as UITableViewCell!;
valueToPass = currentCell?.textLabel?.text
performSegue(withIdentifier: "detailSegue", sender: self)
}
Any help most welcome, in particular code examples. Many thanks in anticipation
Create a custom class for your tableCell, and attach outlets in the StoryBoard.
the cell creation in cellForRowAt becomes
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") As! MyCustomCell
cell.label1.text = posts[indexPath.row].property
cell.label2.text = posts[indexPath.row].propType
and then didSelectRowAtIndexPath becomes
let indexPath = tableView.indexPathForSelectedRow
let currentCell = tableView.cellForRow(at: indexPath!) as! MyCustomCell
self.valueToPass = currentCell.label1?.text
performSegue(withIdentifier: "detailSegue", sender: self)
The final thing you need if to prepare for the segue
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if segue.identifier == "detailSegue" // you may have more than one segue, so you should check
{
let destinationController : DestinationViewControllerClass = segue.destination as! DestinationViewControllerClass
destinationController.valueToPass = self.valueToPass
}
}

Passing Data between TableView in Swift

I have two tableView running in my project.I am trying to pass(copy) my first tableViewcell data to second tableView.I using tableView row action method to pass data.My partial code below...
First VC:
var tableView: UITableView!
var DataArray = ["Bus","Helicopter","Truck","Boat","Bicycle","Motorcycle","Plane","Train","Car","S cooter","Caravan"]
var sendSelectedData = NSString()
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let copyAction = UITableViewRowAction(style: UITableViewRowActionStyle.normal, title: "Pass Data") { (UITableViewRowAction, NSIndexPath) -> Void in
print("Button Pressed") // Xcode Console prints **Button Pressed** when swipe action performed.
self.performSegue(withIdentifier: "send", sender: self)
}
return [copyAction]
}
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
self.performSegue(withIdentifier: "send", sender: self)
// segue.destination as! tableController
let indexPath = tableView.indexPathForSelectedRow
let currentCell = tableView.cellForRow(at: indexPath!)!
self.sendSelectedData = (currentCell.textLabel?.text)! as String as NSString
let viewController = segue.destination as! tableController
viewController.labelcell = ([self.sendSelectedData as String])
print(self.sendSelectedData) // no result
}
Second VC:
var labelcell = [String]()
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: textCellIdentifier, for: indexPath as IndexPath) as UITableViewCell
cell.textLabel?.text = labelcell[indexPath.row] as? String
tableView.reloadData()
return cell
}
Above code looks like passing data to my second VC(segue).But, I am only getting a empty tableview..
Okay after testing it, it turns out, that you're using an incorrect prepareForSegue function. You are not using "prepareForSegue", you are creating a function called prepareForSegue - since the syntax has changed in Swift 3. This one will get called and you can pass data.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "send" {
let selectedIndex = sender as! NSIndexPath
let currentCell = tableView.cellForRow(at: selectedIndex as IndexPath)! as! Cell
self.sendSelectedData = (currentCell.label?.text)! as String as NSString
print(self.sendSelectedData) // till here it worked for me - it is filled with my label.text
// I don't know what this is "viewController.labelcell", so you have to to know how to go on from here on
viewController.labelcell = ([self.sendSelectedData as String])
}
}
Also you need to pass the indexPath:
self.performSegue(withIdentifier: "send", sender: indexPath)
Exactly like this:
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let copyAction = UITableViewRowAction(style: UITableViewRowActionStyle.normal, title: "Pass Data") { (UITableViewRowAction, NSIndexPath) -> Void in
print("editActionsForRowAt called") // Xcode Console prints **Button Pressed** when swipe action performed.
self.performSegue(withIdentifier: "send", sender: indexPath)
}
return [copyAction]
}
This worked in my testing project.
Also beware: Cell is a custom subclass of UITableViewCell I have created and label is an UIOutlet of a label element for my test project.

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
}

Segue not sending correct cell info in Swift

I have a tableView that triggers a segue to a detail view when a cell is pressed. The table contains a list of users that the currentUser is friends with. Pressing the cell loads the view for that user (name, profile, etc). It's a very simple app I'm creating to learn how to program.
The problem is that when I press on a cell, it's always loading the user info for the last user in the table (and also happens to be the most recent "friend" that the user made). I have a feeling that the issue is with an if statement I have in the tableView function:
extension MatchesViewController: UITableViewDataSource
{
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return numberOfMatches
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("MatchCell", forIndexPath: indexPath)
if PFUser.currentUser()!.objectId == self.user1.objectId{
let user = matchesResults[indexPath.row]["user2"] as! PFUser
cell.textLabel?.text = user["first_name"] as! String
self.viewUser = user
}
if PFUser.currentUser()!.objectId == self.user2.objectId{
let user = matchesResults[indexPath.row]["user1"] as! PFUser
cell.textLabel?.text = user["first_name"] as! String
self.viewUser = user
}
return cell
}
}
Here's the segue code, but I don't think there is an issue with it (although I could be wrong):
extension MatchesViewController: UITableViewDelegate
{
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
self.performSegueWithIdentifier("UserSegue", sender: "viewUser")
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "UserSegue") {
let destinationVC = segue.destinationViewController as! UserViewController
destinationVC.user = self.viewUser
}
}
}
Any ideas? If there is an issue with my tableView If statement, how can I fix it?
Thanks!
You can get the user object by indexPath, than pass it through the sender parameter of the performSegueWithIdentifier method
extension MatchesViewController: UITableViewDelegate
{
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
let user:PFUser?
if PFUser.currentUser()!.objectId == self.user1.objectId{
user = matchesResults[indexPath.row]["user2"] as! PFUser
}
if PFUser.currentUser()!.objectId == self.user2.objectId{
user = matchesResults[indexPath.row]["user1"] as! PFUser
}
self.performSegueWithIdentifier("UserSegue", sender: user)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// sender is the user object
if (segue.identifier == "UserSegue") {
let destinationVC = segue.destinationViewController as! UserViewController
destinationVC.user = sender // maybe you need cast sender to UserObject
}
}
}