I have an app which currently uses push notifications and we have started trying to open specific pages of the app from JSON pushes.
This is the code for one of possible pages to open:
//Extract the notification data
if let notificationPayload = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? NSDictionary {
// Get which page to open
let viewload = notificationPayload["view"] as? NSString
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
//Load correct view
if viewload == "videos" {
let mainStoryboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController : UIViewController = mainStoryboard.instantiateViewControllerWithIdentifier("Videos") as! UIViewController
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()
}
}
The problem is that doing this skips the viewcontroller that allows the burger menu to be opened at the side.
Is there a way to open the burger menu controller and load the correct view from the push?
If you need more information let me know, I'll post updates as needed
You generally shouldn't be creating a new window and setting the root view controller. At least not if you don't make the root view controller the true root VC for your app and ask it to display your specific content from the push.
Generally your root VC should understand that there may be a need to show a particular VC (from a push or somewhere else) and offer the app delegate a way to do that. That may be achieved by forwarding the request until some VC can handle it, it may be simply pushing it onto a navigation controller, it may be posting a notification, or it may be presenting a modal.
There are many potential options, you need to decide which is correct for your app, but the important part is that it ties in with your existing view hierarchy rather than replacing it.
Related
All:
I am doing a swift , cocoa macos app project with multiple ViewControllers in one storyboard.
I know if I do segue and link the segue from second ViewController to first ViewController.
I can pop out ViewController.
But what if I have a function and want to call another ViewController to present programmatically from first ViewController?
I search a lot of examples start with UIStoryBoard, but my Storyboard is NSStoryboard.
Could anyone hint me a little to start with?
my code:
func checkPassword(SystemMsg:String) -> String{
//print("x")
let storyBoard = NSStoryboard(name: "Main", bundle: nil)
let mainViewController : NSViewController = storyBoard.instantiateController(withIdentifier: "PasswordInput") as! NSViewController
//self.present(mainViewController, asPopoverRelativeTo: <#T##NSRect#>, of: sender, preferredEdge: NSRectEdge, behavior: <#T##NSPopover.Behavior#>)
return ""
}
And my viewController in storyboard look like(no segue,no link):
enter image description here
If anyone can guide me through this step by step would be appreciated.
I figure it out myself.
The most simple way contains 4 steps:
Identify your main ViewController and second ViewController in storyboard
Create your main ViewController with instantiateController
Create your second ViewController with instantiateController
use presentAsModalWindow or presentAsSheet to present secondController on main ViewController
first we need to Identify storyboard correctly:
Identify first storyboard , we need to click top blue cube and then name it in Storyboard Id area
Identify second storyboard , we need to click top blue cube and then name it in Storyboard Id area
example code:
func checkPassword(SystemMsg:String) -> String{
//print("x")
//let storyBoard = NSStoryboard(name: "Main", bundle: nil)
let mainViewController : NSViewController = self.storyboard?.instantiateController(withIdentifier: "MainController") as! NSViewController
let passwordInputViewController : NSViewController = self.storyboard?.instantiateController(withIdentifier: "PasswordInput") as! NSViewController
mainViewController.presentAsModalWindow(passwordInputViewController)
//Or
mainViewController.presentAsSheet(passwordInputViewController)
return ""
}
If I miss something please correct me gently.
reference: Transitioning between view controller, OS X
PS. if you want to pass value between ViewController, this is good reference : https://learnappmaking.com/pass-data-between-view-controllers-swift-how-to/#back-properties
I'm trying to use QuickLookController subclass as a child controller, setting its view as a subview in the parent. However, it always displays "no file to preview" message in the opening window. URL in the data source is valid, but the controller is never trying to get it! func previewItemAt index is never invoked!
func "numberOfPreviewItems" invokes always.
Please, help!
I get it. driven by example in article https://williamboles.me/hosting-viewcontrollers-in-cells/ I loaded my controller from bundle:
static func createFromStoryBoard() -> PreviewControler {
let storyboard = UIStoryboard(name: "PreviewControler", bundle: Bundle(for: PreviewControler.self))
guard let viewController = storyboard.instantiateViewController(withIdentifier: "PreviewControler") as? PreviewControler else {
fatalError("PreviewControler should be present in storyboard")
}
return viewController
}
But QuickLook controller must be created with it's constructor, so change to
let viewController = PreviewController()
solved the problem. Now all is fine.
So I am trying to transition from my sign in viewcontroller to my tabbarcontroller, after a successful login.
When I enter my login details and press the sign in button, I am redirected to the Appdelegate page with a signal SIGABRT error.
I tried using this code in my viewcontroller:
let mainPage = self.storyboard?.instantiateViewController(withIdentifier: "CustomViewController") as! CustomViewController
self.present(mainPage, animated: true, completion: nil)
What's in CustomViewController? If you're instantiating that one directly as a ViewController instead of as a UiTabBarViewController, I'm thinking you will need to add the Sub ViewControllers for each one of the Tabs manually. But it's difficult to be sure without looking at what you have in CustomViewController.
Have you tried to set the application's rootViewController to the UITabBarController instance?
For example, this would set application's rootViewController to the tab bar controller:
let mainPage = self.storyboard?.instantiateViewController(withIdentifier: "CustomViewController") as! CustomViewController
UIApplication.shared.keyWindow?.rootViewController = mainPage
I'm attempting to switch storyboards when a button only if a condition (The textfield not being empty) is met. I found this piece of code as an answer to a similar question, and it doesn't seem to be working. My program crashes with "'Storyboard () doesn't contain a view controller with identifier 'Avatar Controller''"
I'm not completely sure as to where to find the view controller identifies, or whether or not I have to add '.storyboard' at the end of the storyboard name.
let storyboard = UIStoryboard(name: "Avatar", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "Avatar Controller")
self.navigationController!.pushViewController(vc, animated: true)
To make it works, Use Storyboard ID has to be checked
This could be happening for 2 reasons.
1) Because in your Avatar.storyboard you are referencing a view controller with the id Avatar Controller but you have not set that value on any of the view controllers in the storyboard file. Go into your Avatar.storyboard, click on the view controller you want to show and go to this panel:
Make sure that the Storyboard ID for your viewController matches what value you use in storyboard.instantiateViewController(withIdentifier: "Avatar Controller")
2) Because you are not providing a bundle when you are loading your storyboard. You are calling this
let storyboard = UIStoryboard(name: "Avatar", bundle: nil);
but because you specify bundle as nil it doesn't know where to look for the Avatar.storyboard file. To fix it, specify bundle as Bundle.main:
let storyboard = UIStoryboard(name: "Avatar", bundle: Bundle.main);
I'm looking for a way to show a dynamically show a popup within a view controller when a user selects a particular word within a label.
For example
Click here for a link, click here for another link
The label text is pulled from a database so is dynamically added based on the content a user is viewing, i was hoping to use the URL schemes within Swift to show the correct popup depending on what a user selected, but when i add the following within app delegate the popup shows within a separate view controller and not as a pop up view controller.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let navVC = storyboard.instantiateViewControllerWithIdentifier("glossaryPopupID") as! UIViewController
self.window?.rootViewController?.presentViewController(navVC, animated: true, completion: nil)
return true
When the popup is close the screen behind is now blank rather than showing the original view controller.
SO my question is, whether this is the best way to achieve this as im not sure its best practice to used URL links within an app to link to other parts of the same app, or is there another way i am missing.
Think i have resolved this now, using the following;
let storyboard = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("test") as! ViewController
let popOverVC = UIStoryboard(name:"Main", bundle: nil).instantiateViewControllerWithIdentifier("sbPopUpID") as! PopUpViewController
storyboard.addChildViewController(popOverVC)
popOverVC.view.frame = storyboard.view.frame
storyboard.view.addSubview(popOverVC.view)
popOverVC.didMoveToParentViewController(storyboard)
self.window?.rootViewController?.presentViewController(storyboard, animated: true, completion: nil)