Am trying to use splitviewcontroller for the first time. I have multiple detail views one being normal UIViewcontroller and the other UICollectionViewcontroller . When am trying to navigate to UICollectionViewController on click of a row under RootViewController the methods (cellForItemAt, numberOfSections, numberOfItemsInSecrtion)in my UICollectionViewController does not get invoked .
Am navigating to my UICollectionViewController using the below code. Please let me know the correct way .
func openDocumentsViewController(){ self.splitViewController?.preferredDisplayMode = .automatic
let viewcontroller:DocumentViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "DocumentsViewController") as! DocumentViewController
let navigationController = UINavigationController(rootViewController: viewcontroller)
self.splitViewController?.showDetailViewController(navigationController, sender: self)
}
Okay , I forgot to set the delegate and datasource for collectionView . This fixed the problem !!
Related
How i can present view controller with all stack from appdelegate.
TabBarContoller is the rootviewcontoller.
I have 4 tabs on TabBarController and each of them are nav controllers.
So i need to present viewcontroller like this.
tabBar => navBar => mainViewContoller => aViewController => bViewController;
And i should be able to use to navigate back to the mainviewcontroller or navigate by tabbar.
I have a storyboard .
I tried a lot of solutions which were recommended by similar questions but it didn't help.
You should implement this through the storyboard only.
I tried sample project using appcoda.I run it successfully that.I show you the storyboard design.
It has implemented using multiple view controllers.
TabBarController * tabBar = (TabBarController *)[UIApplication sharedApplication].delegate.window.rootViewController;
if([tabBar isKindOfClass:[UITabBarController class]]){
[tabBar setSelectedIndex:0];
UINavigationController * navBar = (UINavigationController *)tabBar.selectedViewController;
UIViewController * currentVC = navBar.topViewController;
[currentVC performSegueWithIdentifier:#"notificationSegue" sender:nil];
I thought this might be helpful for all you swift'ers. I have a project setup similarly, LoginViewcontroller -> TabBarController (5 tabs) -> NavigationController for each tab -> Other ViewControllers
In storyboard, I gave my TabBarController a storyboard ID
Within AppDelegate(didFinishLaunchingWithOptions) I added
self.window = UIWindow(frame: UIScreen.main.bounds)
let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier: "TabBarControllerID") as! UITabBarController
viewController.selectedIndex = 3
self.window?.rootViewController = viewController
self.window?.makeKeyAndVisible()
Change selectedIndex value to whatever tab you need
I have a nifty project I downloaded from GitHub (here) and I am playing around with it. The project has no storyboard or xibs whatsoever, and only one viewController, which is defined with just a viewController.h file and a viewController.m file.
Perhaps a noob question, but can I have viewController1.h/m programmatically segue to viewController2.h/m without using ANY xibs or storyboards? I found a lot of code on SO and elsewhere allowing one to segue programmatically from one view to another within a Storyboard, from one xib to another or from a scoreboard to a xib (though not the opposite) but nothing on how to segue from one totally code-based vc to another. All the code I found requires that you define the view in terms of the bundle location of the storyboard or xib file, but I want to use neither.
Note: I accepted the answer I did because of its ingenuity/interesting-ness, but for the sake of simplicity I personally ended up opting with this answer to the same question (mine was a duplicate it appears): iOS: present view controller programmaticallly
You can use [viewController presentViewController:anotherController animated:YES completion:nil]; to present the view controller modally.
Another alternative is to use a UINavigationController and do [viewController.navigationController pushViewController:anotherController animated:YES];
The second method will only work if viewController is in the stack of a navigationController
Here is my Context class which changes view controllers. It works with either your own view classes or storyboard view classes.
Specific to your question look at the open function. If there is no root controller when I call open, I assign it as the root view controller. Otherwise I present it from the root view controller.
import Foundation
import UIKit
private let _StoryBoard = UIStoryboard(name: "Main", bundle: nil)
private let _RootWindow = UIWindow(frame: UIScreen.mainScreen().bounds)
public var ROOT_VIEW_CONTROLLER:UIViewController = C_RootViewController()
//abstract base of context classes
class Context:NSObject
{
class var STORYBOARD:UIStoryboard
{
return _StoryBoard
}
class var ROOTWINDOW:UIWindow
{
return _RootWindow
}
var _currentController:Controller!
class func reassignRootViewController(controller:UIViewController)
{
Context.ROOTWINDOW.rootViewController = controller
ROOT_VIEW_CONTROLLER = controller
}
func initController(controllerName:String)->Controller
{
return Context.STORYBOARD.instantiateViewControllerWithIdentifier(controllerName) as Controller
}
func initControllerFromStoryboard(storyboardName:String,controllerName:String)->Controller
{
var storyboard:UIStoryboard = UIStoryboard(name: storyboardName, bundle: nil)
return storyboard.instantiateViewControllerWithIdentifier(controllerName) as Controller
}
func open(controller:UIViewController)
{
if(Context.ROOTWINDOW.rootViewController == nil)
{
Context.ROOTWINDOW.rootViewController = ROOT_VIEW_CONTROLLER
Context.ROOTWINDOW.makeKeyAndVisible()
}
ROOT_VIEW_CONTROLLER.presentViewController(controller, animated: true, completion: {})
}
func close(controller:UIViewController)
{
ROOT_VIEW_CONTROLLER.dismissViewControllerAnimated(true, completion: nil)
}
}
In my storyboard file I have 2 viewcontrollers. A UITableViewController and a ViewController.
I've completed all the needed coding for both of them. But I need to load the UITableView (and its data) inside a view in the ViewController.
Any suggestions?
Yes you can do this by adding UItableViewController as its ChildViewController like this
UItableViewController*vc1 = [[test1 alloc]initWithNibName:#"SecondViewController" bundle:nil];
//add to the container vc which is self
[self addChildViewController:vc1];
//the entry view (will be removed from it superview later by the api)
[self.view addSubview:vc1.view];
Swift:
let tableViewVC = UITableViewController(nibName: "SecondViewController", bundle: nil)
addChildViewController(tableViewVC)
view.addSubview(tableViewVC.view)
Hope it will help you.
I have a navigation controller A on which i push the view controller B. From B i present modally the view controller C. After I dismiss C, I tried back to A. Therefore the Navigation flow is A->B -> (present ModalView) -> C. I tried without success this code in B:
self.navigationController?.popToRootViewControllerAnimated(true)
Any suggestion on how can i achieve this?
This case just happen in iOS7
Thank you
You have to dismiss modal view controller (C) and popToRootViewController in NavigationController. Try the code below in C View Controller:
let presentingVC = self.presentingViewController!
let navigationController = presentingVC is UINavigationController ? presentingVC as? UINavigationController : presentingVC.navigationController
navigationController?.popToRootViewControllerAnimated(false)
self.dismissViewControllerAnimated(true, completion: nil)
In this case user will see just dismissing modal view controller. Pop to Root View Controller in Navigation Controller will be made in backgroud.
Another option is dismissing Modal View Controller and after that pop to the Root View Controller with animation, then user will see everything.
Code for that below:
let presentingVC = self.presentingViewController!
let navigationController = presentingVC is UINavigationController ? presentingVC as? UINavigationController : presentingVC.navigationController
self.dismissViewControllerAnimated(true, completion: { () -> Void in
navigationController?.popToRootViewControllerAnimated(true)
return
})
Is there a way to have one button unwind back to a specific view controller? For example suppose I have ViewController A and B. Both modally segue to ViewController C. Now I understand how to segue unwind back to one of the previous view controllers (As was explained here) but how do I go back to the specific view controller that presented VC C?
So to sum it up, what I'm trying to figure out is...
If A segued to C then I want to unwind back to A when the button is selected. If B segued to C then I want to unwind back to B when the button is selected.
You should use the standard way to return from a modal segue. Put this in your 'back' button...
[[self presentingViewController] dismissViewControllerAnimated:YES];
This doesn't use the storyboard or a segue for the return, just code.
You could use the presentingViewController 'title' property to steer the unwind process to the desired originating ViewController. This solution would also allow you to pass data from your ViewController C to ViewControllers A and B.
1) Select the View Controller button (the yellow one) at the top of the storyboard canvas of ViewController A.
2) In the Attributes Inspector (View Controller section) give ViewController A a title.
3) Include the following code in ViewController A:
#IBAction func returned(segue: UIStoryboardSegue) {
// Don't need any code here
}
4) Repeat steps 1, 2 and 3 for ViewController B.
5) Override the prepareForSegue function in ViewController C as follows:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if self.presentingViewController!.title! == "ViewControllerATitle" {
let destination = segue.destinationViewController as! ViewControllerA
destination.someFunction(someArgument)
}
else if self.presentingViewController!.title! == "ViewControllerBTitle" {
let destination = segue.destinationViewController as! ViewControllerB
destination.someFunction(someArgument)
}
}