I've been trying to get my project up and running using the SWRevealController classes. I am nearly done writing the basic code for my App so there is already quite a bit of code inside this project. I have tried this inside another project before and it did work.
What I am doing:
I have two ViewControllers. One of them being a SWRevealViewController holding absolutely nothing and one BasicViewController who is just holding a button. I added a Button to the ViewController as well as a IBOutlet. In the ViewDidLoad() Method I added a target to the Button to be fired when pressed:
Inside BasicVC:
class BasicViewController: UIViewController {
#IBOutlet weak var menuButton:UIButton!
override func viewDidLoad() {
super.viewDidLoad()
menuButton.addTarget(self.revealViewController(), action: #selector(SWRevealViewController.revealToggle(_:)), for: .touchUpInside)
}
}
In the Storyboard:
I created a segue from the SWRevealViewController to the BasicViewController. (reveal view controller set controller)
Outcome:
The code compiles perfectly, but results in the button being pressed without anything actually happening. However, if I create a new project and do exactly the same thing, the SWRevealViewController appears.
Q: Is there anything I could do in order to get the solution for this problem? Apparently there's something interfering with the SWReavealViewController class, because it is perfectly working in the other projects.. I am just too "blind" / new to Swift to actually find it.
What I already tried:
Was that I set a breakpoint for when the button is being pressed aka the view being loaded. What I noticed was, that in the test project without any other code, the debugger actually went inside the SWRevealController class, but in my project with a whole lot of other code, it actually does not.
EDIT: It actually does go into the class.
Thanks for reading until here! I'd really appreciate any help. Maybe I am just too "noobie" to find the issue and it actually is just a tiny little issue..
Kind regards.
Related
I have been working on an app for some time and just realized the swiping back in the detail view only returns me to the master view the first time. It also isn't smooth, even when it works on the first time. Instead of smoothly going to the master view, it jumps all at once, even when I swipe slowly. It used to work correctly, but I haven't been testing for this specifically, so I don't know when it stopped working and what I changed to cause this.
A little about how my app is setup...
I have a split view controller that is connected to my MasterTableViewController and DetailViewController.
Both of those are have TableViews and are embedded in Navigation Controllers.
I have set it up so that the app originally loads to the MasterTableViewController instead of going immediately to the DetailViewController, but even when I take this out, the interactive pop gesture doesn't work.
I don't believe I've messed with any of the back button controls. I have looked through my code and storyboard and can't find anywhere that I have. This is part of what is most confusing because these questions (1, 2, and 3) all seem to have problems stemming from changing the back button or can be fixed by entering the following line of code:
self.navigationController.interactivePopGestureRecognizer.delegate = nil
Adding that to my code seems to have no impact on how it behaves.
Here is a picture of how it is setup for reference:
I can usually figure out these things on my own, but this problem baffles me because it works the first time, but not any others. As far as I can tell, nothing changes between the first time and the others. I don't know if anybody else has had the same issue, but any help on why this might be happening would be greatly appreciated. I can provide code or answers to questions on how I am doing certain things if needed. I haven't put any in because there are so many different things controlling this piece that I don't know where to start.
When are you calling self.navigationController.interactivePopGestureRecognizer.delegate = nil?
Doing this will definitely disable interactive pop. It sounds like you may be calling this after a certain UIViewController appears.
What other modifications to UINavigationController are you making? Are you using appearance delegate?
Are you subclassing? If so, are you calling super in all of your method overrides?
Also check your overrides of viewWillAppear in child ViewControllers. This method gets called during an interactive pop. If you are doing a lot of computation (or synchronous calls) on the main thread within this method, it could cause frame drop, hence the choppy animation.
Hope this helps
From Alex Chase's answer : Also check your overrides of viewWillAppear in child ViewControllers. This method gets called during an interactive pop.
added it to viewWillAppear and it worked:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.interactivePopGestureRecognizer?.delegate = self
}
I am trying to implement a segue programmatically in IOS.
My story board looks like this:
The first segue between the first two screens is done by connecting the Login button to the next screen (so not completely programmatically), and it works fine.
The issue is with the "secondSegue", which I tried doing programmatically.
It simply does not work and there is no error message appearing.
I connected the 'Load this Screen' button to the following action in the Second Screen's view controller:
#IBAction func openThirdScreen(_ sender: Any) {
performSegue(withIdentifier: "secondSegue", sender: nil)
}
But the screen isn't opening and there is no error.
All the proper IBOutlets seem connected so I don't know what the issue could be.
I put a print statement in openThirdScreen(), and it prints, but a print statement in the third screen's View Controller's viewDidLoad() does not print, even though
I made sure the third screen was connected to a view controller.
I had overridden performSegue() earlier in order to do more with the segue but it was not working so I removed it for simplicity.
Please let me know what I messed up.
Sorry if this is a stupid question, I'm very new to XCode and I couldn't find anyone online with the same issue.
Let me know if there are more screenshots that are necessary to answer my question.
Edit: the following image was requested, in order to answer the question
My app's navigation flow looks a bit like this:
UINavigationController - MasterViewController > DetailViewController > InfoViewController
MasterViewController contains the following method:
#IBAction func unwindToMaster(with segue: UIStoryboardSegue) {}
In DetailViewController, there is a similar method:
#IBAction func unwindToDetail(with segue: UIStoryboardSegue) {}
I use these methods, along with UIButtons, to allow the user to advance forward and back through the navigation hierarchy. In interface builder, I see the method under DetailViewController when I right click on "Exit" in InfoViewController, but when I right click on "Exit" in DetailViewController, no other unwind segues are listed.
I have consulted multiple online sources (Ray Wenderlich, relevant StackOverflow questions) instructing the correct way to produce unwind segues in interface builder, but none of these have helped solve the issue. Right now, I need help figuring out what the problem is in the first place. As development usually goes, it's probably something staring me square in the face.
I am running Xcode 8.1 using Swift 3. Thank you.
To re-iterate: not only an Action for a Storyboard Unwind Segue has to be placed in the same source file as class definition for an unwind-to (destination) View Controller (e.g., #IBAction func prepareForUnwind(segue: UIStoryboardSegue), detected as prepareForUnwind[With]Segue in a "Presenting Segues" list), but also that View Controller cannot have ANY extensions in ANY secondary source files. You have to merge class definition and all extensions into a single source file.
(As of Xcode 8.2.1.)
In my case, I had a complicated inheritance in my view controller and it was a reason why Interface Builder did not see my unwind. So this workaround works for me well:
Go to YouCollViewController.swift file and delete all classes, protocols, generics, etc. your view controller implements in view controller's declaration
Inherit your view controller from UIViewController
Go to the storyboard and connect your action with the unwind, it should appear in unwinds list
Go back to YouCollViewController.swift file and discard all the changes
I consulted Apple's Developer Library (specifically the page "Using Unwind Segues"). There, the example definition of an unwind action is:
#IBAction func unwindToMainMenu(sender: UIStoryboardSegue) {
let sourceViewController = sender.sourceViewController
// Pull any data from the view controller which initiated the unwind segue.
}
Applying this example in my code, I changed my unwind action declarations to:
#IBAction func unwindToMaster(sender: UIStoryboardSegue) {
print("Unwinded to master.")
}
and
#IBAction func unwindToDetail(sender: UIStoryboardSegue) {
print("Unwinded to detail.")
}
I also made sure that each method was contained within the same file as MasterViewController's class declaration. After further testing, I found that all extensions of MasterViewController had to exist in the same file for interface builder to find and recognize the unwind segue.
Now, in storyboard, the exit menu shows both unwind segues. My conclusion is that by fiddling around with where the methods are placed and how they are declared, a configuration that interface builder can recognize will be found. I hope it will be less touchy in the future, as my current method organization is very long and difficult to navigate.
Because none of these answers helped me and I didn't want to mess around with my code that much. Here another solution you can give a try.
Starting from the point where you have already added the unwind function to your MasterViewController.
First I have gone ahead and added a new ViewController to my storyboard as well as a new Cocoa Touch Class File of type UIViewController and connected it with my Storyboard one (I called it the HelperViewController).
Then you can add the same unwind function, you already have inside your MasterVC to your newly created HelperVC.
#IBAction func unwindToMaster(with segue: UIStoryboardSegue) {}
Now connect the Helper to your DetailVC. Your Storyboard should look somewhat like mine. You should get the same option as me if you ctrl + drag and drop to the exit of your DetailVC. When the connection has been established and you hover over the newly created segue both the Master and the HelperVC should be highlighted. Now you can delete the HelperVC again and everything should work as expected.
I hope that helped!
With swift 4 XCode 9.2 I found that you need to drag the reference from the yellow icon at the top of the viewController to the "Exit" reference of the target viewController in the left details panel. Hope this helps!
Sometimes XCode restart makes the actions appear.
I'm new to Swift, and the class I took taught me without storyboards, so just putting that as a caveat.
I'm trying to build my own app now, and I'm trying to push a new viewController onto the main navigation controller. This works fine, but when I go to the new viewController, it doesn't ever load what I put in the xib file. That is, I know it's going to the right place because I can change background color, etc., in code, but I've put some elements in the xib and they're not showing up. I saw this discussion: Load ViewController Swift - Black Screen and did what it said, but it's still not helping.
Here's my push code:
var viewController = CreateViewController(nibName: "CreateViewController", bundle: nil)
self.navigationController?.pushViewController(viewController, animated: true)
What am I doing wrong?
Alternately, and this is probably a better question — I haven't gotten that far yet. Should I just try to learn storyboards? It's not that complicated of an app and everyone seems to say storyboards are better...
I don't know what is wrong with my code. i have developed app successfully and all the things working fine except when i launch app first time, In side first navigation controller, the pop animation is not working fine. it seems that Pop without animation. and its working fine when i changed the tab and come back on first tab. and doing push-pop then its working fine.
I tried to figure out problem since week. but could't get success because of lengthy code. I have tried the same animation with creating Tabbar Demo and its working fine.
My app has following hierarchy.
UINavigationController --> UIViewController --> UITabbarController --> Four UINavigationController --> UIViewControlle.
I have taken UITabbarController in my storyboard.
I know that i asked the question and also provide solution for same. I have asked this question long time ago and i am not getting any solution for this because there is illogical bugs. Not every Tabbar base application have same. Here i am adding solution that is result of long time debugging and i found that even single line can break your project.
Actually i have added UITabbarController from storyboard and programmatically created UITabbarController class and type cast it with UITabbarController inside storyboard.
Here my problem is, i forgot to write [super viewDidAppear:animated]; inside -(void)viewDidAppear:(BOOL)animated method. so i will break pop animation first time then it will work fine.
After getting this solution, even i don't know how this line affect whole code. but i don't want the other people to waste their time to find out such single line (unexpected issue) problem. so here i am adding this code.
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
}
For Swift 5
Depending on #Jatin Patel - JP answer
Create custom class for your TabBarController
Add this Code in your UITabBarController file
class MyTabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
}
}