how to get data when cell accessory is tapped in ios - ios

i have tableview which has several cells, when user tap on the cell it does some other function and when cell accessory is tapped i want it to segue to another view controller
i am able to do so but the problem is i am not able to send the data at cell indexpath row, in order to send data i first have to touch the cell then tap on accessory to send the data here is the code for tableview
func tableView(_ tableView: UITableView, accessoryButtonTappedForRowWith indexPath: IndexPath) {
myTableView.selectRow(at: indexPath, animated: true, scrollPosition: .none)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segue.identifier {
case "ShowDetail":
if let ip = myTableView.indexPathForSelectedRow{
if let svc = segue.destination as? DetailViewController{
svc.selectedObject = (myCounters?[ip.row])!
}
}
default:
print("error in segue")
}
}

func tableView(_ tableView: UITableView, accessoryButtonTappedForRowWith indexPath: IndexPath) {
let vc = storyboard?.instantiateViewController(withIdentifier: "detailvc") as? DetailViewController
vc?.selectedObject = (myCounters?[indexPath.row])!
navigationController?.present(vc!, animated: true, completion: nil)
}

thanks to #shahzaib qureshi
i removed the segue connection and use instantiate view controller method as detail view controller in cell accessory tapped method
func tableView(_ tableView: UITableView, accessoryButtonTappedForRowWith indexPath: IndexPath) {
let vc = storyboard?.instantiateViewController(withIdentifier: "detailvc") as? DetailViewController
vc?.selectedObject = (myCounters?[indexPath.row])!
navigationController?.present(vc!, animated: true, completion: nil)
print("ewwewew")
}

Just pass the index path in the sender parameter, pretty easy:
func tableView(_ tableView: UITableView, accessoryButtonTappedForRowWith indexPath: IndexPath) {
performSegue(withIdentifier: "ShowDetail", sender: indexPath)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "ShowDetail" {
let indexPath = sender as! IndexPath
let svc = segue.destination as! DetailViewController
svc.selectedObject = myCounters![indexPath.row]
}
}

Try this,

func tableView(_ tableView: UITableView, accessoryButtonTappedForRowWith indexPath: IndexPath) {
print("Index : \(indexPath.row)")
var tempIndex: Int!
var tempIdentifier: String!
self.tempIndex = indexPath.row //You can store indexpath.row value in temp variable. And then then you can access it while performing any other functions.
self.tempIdentifier = "ShowDetail" //This upto your needs.
}
//UIStoryboardSegue to move over another controller accordingly.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segue.identifier {
case "ShowDetail":
if let ip = myTableView.indexPathForSelectedRow{
if let svc = segue.destination as? DetailViewController{
svc.selectedObject = (myCounters?[tempIndex])!
}
}
default:
print("error in segue")
}
}

Related

How to pass tableView label to name variable in another viewController?

I'm creating an app for a school project, and I have a tableView with a label inside which contains the name of the cell, and I am trying to pass the name of the label to the navTitle variable on my second viewController. I have tried multiple ways of achieving this but have had no luck.
I have tried printing the passed title but it prints the output 'nil'
Home view
var names = ["Accomodation", "Facilities", "Things To Do", "About"]
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return names.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "homeCell", for: indexPath) as? homeTableViewCell
cell?.label.text = names[indexPath.row]
return cell!
}
//Passing data
var nameChosen : String?
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.tableView.deselectRow(at: indexPath, animated: true)
nameChosen = names[indexPath.row]
performSegue(withIdentifier: "accomodationSegue", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let destinationVC = segue.destination as? accomodationViewController
destinationVC?.navTitle = nameChosen
}
Accomodation view
var navTitle: String?
override func viewDidLoad() {
super.viewDidLoad()
print(navTitle)
// Do any additional setup after loading the view.
}
The easiest way is to pass the name as sender parameter, the property nameChosen is not needed.
And it's good practice to check the identifier of the segue in prepare(for segue
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.tableView.deselectRow(at: indexPath, animated: true)
let name = names[indexPath.row]
performSegue(withIdentifier: "accomodationSegue", sender: name)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard segue.identifier == "accomodationSegue" else { return }
let destinationVC = segue.destination as! accomodationViewController
destinationVC.navTitle = sender as! String
}
If the code crashes you made a design mistake.
And please name classes always with starting uppercase letter (AccomodationViewController).

Cant trigger segue when selecting a table view cell (at once)

I am making a todo list app and have two View Controllers and I have to pass the Index Path of the selected row from the CategoryViewController to ItemsViewController and trigger the Segue...
This Is my Category View Controller
But when I Click one of the cell, it is just being selected but the segue is not triggered
Heres How
But the segue is triggered when I select another Cell after selecting First one...Here's My code
override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "goToItems", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
print("sucess")
let destinationVC = segue.destination as! ToDoListViewControlorer
if let indexPath = tableView.indexPathForSelectedRow {
destinationVC.selectedCategory = categoriesArray[indexPath.row]
}
}
Send your indexPath.row in sender argument of performSegue
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
performSegue(withIdentifier: "youridentifier", sender: indexPath.row)
}
get indexPath.row from the sender argument and pass to ToDoListViewControlorer
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
print("sucess")
let destinationVC = segue.destination as! ToDoListViewControlorer
if let indexPathRow = sender as? Int {
destinationVC.selectedCategory = categoriesArray[indexPathRow]
}
}
First, override didSelectRowAt method, because you want to handle moment when user select row, not deselect. Also as sender pass selected item
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "goToItems", sender: categoriesArray[indexPath.row])
}
and then in prepare(for:sender:) just downcast sender
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destinationVC = segue.destination as? ToDoListViewControlorer {
destinationVC.selectedCategory = sender as! Category
}
}
p.s. name your controller Controller, not Controlorer

Swift: show name in ViewController

I have array with names in TableViewController and I have ViewController. If I click on cell in TableViewController I want to show name from array in ViewController navigation bar title. How to do it?
Try this:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
navigationItem.title = myArray[indexPath.row]
}
UPDATE:
If you are using storyboards, you can:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let ame = myArray[indexPath.row]
performSegue(withIdentifier: "ViewController", sender: selectedName)
}
then, recover the selectedName in prepareForSegue and set the title for destinationVC there:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let selectedName = sender as? String,
let viewController = segue.destination as? ViewController {
detailViewController.navigationItem.title = selectedName
}
}
you can set title of viewcontroller by
suppose you have a view Controller
class UIViewController{
// make a variable in your view controller like
var titleName:String?
override func viewDidLoad(){
self.tittle = self.titleName
}
}
from your tableViewController you can pass the name to your ViewController
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let controller = self.storyboard.instantiateViewController(withIdentifier: "pass you view controller storyboard id here") as! ViewController
controller.titleName = yourArray[indexPath.row]
self.navigationController.pushViewController(controller , animated: true)
}
If you are using Storyboard, and want to navigate and pass "title" to the SecondViewController:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let name = YOUR_ARRAY[indexPath.row]
let storyboard = UIStoryboard(name: "Main", bundle: nil)
guard let destinationVC = storyboard.instantiateViewController(withIdentifier: "YOUR_SECOND_VIEW_IDENTIFIER") as? SecondViewController else { return}
destinationVC.title = name
navigationController?.pushViewController(destinationVC, animated: true)
}
If you use Interface Builder
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let name = YOUR_ARRAY[indexPath.row]
let destinationVC = SecondViewController(nibName: "YOUR_SECOND_VIEW_NAME", bundle: nil)
destinationVC.title = name
navigationController?.pushViewController(destinationVC, animated: true)
}

Pass mapkit data between two view controllers

I have two view controllers. One of them is a search view controller which uses mapkit to allow the user to search for a location.
I want to be able to click on a specific cell, and then assign the subtitle of the cell to a textfield in another viewcontroller. Does anyone have ANY idea on how to do this?!
You can implement below method of UITableViewDelegate.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: false)
let cell = tableView.cellForRow(at: indexPath) as! MyCell
let vc = MyViewController()
vc.subtitle = cell.subTitle.text
present(vc, animated: true, completion: nil)
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: false)
DispatchQueue.main.async {
self.performSegue(withIdentifier: "tosecondVC", sender: indexpath.row)
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let index = segue.destination as! secondViewController
index.indexinSecondVC = sender as! Int
}

Segue with TableView

I have some cell's (image bellow) created by tab[] I need to segue correct value to another view (moreViewController) on this view I have 'nazwa' 'szerokosc' 'dlugosc' and I need to save to nazwa correct "place" from cell etc
have somebody any solution? I search it but I don't find :/
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath){
self.performSegue(withIdentifier: "more", sender: tableView)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let destViewController:moreViewController = segue.destination as! moreViewController
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return nazwaTab.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! cellTableViewCell
let nazwa = nazwaTab[indexPath.row]
let szerokosc = szerokoscTab[indexPath.row]
let dlugosc = dlugoscTab[indexPath.row]
cell.nazwaLabel.text = nazwa
cell.szerokoscLabel.text = szerokosc
cell.dlugoscLabel.text = dlugosc
return (cell)
}
Declare a variable nazwa in MoreViewController and assign a value to it before segueing to it.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let identifier = segue.identifier ?? ""
switch identifier {
case "more":
guard let vc = segue.destination as? MoreViewController else {
return
}
vc.nazwa = self.clickedNazwa
default:
break
}
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath){
self.clickedNazwa = nazwaTab[indexPath.row]
self.performSegue(withIdentifier: "more", sender: tableView)
}
You can save a selected row to global variable and use it after call: prepare(for segue: UIStoryboardSegue, sender: Any?)

Resources