UIViewController presented without background - uiviewcontroller

When im present new VC background is clear and I can see previous VC.
Second VC is empty (without any view)
How FIX?
let vc = AddScrollVC()
let navController = UINavigationController(rootViewController: vc)
navController.modalPresentationStyle = .overFullScreen
present(navController, animated: true)
Second VC is presented, shown only button in navBar

You can solve the issue with replacing this code
let VC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PresentVC") as! PresentVC
VC.modalPresentationStyle = .overFullScreen
self.present(VC, animated: true, completion: nil)

Change the code like this, This is work fine for me
let VC = PresentVC()
VC.modalPresentationStyle = .overFullScreen
self.present(VC, animated: true, completion: nil)

Related

iOS share pdf with webView

I have a problem with webView. I completely load the content of webView:
func openUrl(fileURL: URL, htmlString: String) {
webView.loadHTMLString(htmlString, baseURL: fileURL)
}
but then I want to share content.
When I tried:
let activityController = UIActivityViewController(activityItems: [webView.request?.url], applicationActivities: nil)
let popover = activityController.popoverPresentationController
popover?.sourceView = self.view
popover?.barButtonItem = self.navigationItem.rightBarButtonItem
present(activityController, animated: true, completion: nil)
It didn't work, there wasn't image what i load from function loadHTMLString
How can i share it?
Does anybody know how this problem solve?

How to send data from AppDelegate to my subclass of ViewController in swift 4

I am using Swift 4.1 and I am wondering how to pass the url data that is given here:
func application(_ app: UIApplication, open url: URL,
options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool {
}
into my subclass of UIViewController I called HotSpotRISViewController. Here is what I attempted:
func application(_ app: UIApplication, open url: URL,
options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
let vc = HotSpotRISViewController()
vc.setURL(theURL: url)
let navigationController = UINavigationController(rootViewController: vc)
self.window!.rootViewController = navigationController
}
My HotSpotRISViewController contains this function:
func setURL(theURL: URL) {
self.url = theURL
print(self.url ?? "nil")
}
Inside my HotSpotRISViewController I have a property of type URL ready to be set. The above code correctly passes the info, because my print statement prints out the URL, but I get a black screen instead of my app. What am I missing? And then on the other hand, the following makes the app start up correctly but I have no idea how to pass the url data using this method:
func application(_ app: UIApplication, open url: URL,
options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool {
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = mainStoryboard.instantiateInitialViewController()
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()
}
I'm wondering how I can get both my app started up correctly without a black screen and pass the url data. Thank you.
You can add a global variable in your appDelegate file and fetch it with your setURL function :
In your AppDelegate.swift
var myurl: URL!
....
func application(_ app: UIApplication, open url: URL,
options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool {
self.myurl = url
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = mainStoryboard.instantiateInitialViewController()
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()
}
...
In your HotSpotRISViewController.swift
func setURL(theURL: URL) {
DispatchQueue.main.async {
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
self.url = appDelegate.myurl
}
}

Swift 3. Can present a UIViewController with UIWebViewDelegate but not push it

I have a UIViewController with UIWebViewDelegate. I found that I can present it just fine but not push it. If I try to push it the target view controller loads and executes any variables set but does not fire viewDidLoad() and instead just returns to my calling menu view controller without error.
I set a breakpoint on the first var declaration after the class and stepped through the code. When it got to webView init it flashed up the home (not target) view controller in the simulator and then continued though the var declarations before returning back to my home view controller.
Here is my menu code
works:
let myWebViewController = MyWebViewController()
myWebViewController.urlString = "myUrl"
present(myWebViewController, animated: true, completion: nil)
does not work
let myWebViewController = MyWebViewController()
myWebViewController.urlString = "myUrl"
let navController = (UIApplication.shared.delegate as! AppDelegate).navController
navController!.pushViewController(myWebViewController, animated: true)
Here is my redacted target view controller code. The URL to load is set in the menu.
import UIKit
class MyWebViewController: UIViewController, UIWebViewDelegate {
var urlString: String = "invalid url"
var url: URL {
return URL(string: urlString)!
}
var urlRequest: URLRequest {
var urlRequest = URLRequest(url: url)
return urlRequest
}
let webView: UIWebView = {
let view = UIWebView()
view.backgroundColor = .white
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
// declare various buttons and stack views
override func viewDidLoad() {
super.viewDidLoad()
webView.delegate = self
contentStackView.addArrangedSubview(webView)
mainStackView.addArrangedSubview(contentStackView)
view.addSubview(mainStackView)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
webView.loadRequest(urlRequest as URLRequest)
}
The problem has nothing to do with the web view, the web view controller, or anything else except where you're pushing the view controller. You are saying:
let navController = (UIApplication.shared.delegate as! AppDelegate).navController
navController!.pushViewController(myWebViewController, animated: true)
That is highly unusual. The usual thing is that we are inside a navigation interface already, and we push onto its stack:
let navController = self.navigationController
navController!.pushViewController(myWebViewController, animated: true)
But you are not saying that. Why not? I'm guessing it's because self does not have a navigationController. So you are successfully pushing onto the navigation controller, all right, but you are not seeing anything happening because the navigation controller is behind the scenes — the self view controller's view is blocking it or has replaced it.
And that explains why you never detect the url loading. Your call to webView.loadRequest is in viewWillAppear. But this view will not appear; it is behind the scenes. viewWillAppear is never called. Similarly viewDidLoad is not called, because this view is not going to load; the navigation controller is not occupying the interface — self is.
I could possibly think of one scenario why the webViewController is not being pushed.
The UIViewController from which you are trying to make the push might not be part of the navigation controller hierarchy.
Why don't you try using the code instead of getting the navController from AppDelegate
self.navigationController?.pushViewController(myWebViewController, animated: true)
If this doesn't work out then your are certainly doing something wrong.

Redirect to specific view

I want to redirect the user of my app to a specific view if he is logged in or not. This is my code:
override func viewDidLoad() {
super.viewDidLoad()
if FIRAuth.auth()?.currentUser != nil {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier :"LoginViewController") as! LoginViewController
self.present(viewController, animated: true)
}
else {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier :"SWRevealViewController") as! SWRevealViewController
self.present(viewController, animated: true)
}
}
If I open my app I always get a white screen.
Does anyone know my mistake?
It worked. I didn't connected the navigation controller in the storyboard. The code itself works finde.

Access to tabbar Controller from AppDelegate

I have this situation:
How can I access the 3rd Tab bar badge from AppDelegate?
I've used this code:
UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
UIViewController *vc = [[UIViewController alloc] init];
if ([nonLette isEqualToString:#"0"]) {
for (vc in tabBarController.viewControllers) {
if (vc.tabBarItem.tag == 999) {
vc.tabBarItem.badgeValue = nil;
}
}
but the self.window.rootViewController returns "start View" and so does not work.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let tabController = storyboard.instantiateViewController(withIdentifier: "TabBarViewController") as! TabBarViewController
let tabArray = tabController.tabBar.items as NSArray!
let alertTabItem = tabArray?.object(at: 3) as! UITabBarItem
alertTabItem.badgeValue = "10"
Ok, I'm resolved, but in part!!!
This method works well. With debug, I can see that now I can change the badge on desired tab, but in reality don't change in graphics (the red number not appear).
Some suggestion?
UIStoryboard* storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UITabBarController *myTabBarController = [storyboard instantiateViewControllerWithIdentifier:#"tabBarController"];
if ([nonLette isEqualToString:#"0"]) {
for (UIViewController *vc in myTabBarController.viewControllers) {
if (vc.tabBarItem.tag == 999) {
vc.tabBarItem.badgeValue = nil;
}
}
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
} else {
for (UIViewController *vc in myTabBarController.viewControllers) {
if (vc.tabBarItem.tag == 999) {
vc.tabBarItem.badgeValue = nonLette;
}
}
[UIApplication sharedApplication].applicationIconBadgeNumber=[result integerValue];
}
With the new XCode 11 and Swift 5 this is no longer possible.
Instead you want to do this in SceneDelegate.swift, in particular this function func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
You then want to do something like this.
self.window = self.window ?? UIWindow()//#JA- If this scene's self.window is nil then set a new UIWindow object to it.
//#Grab the storyboard and ensure that the tab bar controller is reinstantiated with the details below.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let tabBarController = storyboard.instantiateViewController(withIdentifier: "tabBarController") as! UITabBarController
self.window!.rootViewController = tabBarController //Set the rootViewController to our modified version with the StateController instances
self.window!.makeKeyAndVisible()
print("Finished scene setting code")
guard let _ = (scene as? UIWindowScene) else { return }
Hope this helps for the people using the newer XCode out there. The key here is appDelegate no longer has access to window, the sceneDelegate does. If you try to use appDelegate you will get an error that window no longer exists.
Make sure the identifier is set for the tabBarController in the storyboard so it can find it. You can name it whatever, but just refer to that name in the code here for the withIdentifier function