When I segue my UIImageView from my NewsTableViewController.swift, the image does not appear in my NewsDetailTableViewController.swift.
Here is an image of my simulator:
Here is an image of my Main.storyboard:
Here is my prepareForSegue() method code:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?){
if segue.identifier == "showDetail" {
if let indexPath = tableView.indexPathForSelectedRow {
let destinationController = segue.destinationViewController as! NewsDetailTableViewController
destinationController.item = items[indexPath.row]
let newsImage = UIImageView(image: UIImage(named: detailImages[indexPath.row]))
destinationController.image = newsImage
}
}
}
It is also worth mentioning that my image in my NewsTableViewController.swift is set to 0x0, and in my NewsDetailTableViewController.swift, it is set to 600x216. I don't know if this would matter or not. If you desire any code, please do feel free to ask.
FYI, I use Swift.
In prepareForSegue the IBOutlets of your destinationController have not been initialized yet. Just pass detailImages to another array property on NewsDetailTableViewController. Change your prepareForSegue to:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?){
if segue.identifier == "showDetail" {
if let indexPath = tableView.indexPathForSelectedRow {
let destinationController = segue.destinationViewController as! NewsDetailTableViewController
destinationController.item = items[indexPath.row]
destinationController.imageNames = detailImages
}
}
}
Then in NewsTableViewController add the following code:
var imageNames:[String]?
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
//replace with whatever identifier you're using
var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("Cell") as UITableViewCell
cell.imageView?.image = self.imageNames[indexPath.row]?
return cell
}
Related
Navigation Bar title is not appearing according to the Selected Cell.
I have the Navigation View Controller inside a Container View.
The Container View is in ViewController.
ViewController:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "embedseg" {
guard let splitViewController = segue.destination as? UISplitViewController,
let leftNavController = splitViewController.viewControllers.first as? UINavigationController,
let masterViewController = leftNavController.topViewController as? MasterViewController,
//let detailViewController = splitViewController.viewControllers.last as? DetailViewController
let rightNavController = splitViewController.viewControllers.last as? UINavigationController,
let detailViewController = rightNavController.topViewController as? DetailViewController
else { fatalError() }
let firstMonster = masterViewController.monsters.first
detailViewController.monster = firstMonster
masterViewController.delegate = detailViewController
detailViewController.navigationItem.leftItemsSupplementBackButton = true
detailViewController.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem
//detailViewController.navigationItem.title = "Hello" <-- tested this, it worked.
//detailViewController.navigationItem.title = cell.textLabel?.text <-- this didn't work.
//detailViewController.navigationItem.title = monster.name <-- and this didn't work.
}
}
MasterViewController:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let monster = monsters[indexPath.row]
cell.textLabel?.text = monster.name
return cell
}
When you select the cell
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as! YourCellClassName
self.performSegue(withIdentifier: "embedseg", sender:cell.textLabel?.text)
}
in prepareforSegue
let cellText = sender as! String
detailViewController.navigationItem.title = cellText
This happens because monster and cell are defined inside
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {}
but not inside
override func prepare(for segue: UIStoryboardSegue, sender: Any?){}
If you have set your segues using the storyboard you can do something like this:
override func prepare(for segue: UIStoryboardSegue, sender: Any?){
if let cell = sender as? UITableViewCell {
detailViewController.navigationItem.title = cell.textLabel?.text
}
}
or something like this:
override func prepare(for segue: UIStoryboardSegue, sender: Any?){
if let cell = sender as? UITableViewCell {
let indexPath = tableView.indexPath(for: cell)
detailViewController.navigationItem.title = monsters[indexPath.row].name
}
}
In the first case you cast "sender" as the cell so you can access it's values, in the second case you cast "sender" as the cell, you find what is it's indexPath and then you use the indexPath to find the correct "monster" using you array monsters
I am trying to pass value from Realm via segue to another viewcontroller. The problem is it is crashing with error : Reciever has no segue with identifier. I tried other way, prepareforsegue but it is not working as well as this one.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let lektire = datasource[indexPath.row]
let destinationVC = DetaljiViewController()
destinationVC.programVar = lektire.ime
destinationVC.performSegueWithIdentifier("oLektiri", sender: self)
}
However, my segue is definitely there, and its identifier is properly set (see screen shot below).
What is going on, and how can I fix this problem?
I believe this is what you are looking for you have to call performSegueWithIdentifier from the view controller you are currently inside of and either make the sender the indexPath or you can make it your datasource item.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier("oLektiri", sender: indexPath)
// Another WAY
self.performSegueWithIdentifier("oLektiri", sender: datasource[indexPath.row])
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "oLektiri") {
let indexPath = sender as! NSIndexPath
let toViewController = segue.destinationViewController as? NextViewController
let lektire = datasource[indexPath.row]
toViewController?.selectedObject = lektire
}
// Another WAY
if(segue.identifier == "oLektiri") {
let lektire = sender as? lektireTYPE
let toViewController = segue.destinationViewController as? NextViewController
toViewController?.selectedObject = lektire
}
}
// An example of what the next view controller should look like
class NextViewController: UIViewController {
var selectedObject: ObjectType?
}
I have a custom UITableViewCell with a button inside to segue the data to another viewController. This is by utilizing the
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
//cell setup code
cell.button.tag = indexPath.row
cell.button.addTarget(self, action: "editRow", forControlEvents: .TouchUpInside)
return cell
}
then using the function
func editRow() {
self.performSegueWithIdentifier("editRow", sender: self)
}
the editRow segue is a storyboard segue.
The issue...Instead of performing the segue and passing the data, it fires the segue twice and doesn't transfer any data to the "SLEdit" viewController. Any ideas as to why this is happening? Please keep in mind I'm not very familiar with objective-c due to beginning learning with swift. If you need any further information or more code let me know. Thanks!
EDIT:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "editRow" {
let cell = sender as! SLTableViewCell
let indexPath = tableView.indexPathForCell(cell)
let SListController:SLEdit = segue.destinationViewController as! SLEdit
let items:SList = frc.objectAtIndexPath(indexPath!) as! SList
SListController.item = items
}
}
This is because you have already made a segue action in storyboard editor and you are calling the same segue again by assigning custom action to the button.
And to pass data to the next view controller use this method:
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!){
if segue.identifier == "segueIdentifier" {
}
}
Edit 1:
The error: "Could not cast value of type UIButton" is due to this line:
let cell = sender as! SLTableViewCell
Here the sender UIButton and you are convertring/assigning(whichever term is suitable) to the TableViewCell.
Edit 3:
Replace your code by this:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!{
if segue.identifier == "editRow" {
let button = sender as! UIButton
let view = button.superview!
let cell = view.superview as! <Your custom cell name here>
let indexPath = itemTable.indexPathForCell(cell)
let SListController:SLEdit = segue.destinationViewController as! SLEdit
let items:SList = frc.objectAtIndexPath(indexPath) as! SList
SListController.item = items
}
}
I have followed multiple tutorials, and have tried many answers on here, but I cannot seem to figure out what the problem is.
Here is my code:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
println("You selected cell #\(indexPath.row)!")
let indexPath = homeTimelineTableView.indexPathForSelectedRow()
let currentCell = homeTimelineTableView.cellForRowAtIndexPath(indexPath!) as! ProductTableViewCell
productTitle = currentCell.productCellTitleLabel!.text
println("The product title is \(productTitle)")
self.performSegueWithIdentifier("timelineDetail", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var titleLables: String!
if (segue.identifier == "timelineDetail") {
println("it works thus far!")
let viewController = segue.destinationViewController as! ProductDetailViewController
let selectedRow = homeTimelineTableView.indexPathForSelectedRow()!.row
viewController.titleLabel?.text = productTitle
}else {
println("wtf is wrong with your code?!")
}
}
I do not receive any errors. However, when I go to run my app, my product title still refuses to pass to the viewcontroller.
Any suggestions? Thanks.
At this stage viewController.titleLabel is nil (you are using ?, that's why there is no error)
The correct approach should be:
add var productTitle: String! in ProductDetailViewController
pass productTitle not to UILabel, but to viewController.productTitle
in viewDidLoad of ProductDetailViewController set viewController.titleLabel?.text = self.productTitle
The productTitle variable must be assigned from the currently selected cell in the prepareForSegue method.
Check the code below.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var titleLables: String!
if (segue.identifier == "timelineDetail") {
println("it works thus far!")
let viewController = segue.destinationViewController as! ProductDetailViewController
let selectedRow = homeTimelineTableView.indexPathForSelectedRow()!.row
let currentCell = homeTimelineTableView.cellForRowAtIndexPath(indexPath!) as! ProductTableViewCell
productTitle = currentCell.productCellTitleLabel!.text
viewController.titleLabel?.text = productTitle
} else {
println("wtf is wrong with your code?!")
}
}
The problem is most lilely in these two lines:
let indexPath = homeTimelineTableView.indexPathForSelectedRow()
let currentCell = homeTimelineTableView.cellForRowAtIndexPath(indexPath!) as! ProductTableViewCell
First, func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) provides already the selected indexPath. There is no need for let indexPath = ....
Second, don't load the cell's value (which returns nil, if the cell is visible and tableView.visibleCells() brings other issues), but use your data source to get the item at the selected indexPath.
In total it might look like:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
// `indexPath` comes from the function parameters
let item = model.itemAtIndexPath(indexPath)
// the 'model'-part should be the same like in `cellForRow:indexPath`
// your mission is only to get the item at the path, not the cell
productTitle = item.title
self.performSegueWithIdentifier("timelineDetail", sender: self)
}
I'm trying to get the name of the selected row in the custom cell. How I can do that in Swift?
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var selectedCell = CustomCell()
selectedCell = tableView(tbl, cellForRowAtIndexPath: <#NSIndexPath#>)
if(segue.identifier == "next") {
var next = (segue.destinationViewController as! EngineViewController)
next.titleSub = selectedCell.cell.lblBrand.text
}
}
I believe if you are just selecting a cell, the cell should be the sender. Try this
if let selectedCell = sender as? CustomCell {
if(segue.identifier == "next") {
var next = (segue.destinationViewController as! EngineViewController)
next.titleSub = selectedCell.cell.lblBrand.text
}
}
You could attempt to override didSelectRowAtIndexPath to get your cell.
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.dequeueReusableCellWithIdentifier("CellIdentifier", forIndexPath: indexPath) as! CustomCell
cell.yourLabel.textYouWant
let yourViewController = storyboard?.instantiateViewControllerWithIdentifier("ViewController") as! ViewController
navigationController?.pushViewController(yourViewController, animated: true)
}