How to add my custom UIViewController in react native App - ios

I want to implement Face detection in react native. I want to add CameraViewController Demo in react native. CameraView controller source code is here: https://github.com/googlesamples/ios-vision/blob/master/FaceDetectorDemo/FaceDetector/CameraViewController.m
import Foundation
#objc(SampleViewManager)
class SampleViewManager : RCTViewManager {
override func view() -> UIView! {
// UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Sample" bundle: nil];
// //
// UIViewController *vc = [storyboard instantiateInitialViewController];
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateInitialViewController()!
return vc.view;
}
}
but error occured:Could not load the "Camera" image referenced from a nib in the bundle with identifier
kindly help me how to implement Face detection in react native.

Related

Access view controller from referencing storyboard

As I know that referencing storyboard can be used to make the multiple storyboard with the same storyboard reference. If all View Controllers hierarchy is connected via the segue it works.
I want to know how to use referencing storyboard without segue between View controllers, because one view controller may be used in multiple ways or may need to access the view controller with the storyboard identifier from the new referencing storyboard.
Please let me know, I want to use referencing storyboard's view controller without the segue.
You could do somthing like this...
#IBAction func tapButtonToShowOtherController(_ sender: Any?) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
//storyboard identifier set in storyboard "userSB"
let aVC = storyboard.instantiateViewController(withIdentifier: "userSB") as? AViewController
aVC?.udelegate = self
self.present(aVC!, animated: true, completion: nil)
}
Give the id to storyboard in identity inspecter like "ViewController_id"
MyCartViewController* destVC = [self.storyboard instantiateViewControllerWithIdentifier:#"MyCartViewController_id"];
[self.navigationController pushViewController:destVC animated:YES];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
MyNewViewController *myVC = (MyNewViewController *)[storyboard instantiateViewControllerWithIdentifier:#"myViewCont"];
Select your viewcontroller from storyboard and select identity inspecter give stoary board id whatever you want
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"your storyboard name" bundle:nil];
MyNewViewController *myVC = (MyNewViewController *)[storyboard instantiateViewControllerWithIdentifier:#"your storyboard id"];
I downloaded sample at here https://www.raywenderlich.com/115697/ios-9-storyboards-tutorial-whats-new-in-storyboards
They have used storyboard reference as segue.Here i have modified something below:
1.select Checklists.stoaryboard
2.Remove ChecklistDetailViewController segue.
3.Select ChecklistsViewController.swift
4.Add following code:Its working without segue
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let storyboard = UIStoryboard(name: "ChecklistDetail", bundle: nil)
let aVC = storyboard.instantiateViewController(withIdentifier: "ChecklistDetailViewController") as? ChecklistDetailViewController
aVC?.checklist = checklists[indexPath.row]
navigationController?.pushViewController(aVC!, animated: true)
}
5.comment prepare(for segue: UIStoryboardSegue, sender: Any?) method.
Here i have understand:
When you are using, storyboard reference You need to mention ReferenceID
Then you can take viewcontroller by giving stoarboard name with Respective storyboardId

How to represent a startup screen in Storyboards

Right now I have a MainViewController which is embedded in a UINavigationController so the navigation controller is set as initial view controller.
What I want is first time the app starts and only then to show a StartupViewController. But I am not sure how to represent this in my storyboard.
Should this be set as initial view controller if the app starts the first time, if not the navigation controller should be set.
What I tried is to show StartupViewController in MainViewController::viewDidLoad(), but its not working how I wanted too.
Anyone know what is the right approach to do this ?
Hello this code may be helpfull for you :
// MARK: - Application Supporting Funcations -
func loadFirstViewController(viewController: String)
{
// for loading first view Controller
let storyBoard = appDelegate.AppStoryBoard()
/////////////////////////Add Navigation Controller and set Root View Controller///////////////////////////////////////
let object = storyBoard.instantiateViewControllerWithIdentifier(viewController) // for prelogin navigation
self.navigationController = UINavigationController(rootViewController: object)
self.navigationController?.navigationBar.hidden = true
self.loadNavigationControllerToWindow()
}
func loadNavigationControllerToWindow()
{
if self.window == nil
{
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
}
// for loading root view
self.window!.rootViewController = self.navigationController!
self.window!.makeKeyAndVisible()
}
call this function in didFinishLaunchingWithOptions
if((NSUserDefaults.standardUserDefaults().valueForKey("isFirstTime") != nil))
{
self.loadFirstViewController("LoginVC") // for loading first view controller
}
else
{
self.loadFirstViewController("WelcomeVC") // for loading first view controller
}
put this after you go in second controler viewDidLoad
if((NSUserDefaults.standardUserDefaults().valueForKey("isFirstTime") == nil))
{
NSUserDefaults.standardUserDefaults().setValue("1", forKey: "isFirstTime")
}
This is how I acheived in my app.
Add this in appdelegate applicationdidfinishlaunching.
NSUserDefaults *defaults =[NSUserDefaults standardUserDefaults];
if (![defaults boolForKey:#"FirstTime"])
{
//NSLog(#"Enter First Time ");
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"Main" bundle:[NSBundle mainBundle]];
StartupViewController * firstViewController = [storyBoard instantiateViewControllerWithIdentifier:#"StartupViewController"];//AskAndAnswerViewId RegisterViewId TagViewId HelpViewId
self.navigationController=[[UINavigationController alloc]initWithRootViewController:firstViewController];
self.window.rootViewController = self.navigationController;
[self.navigationController setNavigationBarHidden:YES];
}
else
{
//NSLog(#"not First Time");
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"Main" bundle:[NSBundle mainBundle]];
HelpViewController *mainviewcontroller = [storyBoard instantiateViewControllerWithIdentifier:#"AskAndAnswerViewId"];
self.navigationController=[[UINavigationController alloc]initWithRootViewController:mainviewcontroller];
self.window.rootViewController = self.navigationController;
[self.navigationController setNavigationBarHidden:YES];
}
Once you reached in Mainviewcontroller change the userdefault value for FirstTime to "NO".
I understand your Question ,
In AppDelegate try to set rootViewController ,
I have store data in the NSUserDefault if user came first time
And try to set rootViewController once he visit first time.
In below Example I have navigate user to Login screen/Home screen
let str = userDefaults.objectForKey("firstTime")
{}else{}
Please don't forget to give identifier to your view controller StartupViewController
-> user interaction enable in StartupViewController
if (UserDefaults.standard.string(forKey: "keepUsername") != nil) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "Revealview")
self.present(vc, animated: false, completion: nil)
}
else
{
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "loginview") as! loginview
self.present(nextViewController, animated:true, completion:nil)
}

Going directly to Main View controller for already logged in user

I have a loginViewController as my rootviewcontroller followed by the main screen and then other screens. My views follow push and pop approach. What I want is, if a user is already logged in my view should start from main screen else start from login screen, and if I logout from main screen it should go back to login screen and the push and pop structure should be maintained. I can achieve this using the modal transition, but I need to use push and pop approach, is this possible? Currently I have checked a already logged in condition in my appdelegate to set the rootview controller but it fails if I attempt to log out as its not present in my navigation controller stack.
if !alreadyLoggedin
{
let mainListVC = storyBoard.instantiateViewControllerWithIdentifier(“MainListViewController”)
self.window!.rootViewController = mainListVC
}
else
{
let loginVC = storyBoard.instantiateViewControllerWithIdentifier("ViewController")
self.window!.rootViewController = loginVC
}
It's basic use case, Please follow my steps.
In your story create navigation view controller with view controller.
Select navigation view controller as your initial view controller in storyboard.
Create three views controllers- InitialViewController, LoginViewController and MainViewController and set storyboard id for all view controllers.
Created sample project for you. Download link (https://www.dropbox.com/s/zk8x7ptg5mzmotk/test.zip?dl=0)
You need to use. AppDelegate
Objective C
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if (![[NSUserDefaults standardUserDefaults] boolForKey:#"LoginStatus"]) {
UIStoryboard* storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
self.window.rootViewController = [storyboard instantiateViewControllerWithIdentifier:#"loginController"];
}else{
UIStoryboard* storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
self.window.rootViewController = [storyboard instantiateViewControllerWithIdentifier:#"RootView"];
}
}
SWIFT - i hope its correct
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
//Using UserDefaults check already loggedin user or not
if (!someStatus) {
let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("someViewController") as! UIViewController
self.presentViewController(vc, animated: true, completion: nil)
}else{
let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("loginViewController") as! UIViewController
self.presentViewController(vc, animated: true, completion: nil)
}
}

Implementing SWRevealViewConroller Library (slide out menu) in multiple storyboards

I am trying to implement SWRevealViewController Library as given in VideoTutorial, I was successfully able to do that but I don't want everything on 1 storyboard, I want to break it down in 2 storyboards
AppDelegate Code:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
storyboard = UIStoryboard(name: "MenuDrawer", bundle: nil)
initialViewController = storyboard.instantiateViewControllerWithIdentifier("SWRevealViewController") as! UIViewController
self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()
return true
}
Rightnow MenuDrawer storyboard has everything
SWRevealViewCOntroller
TableViewController
NavigationController
RootViewController
and below segues which are defined in Library:
segue1 (sw_rear) : between SWRevealViewController --> TableViewController
segue2 (sw_front) : between SWRevealViewController
--> NavigationController
now I want 3 and 4 in different storyboard. but when I move 3 and 4 to different storyboard how do I create segue 2 across storyboards
I am not really sure if I understand your problem but you can try this to retrive your second storyboard and load your navigationViewController from there.
let storyBoard : UIStoryboard = UIStoryboard(name: "SecondStoryBoard", bundle:nil)
let deleteViewController = storyBoard.instantiateViewControllerWithIdentifier("SecondNavigationController") as UINavigationController
as far as iknow, you don't need to push again the segue 2 on 3 and 4. what you need is refer the new view (3 and 4) on the segue 2. in Obj-c will be like that:
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
SWRevealViewController *view = [mainStoryboard instantiateViewControllerWithIdentifier:identifier];
[view setModalTransitionStyle:UIModalTransitionStyleCoverVertical];
[self.navigationController pushViewController:view animated:YES];
where "self" is the ViewController where segue 2 has been created.
i hope have answered your question.
Try This First Of All Make the other storyboard and add what you need then call the other storyboard in
AppDelegate Code:
func application(application: UIApplication,didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
var storyboard = UIStoryboard(name: "MenuDrawer", bundle: nil)
var storyboard1 = UIStoryboard(name: "NewStoryBoardName", bundle: nil)
var initialViewController = storyboard.instantiateViewControllerWithIdentifier("SWRevealViewController") as! UIViewController
var initialViewController1 = storyboard1.instantiateViewControllerWithIdentifier("SWRevealViewController") as! UIViewController
self.window?.rootViewController = [initialViewController,initialViewController1]
self.window?.makeKeyAndVisible()
return true
}
You can not create segues between storyboards using Interface Builder.
It is only possible programmatically, example:
let storyBoardTwo = UIStoryboard(name: "storyBoardTwo", bundle: nil)
// Pick a view controller using it's identifier string set in Interface Builder.
let myVC = storyBoardTwo.instantiateViewControllerWithIdentifier("aViewController") as! UIViewController // Or use more specific (custom) type
// Push it to the navigation controller
self.navigationController.pushViewController(myVC, animated: true)
pushViewControllerwill simply put the myVC on top. This code is what a segue will end up doing. You can put this code anywhere in an existing ViewController, on a button tap IBAction or where ever needed.
If the pushed ViewController have any segues (from Storyboard or code) they will still work, as expected.
This of course works if you would want to programmatically load ViewController from one and the same Storyboard as well.

How can I load storyboard programmatically from class?

My problem is that I was looking for way to use both storyboard and xib. But I can't find proper way to load and show storyboard programmatically. Project was started developing with xib, and now it's very hard to nest all xib files in storyboard. So I was looking a way to do it in code, like with alloc, init, push for viewControllers. In my case I have only one controller in storyboard: UITableViewController, which has static cells with some content I want to show. If anyone knows proper way to work both with xib and storyboard without huge refactoring, I will appreciate for any help.
In your storyboard go to the Attributes inspector and set the view controller's Identifier. You can then present that view controller using the following code.
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:#"myViewController"];
vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController:vc animated:YES completion:NULL];
Swift 3
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "viewController")
self.navigationController!.pushViewController(vc, animated: true)
Swift 2
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("viewController")
self.navigationController!.pushViewController(vc, animated: true)
Prerequisite
Assign a Storyboard ID to your view controller.
IB > Show the Identity inspector > Identity > Storyboard ID
Swift (legacy)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("viewController") as? UIViewController
self.navigationController!.pushViewController(vc!, animated: true)
Edit: Swift 2 suggested in a comment by Fred A.
if you want to use without any navigationController you have to use like following :
let Storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = Storyboard.instantiateViewController(withIdentifier: "viewController")
present(vc , animated: true , completion: nil)
In attribute inspector give the identifier for that view controller and the below code works for me
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
DetailViewController *detailViewController = [storyboard instantiateViewControllerWithIdentifier:#"DetailViewController"];
[self.navigationController pushViewController:detailViewController animated:YES];
Try this
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *vc = [mainStoryboard instantiateViewControllerWithIdentifier:#"Login"];
[[UIApplication sharedApplication].keyWindow setRootViewController:vc];
in swift
NavigationController and pushController you can replace for
present(vc, animated:true , completion: nil)
For swift 4 and 5, you can do this. Good practice is set name of Storyboard equal to StoryboardID.
enum StoryBoardName{
case second = "SecondViewController"
}
extension UIStoryboard{
class func load(_ storyboard: StoryBoardName) -> UIViewController{
return UIStoryboard(name: storyboard.rawValue, bundle: nil).instantiateViewController(withIdentifier: storyboard.rawValue)
}
}
and then you can load your Storyboard in your ViewController like this:
class MyViewController: UIViewController{
override func viewDidLoad() {
super.viewDidLoad()
guard let vc = UIStoryboard.load(.second) as? SecondViewController else {return}
self.present(vc, animated: true, completion: nil)
}
}
When you create a new Storyboard just set the same name on StoryboardID and add Storyboard name in your enum "StoryBoardName"
You can always jump right to the root controller:
UIStoryboard* storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *vc = [storyboard instantiateInitialViewController];
vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController:vc animated:YES completion:NULL];
The extension below will allow you to load a Storyboard and it's associated UIViewController. Example: If you have a UIViewController named ModalAlertViewController and a storyboard named "ModalAlert" e.g.
let vc: ModalAlertViewController = UIViewController.loadStoryboard("ModalAlert")
Will load both the Storyboard and UIViewController and vc will be of type ModalAlertViewController. Note Assumes that the storyboard's Storyboard ID has the same name as the storyboard and that the storyboard has been marked as Is Initial View Controller.
extension UIViewController {
/// Loads a `UIViewController` of type `T` with storyboard. Assumes that the storyboards Storyboard ID has the same name as the storyboard and that the storyboard has been marked as Is Initial View Controller.
/// - Parameter storyboardName: Name of the storyboard without .xib/nib suffix.
static func loadStoryboard<T: UIViewController>(_ storyboardName: String) -> T? {
let storyboard = UIStoryboard(name: storyboardName, bundle: nil)
if let vc = storyboard.instantiateViewController(withIdentifier: storyboardName) as? T {
vc.loadViewIfNeeded() // ensures vc.view is loaded before returning
return vc
}
return nil
}
}

Resources