I show the data in labelTEx in the table.
When I click labelTEx, I open another table class.
I want to transfer the text data of labelTExt that I clicked in UITableViewCell to formBaslik in DetayViewController.
that is, I want to transfer the gifsabaslik [indexPath.row] that I have selected to the detayBaslik in DetayViewController. How can I do that?
DetayViewController
class DetayViewController: UIViewController {
var formBaslik = String()
}
TableViewController
class TableViewController: UIViewController{
var gifsayeniresim: [String] = []
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath) as! TableViewCell
cell.labelTExt.text = self.gifsabaslik[indexPath.row]
cell.labelTExt.textColor = UIColor.white
cell.labelTExt.font = UIFont(name: "HelveticaNeue", size: 14.0)!
cell.labelTExt.backgroundColor = UIColor.lightGray
cell.labelLayout.constant = cell.labelTExt.contentSize.height
cell.labelTExt.isEditable = false
let tap = UITapGestureRecognizer(target: self,action: #selector(handleTaponTextField(_:)))
tap.numberOfTapsRequired = 1
tap.delegate = self
cell.labelTExt.isUserInteractionEnabled = true
cell.labelTExt.addGestureRecognizer(tap)
return cell
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?){
if segue.identifier == "newo"{
if segue.destination is DetayViewController {
}
}
#SH Yasilm
In DetayViewController, declare
var formBaslik = String?
In TableViewController, in prepare, write
override func prepare(for segue: UIStoryboardSegue, sender: Any?){
if segue.identifier == "newo" {
if let cell = sender as? UITableViewCell {
// You have clicked in a cell, but that may not have selected it: let's compute its indePath
let tapPosition:CGPoint = cell.convert(CGPoint.zero, to: self.table)
let indexPath = self.table.indexPathForRow(at: tapPosition)
if let vc = segue.destination as? DetayViewController {
vc.formBaslik = gifsabaslik[indexPath.row]
}
}
}
You can retrieve the indexPath by following the code below.
In the DetayViewController's very top (below class)
var myStr: String!
Inside the class where you have the tableview
override func prepare(for segue: UIStoryboardSegue, sender: Any?){
if segue.identifier == "newo"{
if segue.destination is DetayViewController {
let vc = segue.destination as? DetayViewController
let indexPath = self.tableView.indexPathForSelectedRow
let cell = tableView.cellForRow(at: indexPath!) as! YourCellClassName
vc.myStr = cell.yourString
//NOTE! If. the cell is a string just do like I did, other way, if that's a textfield/label you should use cell.yourLabel.text
}
}
Related
I have a ViewController that contains a UICollectionView where each cell is a custom cell. I need to perform a segue, so when the user taps over any of the cell, a new ViewController is shown for showing the detail of the pressed cell.
With the code I have right now, the segue is performed if I press over a cell with two fingers, but not with just one. Moreover, when the DetailsViewController is show, the title is not updated.
I cannot post images, but the segue I create in the storyboard goes from the cell to the DetailsViewController, is type Show (e.g. Push) and the id is showDetail.
ViewController.swift
override func viewDidLoad() {
super.viewDidLoad()
collectionView.dataSource = self
collectionView.delegate = self
collectionView.register(UINib.init(nibName: "MovieCell", bundle: nil), forCellWithReuseIdentifier: "MovieCell")
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIInputViewController.dismissKeyboard))
view.addGestureRecognizer(tap)
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
performSegue(withIdentifier: "showDetail", sender: indexPath)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if(segue.identifier == "showDetail") {
guard let viewController = segue.destination as? DetailsViewController else {return}
guard let indexPath = sender as? IndexPath else {return}
viewController.movie = self.moviesList[indexPath.row]
}
}
DetailsViewController.swift
class DetailsViewController: UIViewController {
var movie: Movie? = nil {
didSet {
navigationController?.title = movie?.title
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
Any idea what is going wrong?
Change sender to the collectionView cell:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
performSegue(withIdentifier: "showDetail", sender: MovieCell)
}
Use this in prepare for segue:
if(segue.identifier == "showDetail") {
guard let viewController = segue.destination as? DetailsViewController else {return}
let cell = sender as MovieCell
guard let indexPath = self.collectionView!.indexPathForCell(cell) else {return}
viewController.movie = self.moviesList[indexPath.row]
}
I'm trying to append string using an alert in createPlaylistVC to a tableView in another ViewController createdPlaylistVC.
I've looked up this answer and it didn't do much for me
add a row to the tableView from another viewController
CreatePlaylistVC
var crdPlaylistVC = CreatedPlaylistVC()
alert.addAction(UIAlertAction(title:"OK", style:.default, handler: {
action in
if let playlistName = alert.textFields?.first?.text {
self.crdPlaylistVC.emptyArray.append("Your playlist: \(playlistName)")
let indexPath = IndexPath(row: self.crdPlaylistVC.emptyArray.count - 1, section: 0)
self.crdPlaylistVC.tableView?.beginUpdates()
self.crdPlaylistVC.tableView?.insertRows(at: [indexPath], with: .automatic)
self.crdPlaylistVC.tableView?.endUpdates()
self.crdPlaylistVC.tableView?.reloadData()
func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let SEC: CreatedPlaylistVC = segue.destination as! CreatedPlaylistVC
SEC.emptyArray.append("Your playlist: \(playlistName)")
self.crdPlaylistVC.tableView.reloadData()
}
CreatedPlaylistVC
class CreatedPlaylistVC:UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
var emptyArray = [String]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "playlistCell", for: indexPath) as! UITableViewCell
cell.textLabel?.text = emptyArray[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return emptyArray.count
}
}
The code cannot work. createdPlaylistVC() is never the instance in the storyboard.
You have to call performSegue in the action and pass the string as sender. And prepare for must be on the top level of the class
var crdPlaylistVC = createdPlaylistVC()
alert.addAction(UIAlertAction(title:"OK", style:.default) { [weak self] action in
if let playlistName = alert.textFields?.first?.text {
self?.performSegue(withIdentifier: "MyIdentifier" sender: playlistName)
}
}
func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard segue.identifier == "MyIdentifier" else { return }
let playlistName = sender as! String
let sec = segue.destination as! createdPlaylistVC
sec.emptyArray.append("Your playlist: \(playlistName)")
}
You have to reload the table view in createdPlaylistVC because the table view might be not connected yet.
And please conform to the naming convention that class names start with an uppercase letter and variable names start with a lowercase letter.
I have the function
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let indexPath = tableView.indexPathForSelectedRow {
let object = dailyAgenda[indexPath.row]
if object == "Time Management" {
self.performSegue(withIdentifier: "showTimeManagement", sender: self)
}
else {
self.performSegue(withIdentifier: "showDetail", sender: self)
}}}
And the prepare for segue function
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showDetail" {
if let indexPath = tableView.indexPathForSelectedRow {
let object = dailyAgenda[indexPath.row]
var controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController
controller.detailItem = object
controller.textDescription = indepthDescript[indexPath.row]
}}
if segue.identifier == "showTimeManagement" {
var controller = (segue.destination as! UINavigationController).topViewController as! TimeManagement
}
}
But I keep getting the error "Thread 1: Fatal error: Index out of range" when selecting the cell that performs the showTimeManagement segue. The error occurs on the "controller.textDescription = indepthDescript[indexPath.row]]" line within the showDetail segue. Why would it even be running this line in the first place and where am I going wrong?
I have two viewcontrollers (one is tableVC) that I would like to pass information between. Here is code from that tableVC:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
var rowSelected = indexPath.row
print(rowSelected) //always returns the correct integer
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let destViewController: newController = segue.destination as! newController
newController.rowSelected = rowSelected
}
performSegue(withIdentifier: "rowSelected", sender: Any?.self)//segue to newController
}
And here is the code for the newController that I want the info to be passed to:
#IBOutlet weak var label: UILabel!
var rowSelected = Int()
override func viewDidLoad() {
super.viewDidLoad()
label.text = infoArray[rowSelected]
print(rowSelected) //always logs 0 to the console, regardless of cell selection
}
I thought I had set this up appropriately, but for whatever reason the index called to the infoArray is always 0, no matter what cell is selected in the tableVC. Not sure what the problem is.
write prepareForSegue in class scope/global scope. in your code prepareForSegue will never call because you are writing this inside the method. pass rowSelected in performSegue and get rowSelected value in prepareForSegue using sender or you can use indexPathForSelectedRow property of tableView.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
...
performSegue(withIdentifier: "rowSelected", sender: rowSelected)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: Any?) {
let rowSelected = sender as! Int
// or you can use indexPathForSelectedRow for getting row value
// let indexPath = self.tableView.indexPathForSelectedRow?
// let rowSelected = indexPath!.row
let destViewController: newController = segue.destination as! newController
newController.rowSelected = rowSelected
}
Need to use override in your function when you prepareForSegue
See below example code : -
Swift 3
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "ShowAttractionDetails" {
let detailViewController = segue.destination
as! AttractionDetailViewController
let myIndexPath = self.tableView.indexPathForSelectedRow!
let row = myIndexPath.row
detailViewController.webSite = webAddresses[row]
}
}
Swift 2.3
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "ShowAttractionDetails" {
let detailViewController = segue.destination
as! AttractionDetailViewController
let myIndexPath = self.tableView.indexPathForSelectedRow!
let row = myIndexPath.row
detailViewController.webSite = webAddresses[row]
}
}
Source - Segue from UITableViewCell Taps in Swift & TableView Navigation using Storyboards in Xcode 8
I have created custom cell with button inside. Now I am trying to pass a data via pressing on this button, but cant catch indexPath, need your help.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier=="editData"){
if let indexPath = tableView.indexPathForSelectedRow {
let destinationController = (segue.destinationViewController as! AddDetail)
destinationController.info = data[indexPath.row]
let nItem : Dealers = data [indexPath.row]
destinationController.nItem = nItem
also Im trying do the same but from swiping menu:
override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]?{
let edit = UITableViewRowAction(style: .Normal, title: "Edit") { (action, indexPath) in
self.performSegueWithIdentifier("addDealer", sender: self)
let name = self.data [indexPath.row].dealerName
print(name)
}
edit.backgroundColor = UIColor.lightGrayColor()
return [delete, edit]
is it possible pass segue from swiping menu?
You can pass indexPath as the sender in performSegueWithIdentifier.
self.performSegueWithIdentifier("addDealer", sender: indexPath)
then
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let indexPath = sender as? NSIndexPath {
// then here you know what the indexPath was
// and can do whatever you want with it
}
...
Try using tableView.indexPathForCell(selectedCell) instead of tableView.indexPathForSelectedRow; you first extract selectedCell as your custom table view cell (YourCustomTableViewCell below):
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
if segue.identifier == "editData" {
let destinationController = segue.destinationViewController as! AddDetail
if let selectedCell = sender as? YourCustomTableViewCell {
let indexPath = tableView.indexPathForCell(selectedCell)!
destinationController.info = data[indexPath.row]
let nItem : Dealers = data[indexPath.row]
destinationController.nItem = nItem
}
}
}
As for the swiping question: I'll get back answer to this.