Passing data from 2 Tableviews to ViewController - swift3

I'm trying to pass data from tableView1 and tableView2 one at a time to MainVC via segues from textfields, the problem is MainVC.textField is not keeping the value of the previous tableView data, looks like is creating a new MainVC all the time, here is the code from the tableView which is the same for the second tableView.
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let indexPath = self.itemTableView.indexPathForSelectedRow
let currentCell = tableView.cellForRow(at: indexPath!) as! ItemCell
itemToPass = currentCell.itemName?.text
performSegue(withIdentifier: "toEnterItem", sender: self)
}
and
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toEnterItem" {
let enterItemVC = segue.destination as! MainVC
MainVC.passedItem = itemToPass
}
}
Any help will be appreciated. Thanks

Problem solved, I used protocols to temporarily persist the data in textfields after segue.
protocol sendName {
func sendToLastVC{name: String)
}

Related

How to get selected index of items in more navigation controller

I use below code for get selected items of tab bar controller. My UITabbar has 7 view controllers(there are 3 items in More tab).
this code work only for 5 tabs but it don`t return selected index of items on More!
import UIKit
class CustomTabbarController: UITabBarController{
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
}
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
print(self.selectedIndex)
}
}
Following code worked for me. I had to redesign moreTableView to follow my app design. Function 'didSelectRowAt' returns what index is selected.
This code is added to 'UITabBarController' class.
var moreTableView: UITableView?
weak var currentTableViewDelegate: UITableViewDelegate?
func customizeMoreTableView() {
moreTableView = moreNavigationController.topViewController?.view as? UITableView
currentTableViewDelegate = moreTableView?.delegate
moreTableView?.delegate = self
moreTableView?.dataSource = self
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (viewControllers?.count ?? 4) - 4
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let moreCell = UITableViewCell()
let item = viewControllers?[indexPath.row + 4].tabBarItem
moreCell.textLabel?.text = item?.title
moreCell.textLabel?.textColor = .white
moreCell.imageView?.image = item?.image
moreCell.imageView?.tintColor = .white
moreCell.backgroundColor = .black
return moreCell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
currentTableViewDelegate?.tableView!(tableView, didSelectRowAt: indexPath)
}
Get selected item like this :
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
print(tabBar.items?.index(of: item))
}

Presenting a UIViewController with a button or UIImageview in a UITableViewCell

I am trying to make it when the users clicks on Button in a table view cell it takes them to a new view controller related to the current cell.
Try the below code,
Do this in cellForRowAt indexPath,
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell_Identifier", for: indexPath) as! UITableViewCell
cell.myButton.isUserInteractionEnabled = true
cell.myButton.tag = indexPath.row
cell.myButton.addTarget(self, action: #selector(didTapMyButton(_:)), for: UIControlEvents.touchUpInside)
return cell
}
And here is the button action,
func didTapMyButton(_ sender : UIButton) {
let selectedIndex = sender.tag // You can get index here, so according to the index you can navigate to particular ViewController
let nextVC = self.storyboard?.instantiateViewController(withIdentifier: "UIViewController_identifier") as! UIViewController
self.present(nextVC, animated: true, completion: nil)
}
Hope it helps ..

Swift: Prepare for segue not passing data

I have got a collection view inside a table view (Netflix App Style). I followed this tutorial: https://www.thorntech.com/2016/01/scrolling-in-two-directions-like-netflix-part-2-making-api-calls/
Now I want to implement a function that whenever I click on a collection view, it will pass the employee's name to the next view controller.
Here is my code:
import UIKit
class CategoryRow: UITableViewCell, UICollectionViewDataSource {
#IBOutlet weak var collectionView: UICollectionView!
var jobpost:JobPosition?
var employee: Employee?
var myname = ""
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return jobpost!.Employees.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "videoCell", for: indexPath) as! EmployeeCell
cell.employeephoto.image = UIImage(named: "spanner")
cell.employeename.text = jobpost?.Employees[indexPath.row].name
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let myname = jobpost?.Employees[indexPath.row].name
//print(myname)
}
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let EmployeeDetailPage = segue.destination as? EmployeeDetailViewController
EmployeeDetailPage?.employeename = myname
print(myname)
}
Now my problem is, the whole PrepareForSegue function didn't actually run. The app runs normally without any error but the data just didn't pass through? (i.e. the print(myname) didn't actually print anything).
Is there something I missed out? Very much appreciated.
Step 1
Create a global variable in your CategoryRow
var myname: String!
Step 2
Change the didSelectItemAt func like below
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
myname = jobpost?.Employees[indexPath.row].name
performSegue(withIdentifier: "EmployeeDetailViewController", sender: myname)
}
Step 3
Create a variable in EmployeeDetailViewController
var employeename: String!
Step 4
Give a identifier to your segue. Here I give "EmployeeDetailViewController"
Then change the prepareForSegue func like below
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "EmployeeDetailViewController" {
if let EmployeeDetailVC = segue.destination as? EmployeeDetailViewController {
EmployeeDetailVC.employeename = myname
}
}
}
It looks like your problem is that you are setting a local let constant called myname in your collectionView(_:didSelectItemAt:) method instead of setting your class's myname property.
let myname = jobpost?.Employees[indexPath.row].name
should be:
myname = jobpost?.Employees[indexPath.row].name

Can't get Cell Swipe Actions to work

It's been awhile since I've made a fool of myself here, so here goes again as I'm still trying to learn and feel as though I'm chasing my tail on this project.
With that said, ultimately I would like to get Jerkoch's SwipeCellKit to work, but not necessary at this point as I just need to figure out how to add more options other than just the 'delete' cell action.
This is what I've got: My Project
This is what I'd like: Jerkoch's Project
I loose my data if I set the delegate property on tableView from
let cell = tableView.dequeueReusableCell(withIdentifier: "CommentCell", for: indexPath) as! CommentTableViewCell
to
let cell = tableView.dequeueReusableCell(withIdentifier: "CommentCell", for: indexPath) as! SwipeTableViewCell
Here is my CommentViewController Code:
import UIKit
import SwipeCellKit
class CommentViewController: UIViewController {
var postId: String!
var comments = [Comment]()
var users = [User]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.tableFooterView = UIView(frame: CGRect.zero)
tableView.separatorInset = UIEdgeInsets.zero
tableView.dataSource = self
tableView.estimatedRowHeight = 100
tableView.rowHeight = UITableViewAutomaticDimension
loadComments()
}
func loadComments() {
Api.Post_Comment.REF_POST_COMMENTS.child(self.postId).observe(.childAdded, with: {
snapshot in
Api.Comment.observeComments(withPostId: snapshot.key, completion: {
comment in
self.fetchUser(uid: comment.uid!, completed: {
self.comments.append(comment)
self.tableView.reloadData()
})
})
})
}
func fetchUser(uid: String, completed: #escaping () -> Void ) {
Api.User.observeUser(withId: uid, completion: {
user in
self.users.append(user)
completed()
})
}
}
extension CommentViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return comments.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CommentCell", for: indexPath) as! CommentTableViewCell// Can't update this to SwipeTableViewCell - Will loose data
cell.selectedBackgroundView = createSelectedBackgroundView()
let comment = comments[indexPath.row]
let user = users[indexPath.row]
cell.comment = comment
cell.user = user
cell.delegate = self
return cell
}
}
extension CommentViewController: SwipeTableViewCellDelegate{
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> [SwipeAction]? {
guard orientation == .right else { return nil }
let deleteAction = SwipeAction(style: .destructive, title: "Delete") { action, indexPath in
// handle action by updating model with deletion
}
// customize the action appearance
deleteAction.image = UIImage(named: "delete")
let flagAction = SwipeAction(style: .destructive, title: "Flag") { action, indexPath in
// handle action
}
deleteAction.image = UIImage(named: "flag")
let blockAction = SwipeAction(style: .destructive, title: "Block") { action, indexPath in
// handle action
}
deleteAction.image = UIImage(named: "block")
return [deleteAction, flagAction, blockAction]
}
}
I've even tried something like the following:
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
// THIS GIVES THE DEFAULT 'DELETE' ACTION
print("Commit editingStyle")
}
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
print("editActionsForRowAtIndexPath")
let blockAction = UITableViewRowAction(style: UITableViewRowActionStyle.normal, title: "Block", handler: { (action:UITableViewRowAction, IndexPath:IndexPath) in
//self.isEditing = false
print("Block action Pressed")
})
let flagAction = UITableViewRowAction(style: UITableViewRowActionStyle.normal, title: "Flag", handler: { (action:UITableViewRowAction, IndexPath:IndexPath) in
print("Flag action Pressed")
})
let deleteAction = UITableViewRowAction(style: UITableViewRowActionStyle.destructive, title: "Delete", handler: { (action:UITableViewRowAction, IndexPath:IndexPath) in
print("Delete action Pressed")
})
return [blockAction, flagAction, deleteAction]
}
No matter what I do, I can't get more than just the generic 'Delete' action to show on a swipe action.
I don't even think the following function is being called/referenced:
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
What am I doing wrong, or what do I need to CUD to get 3 swipe actions; Delete, Flag and Block, to make Apple happy for my next submission.
Thank you all in advance!
This question is outdated but i'll write the answer which i think would have done the trick :)
You should be using UITableViewController not UIViewController for your view. SwipeCellKit only works with TableViewControllers.

Issue with "didSelectRowAt indexPath" in Swift 3

I'm pretty new to swift but I've managed to follow along for the most part. However, there's an issue with my code that the code itself can't even identity apparently(I'm not receiving any error signs). I'm trying to click on a row from the table view to make it go to the following page but I don't think the code is recognizing the didselectrow method. Maybe one of you more experienced persons can help me out.
Here's the code:
import UIKit
import Foundation
class OnePercentersViewController: UIViewController, UITableViewDataSource
{
var copiedExecutiveArray : [String] = NSArray() as! [String]
var identities : [String] = NSArray() as! [String]
override func viewDidLoad()
{
super.viewDidLoad()
let copyExecutiveNames : ExecutiveArray = ExecutiveArray()
copiedExecutiveArray = copyExecutiveNames.executiveNames
identities = copyExecutiveNames.executiveNames
}
//how many sections in table
func numberOfSections(in tableView: UITableView) -> Int
{
return 1
}
//returns int (how many rows)
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return copiedExecutiveArray.count
}
//contents of each cell
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")//UITableViewCell()
let personName = copiedExecutiveArray[indexPath.row]
cell?.textLabel?.text = personName
return cell!
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
let execName = identities[indexPath.row]
let viewController = storyboard?.instantiateViewController(withIdentifier: execName)
self.navigationController?.pushViewController(viewController!, animated: true)
print("button clicked")
tableView.deselectRow(at: indexPath as IndexPath, animated: true)
}
}
I haven't checked other parts of your code, but to make tableView(_:didSelectRowAt:) work, your ViewController needs to conform to UITableViewDelegate:
class OnePercentersViewController: UIViewController, UITableViewDataSource, UITableViewDelegate
Also you need to connect the delegate of the UITableView to your ViewController in your storyboard. Or you can do it in code, if you have an #IBOutlet to the UITableView. Anyway, not only dataSource, but also delegate.
And this is not a critical issue, but you can write the first two lines of the class as:
var copiedExecutiveArray : [String] = []
var identities : [String] = []
After spending a day and a half watching Youtube videos and reading comments to similar problems, tt took trial and error but I finally got it thanks to you guys!It finally clicked when I read that I had to connect the delegate to the ViewController through the storyboard, so thanks for that!
Here's the final code for those with similar issue:
import UIKit
import Foundation
class OnePercentersViewController: UIViewController,UITableViewDataSource, UITableViewDelegate
{
var copiedExecutiveArray : [String] = []
var identities : [String] = []
override func viewDidLoad()
{
super.viewDidLoad()
let copyExecutiveNames : ExecutiveArray = ExecutiveArray()
copiedExecutiveArray = copyExecutiveNames.executiveNames
identities = copyExecutiveNames.executiveNames
}
//how many sections in table
func numberOfSections(in tableView: UITableView) -> Int
{
return 1
}
//returns int (how many rows)
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return copiedExecutiveArray.count
}
//contents of each cell
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let personName = copiedExecutiveArray[indexPath.row]
cell.textLabel?.text = personName
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
let execName = identities[indexPath.row]
let viewController = storyboard?.instantiateViewController(withIdentifier: execName)
self.navigationController?.pushViewController(viewController!, animated: true)
tableView.deselectRow(at: indexPath as IndexPath, animated: true)
}
}