Dynamic Popups in Swift on label word selection - swift

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)

Related

How to navigate between tabs "TabBarController" and transfer data between them?

this code works almost as it should, but it opens a second window on top of the main one, and not separately. How do I programmatically navigate to another view controller?
let tableVC = self.storyboard?.instantiateViewController(withIdentifier: "SaveTableViewController") as! SaveTableViewController
tableVC.titleText = alert.textFields![0].text ?? "Test"
tableVC.tabBarController?.selectedIndex = 1
//self.tabBarController?.showDetailViewController(tableVC, sender: self)
//self.present(tableVC, animated: true, completion: nil)
Your tabBarController have a viewControllers array. If you want to show a specific ViewController programmatically you could set the selectedViewController attribute of your tabBarController to an element out of the viewControllers array...
For more detail: https://developer.apple.com/documentation/uikit/uitabbarcontroller/1621172-selectedviewcontroller

Quicklook always displays "no file to preview" error (url is valid)

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.

Cannot Programmatically Switch Storyboards

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);

Burger menu does not load when opening viewcontroller from push

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.

Change ViewController Swift

i have an issue. I would like to change the view controller in swift.
This is a part of my code:
if success == "1" {
NSLog("Login SUCCESS");
var prefs:NSUserDefaults = NSUserDefaults.standardUserDefaults()
prefs.setObject(mobile, forKey: "USERNAME")
prefs.setInteger(1, forKey: "ISLOGGEDIN")
prefs.synchronize()
self.presentViewController(OtpVC(), animated: true, completion: nil)
}
my OtpVC file is:
class OtpVC: UIViewController {
#IBOutlet weak var smsfield: UITextField!
#IBAction func continueButton(sender: AnyObject) {
}
}
The problem now is that when is login successful the page change and goes all black!
How i can fix that? Thanks in advance.
The page in blank is an indicator of that your view has not being loaded. And it seems like that's the case:
Please take a closer look, you are creating an instance of that class, but you are not instantiating the view of it.
In swift you can have single classes affecting several views in your
storyboards.
The correct way, should be:
if success == "1" {
NSLog("Login SUCCESS");
var prefs:NSUserDefaults = NSUserDefaults.standardUserDefaults()
prefs.setObject(mobile, forKey: "USERNAME")
prefs.setInteger(1, forKey: "ISLOGGEDIN")
prefs.synchronize()
var storyboard = UIStoryboard(name: "Main", bundle: nil)
"Main" here should be the name of the storyboard in which the OtpVC view is.
var controller = storyboard.instantiateViewControllerWithIdentifier("OtpVC") as! OtpVC
"OtpVC" here should be the storyboard identifier of your view
self.presentViewController(controller, animated: true, completion: nil)
}
Update:
Another root cause may be that your identifier is not well set at storyboard.
At your Identity Inspector settings should be similar to:
Here in Module, like I have no such Class on my targets it says None.
This could be something you may want to have a look at. Maybe in your storyboard you are referencing other target than the one with such OptVC class implementation.
You can also use segues.
Set a segue from one view controller to the one where you want to shift in the storyboard.
Also set the identifier of the segue in storyboard.
Now use below code
self.performSegueWithIdentifier("identifier", sender: self)
self.presentViewController(OtpVC(), animated: true, completion: nil)
With the line above, you'll create a new instance of OtpVC programmatically. It's not a problem if that's what you want and the view controller is coded properly to be initialized like that.
But because it's all black I assume you've created OtpVC in storyboard so you'll either need to use a segue like Sukhdeep Singh Kalra has suggested or instantiate it with:
let destination = storyboard?.instantiateViewControllerWithIdentifier("identifier") as! OtpVC
presentViewController(destination, animated: true, completion: nil)
Both options, you'll have to set an identifier.
To set an identifier for the latter, go to storyboard and click on your view controller. Make sure the view controller is selected by clicking the left yellow button on top of your view controller. Then in identity inspector, type in the identifier name and replace "identifier" in my example with that name.