iOS Swift Segue from TableView Cell without Storyboard - ios

I am having trouble on performing a segue when you click on a tableView's cell. I am not using storyboard at all in the application (deleted the storyboard file), and was wondering how I could perform this segue.
Note:
My tableView is in a different file than the viewController that displays it. So in my ViewController i have this line:
let tableView = MyTableView(restaurants_data: restaurants, frame: CGRect(), style: .Plain)
view.addSubview(tableView)
So since MyTableView.swift is the file where the didSelectRowAtIndexPath function is located at I cant do something like
self.navigationController?.showViewController(destinationVC, sender:nil)
So, how do I perform a segue when the user clicks on the cell, given that I am using a custom TableView and my application is not using StoryBoard?
Thanks a lot in advance

Add a reference for the viewController inside your tableView
and initialise it in the viewController init
var controller : UIViewController
controller.presentViewController(viewControllerToPresent: UIViewController, animated: Bool, completion: block?>)

Related

How do I use performSegue to get to another UIViewController?

I tried to connect my ViewController to a CollectionViewController with a segue between the two. I control+clicked from the ViewController to the CollectionView Controller and selected the 'show detail' segue, and then made a button with this code:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
print("ViewController loaded")
}
#IBAction func EditCharacterSetPressed(_ sender: UIButton) {
self.performSegue(withIdentifier: "CollectionViewSegue", sender: self)
}
When I press the button in the simulator, it gives me this error message:
How do I fix this? Does it have something to do with these other warnings about my CollectionView?:
I have an Identifier, so that's not the problem:
EDIT: Problem was, he had non-existent IBAction connected to his button.
It seems like your segue does not have an identifier in your storyboard. Based on your code, it should be
CollectionViewSegue
Regarding your collection view cells. If I recall correctly (did objective-c couple of years back) xcode is creating instances of new Cell and not re-using any of the existing, because you don't have prototype cells defined.
You can (and should) create a cell (either in storyboard, or purely in code), set an identifier to that cell and reuse it in your table view controllers (or in this case in your collection view).
I guess you are just starting with the development, so I would suggest to go through couple of tutorials (e.g. http://www.thomashanning.com/uitableview-tutorial-for-beginners/)

"Attempt to present VC on VC whose view is not in the window hierarchy!" when button pressed from tableview

Trying to build my first app. Using a TableView to present 4 different sections. Each section has its own type of cell, which is defined in a .xib file. In the last section of the TableView, a cell is presented with two buttons, plus and minus.
When, for example, the plusbutton is pressed, it calls the following code in the class related to the cell:
// link to the viewcontroller with the tableview in it
let mainViewController = ViewController()
// func called when plusbutton is tapped
#IBAction func plusButtonTapped(_ sender: UIButton) {
// viewcontroller that should popup when the button is tapped
let popup = PopupViewController()
let sbPopup = SBCardPopupViewController(contentViewController: popup)
// call to show()
sbPopup.show(onViewController: mainViewController)
}
// show() function that is called
public func show(onViewController viewController: UIViewController) {
self.modalPresentationStyle = .overCurrentContext
viewController.present(self, animated: false, completion: nil)
}
When I tap the button in the simulator, it should present the PopupViewController, but the following warning shows:
Warning: Attempt to present "balance1.SBCardPopupViewController: 0x7fdf8752cb20> on <balance1.ViewController: 0x7fdf8743cac0> whose view is not in the window hierarchy!
I tried researching the warning and found some other topics relating to it. None of the solutions worked for me. Maybe it has to do with the fact that I'm calling the plusButtonTapped() from a cell defined in a .xib file?
I followed this tutorial on youtube: https://www.youtube.com/watch?v=9yUIOjykPDU
All went wel untill 10:36 where the show() is called on the same VC where the button lives that calls the function. In my case the plusButton that calls the show() function lives on a cell that is defined in a separate .xib file and thus not on the (main) VC (as shown in the tutorial). Does this have anything to do with the problem I am facing?
The error message looks like it's right. Just looking at your code the "dangling" mainViewController hasn't been added to a window yet.
// link to the viewcontroller with the tableview in it
let mainViewController = ViewController()
This comment above this line seems to indicate that it's a link to the parent viewcontroller, but it's actually a freshly instantiated viewcontroller. You'd need to pass the actual parent down through the hierarchy to achieve what you're trying.
You could make it easier on yourself if you gave each cell a "presentationDelegate" of some sort, that would handle all presentation of cards.

How to open a TabBarController in ViewControllers that Instantiate from SlideMenuViewController

I want to have tabBar in all my ViewControllers. I have implemented the SWRevealViewController, which have two view controllers linked one is TabBarController and another is TableViewController I wants to have the same tabBar in all my ViewControllers that Segues from TableViewController.
I want to have tabBar in all my ViewControllers. I have implemented
the SWRevealViewController, which have two view controllers linked one
is TabBarController and another is TableViewController I wants to have
the same tabBar in all my ViewControllers that Segues from
TableViewController.
You can do some tweak like this, create the custom delegate and set delegate of TableViewController and TabBarController to SWRevealViewController. Now first time lets say you open the TableViewController and when tap on any cell then just invoke the delegate method which should execute inside SWRevealViewController class and then perform segue inside that class which should open the TabBarController and when click back button of TabBarController again invoke the delegate method which should execute inside SWRevealViewController class and perform segue to open the TableViewController
This shouldn't be too difficult. Your RevealViewController (the initial controller of your storyboard) already seems to be a subclass of SWRevealViewController. This is good, but it's not essentially needed for this scenario. What you do need is a UIViewController implementation for your side menu. The Storyboard alone won't do.
Also, I wouldn't use segues here to switch between the tabs because a segue has a destination view controller. So every time you perform a segue, you would create a new instance of the destination view controller. I would rather implement a UIViewController that handles the cell selection of the UITableView
Now let's say you create a UIViewController or UITableViewController as your menu (actually the RearViewController). Make sure to assign this class to your UITableViewController in your storyboard.
class MenuViewController: UITableViewController {
// MARK: UITableViewDelegate
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let tabIndex = indexPath.row
let tabbarVC = (revealViewController().frontViewController as! UITabBarController)
tabbarVC.selectedIndex = tabIndex // this assumes the menu items are in the same order as the tabs. if not you need to adjust this
revealViewController().revealToggle(animated: true) // close the side menu after switching tabs
}
}
this should be all you need

Connecting a cell of array in a view created in the main storyboard

I used the ExpandTableView of this repository on Github:
Repo -> https://github.com/SubhiH/ExpandableTableView
I need know how i connect a position of the array of this expandable view in a View in the Main storyboard, example:
Image of the ExpandableTableView
I want that when a User click for example in the cell a1 user is sent to a TableView (View) on Main storyboard.
Any ideas?
I think you are looking for the function func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath), that you already implemented in ExpandableTableViewViewController.swift.
There, you can add a segue to your Main View Controller, passing it the data.
if let resultController = storyboard!.instantiateViewControllerWithIdentifier("IDOfYourMainView") as? ResultViewController {
//Here you can access to the view's functions and attributes.
//You can set, for example, an imageView and set it the image you want.
//Then, when the view loads (Read next line), it should have your image loaded.
presentViewController(resultController, animated: true, completion: nil)
}

Performing Segue from - TableViewCell.xib to UIView - and - TableView.xib to UIViewController -

How can I perform segue from one .xib (TableCell.xib) to another .xib(UIViewController) on click on TableCell?
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print(results?[indexPath.row]) // prints successfully
...
// apply below chunks here...
}
First, I tried setting up a manual segue in Storyboard. Note that, TableView & TableViewCell are external xib but parent of TableView is in Storyboard. So, I tried control-dragging from parent-ViewController to the detailViewController (and identifier: showDetails)..However, doesn't work.
...
NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
self.performSegueWithIdentifier("showDetails", sender: AnyObject?())
})
...
Obviously, I received this error (because TableView is in .xib whereas parent and detailsVC are in Storyboard and I ctrl+dragged from parentVC to detailsVC but TableView1 apparently doesn't recognise the segue in Main Storyboard):
TableView1: 0x7f97626a3280>) has no segue with identifier 'showDetails''
Then I tried creating a ViewController and tried adding var parentNavigationController : UINavigationController! at the top and referencing below chunk inside didSelectRowAtIndex
...
let newVC : UIViewController = CellDetailsVC()
newVC.title = "DetailsView"
print(newVC)
parentNavigationController!.pushViewController(newVC, animated: true)
However, I am receiving an error:
DetailsVC: 0x7ff7794ae550>
fatal error: unexpectedly found nil while unwrapping an Optional value
Finally, I also tried below chunk inside didSelectRowAtIndex, and got something close (as I can use dismissView to < Back); but not exactly what I want. Its problem is that the segue animation looks like the page is coming from bottom.
...
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("VideoDetailsVC") as UIViewController
self.presentViewController(vc, animated: true, completion: nil)
}
I am also receiving a warning (but not crash) for some reason I couldn't figure out:
Presenting view controllers on detached view controllers is discouraged
Which approach is the right one? Or is there a better way to adapt to achieve what I am trying to?
Firstly, what is the right way to perform segue from didSelectRowAtIndex (in TableView.xib class) to a new ViewController (either Storyboard or xib)?
Secondly, assume that there is an image thumbnail in the TableViewCell.xib. What is right way of performing segue to a new UIView on click on that view? (like full-screen image / dismiss-able)
Your second approach looks to be right one but of course you are doing something wrong there. You need to drag and drop Segue from Parent ViewController to Detail ViewController and give it a Segue identifier in Storyboard (check attached Image below). IN didSelectRowAtIndexPath you need to do below code:
self.performSegueWithIdentifier("showDetailViewController", sender: nil)
As I can see you already tried that but it looks like you missed some step either setting Segue Identifier or giving wrong identifier in performSegueWithIdentifier method. Also your Parent ViewController should be embedded in UINavigationController in case you are missing that thing :)
Also keep in mind you should perform navigation (here its Segue) from one ViewController to another ViewController at same level not from one View to another ViewController.

Resources