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/)
Related
I have a case that I need to show one specific UIViewController from different tab bar controllers, navigation controllers and acting by pressing table view cells and know where are from it was showed and run some code depending on that. So, I decided that the using of Storyboard Segue is nice idea, but even can't call prepare for segue function. All using show segue identifiers are named, so I don't know what's wrong I'm doing.
But if somebody want to say any other ways to implement some kind of it, i want to know it.
https://i.imgur.com/ZSkta3p.jpg
I'm trying to do it though Storyboard References (just cuz it looks easier to navigate in storyboard), but connection directly to the UIViewController isn't works too.
I'm on Xcode 10.1 and Swift 4.2.1
import UIKit
class TestsController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
print("I'm working!'")
if segue.identifier == "Test1" {
print("test 1")
} else if segue.identifier == "Test2" {
print("test 2")
}
}
}
A static table can only be inside a UITableViewController , so change
class TestsController: UITableViewController {
then assign this class in IB , and remove any implementations of the UITableView | UITableViewDelegate | UITableViewDataSource
then prepare should work , look to this Demo
I'm having trouble with my didSelectRowAt portion of the code.
My menu (so far) has: Workout, Tips, Contact Us. They all have a special UIViewController dedicated to their view. In my didSelectRowAt func, I have a switch case:
UIViewController.swift
switch indexPath.row {
case 0:
// Call Workout View
self.performSegue(withIdentifier: "wrkOut", sender: self)
case 1:
self.performSegue(withIdentifier: "tipsN", sender: self)
workoutView.swift
class workoutview: UIViewController {
override func viewDidLoad() { super.viewDidLoad() }
Keeping in mind "wrkOut" is the title of the Workout view and not a push segue. When I try the code it just displays a black screen when clicked. I tried ctrl dragging a push segue to each view but it can only be directed to one of them.
How can I code this to go to a specific UIViewController when the row is clicked? We have to use push segues for whatever reason.
I am working in storyboard and also programmatically do some things. First, I have created a viewController controller which is login page (first view) programmatically. But in storyboard I have a NavigationController whose root is ViewController. Everything (methods forgotPassword and loginDidFinish) worked fine, except that ViewController was viewed before controller immediately after launching the app.
So I have changed the root of NavigationController to controller, and after that my functions does not work. I've tried several things like deleting navcontrol in storyboard, etc. You can see my project here: https://github.com/ardulat/SPE
I will provide you a basic example of a Login scenario, hope it can help you with your issue, what I would do first is set right the navigation between ViewControllers like this:
I have two view controllers in my project (LoginViewController.swift and MainViewController.swift):
So in my storyboard I create two ViewControllers, the first one embedded with NavigationController then I set a segue from my first ViewController to my second ViewController:
Then I give a name to the segue I created like so:
And in order to navigate from Login to Main ViewController, I call the performSegue method inside the loginButtonTapped action that is triggered when the login button is touched.
LoginViewController.swift:
class LoginViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func loginButtonTapped(_ sender: AnyObject) {
// TODO: validate your login form
performSegue(withIdentifier: "LoginToMain", sender: nil)
}
}
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.
I have a TableViewController and I would like to trigger a segue within its navigation bar. I created the segue in the storyboard to my new ViewController. However if I click the bar button item, the view does not appear.
Instead the bar button item becomes inactive (greyed out) and the app freezes. There is no error message and the app does also not crash. The prepareForSegue method in my TableViewController also gets called
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
print("prepare for segue called")
print("destination view controller = \(segue.destinationViewController.description)")
}
I did the following things:
created a custom view Controller class for the second screen (in my storyboard and as a .swift file). I assigned the respective ViewController in the storyboard to my custom view controller in the Identity inspector
created an IBAction for a click event on the button and triggered
the segue programatically. The result remains the same.
prepareForSegue is called. The destionationViewController is correct
but does not show up. I removed this IBAction afterwards.
My destination view controller looks like this
class EnterUserDataViewController : UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
print("EnterUserDataViewController viewDidLoad called")
}
}
viewDidLoad never gets called even though the right segue has been triggered.
Can someone please give me a hint on why this happens?
You wouldn't happen to have a rogue breakpoint set somewhere would you?
If I put a breakpoint somewhere in the view loading cycle it recreates the exact symptoms you are describing.