I have a simple Swift project in which:
ViewController A (class ViewController: UIViewController
) presents ViewController B -- (class WebViewController: UIViewController, WKNavigationDelegate, CLLocationManagerDelegate, WKScriptMessageHandler
).
ViewController B is essentially just a WKWebView, here's its viewDidLoad()
:
let contentController = WKUserContentController();
contentController.addScriptMessageHandler(
self,
name: "eventHandler"
)
let config = WKWebViewConfiguration()
config.userContentController = contentController
webView = WKWebView(frame: CGRectZero, configuration: config)
webView.navigationDelegate = self
webView.allowsBackForwardNavigationGestures = false
view = webView
So, when ViewController B is presented, I basically just have a web browser on the entire screen.
The problem I'm running into is that, if the User (while on a webpage) clicks a "File Upload / File Picker", first I see this:
Passed in type public.item doesn't conform to either public.content or public.data. If you are exporting a new type, please ensure that it conforms to an appropriate parent type. the behavior of the UICollectionViewFlowLayout is not defined because the item width must be less than the width of the UICollectionView minus the section insets left and right values, minus the content insets left and right values.
The relevant UICollectionViewFlowLayout instance is <_UIAlertControllerCollectionViewFlowLayout: 0x12e30f270>, and it is attached to ; animations = { bounds.origin=; bounds.size=; position=; }; layer = ; contentOffset: {0, 0}; contentSize: {0, 0}> collection view layout: <_UIAlertControllerCollectionViewFlowLayout: 0x12e30f270>.
Then, if the User chooses "Take Photo or Video" or "Photo Library" from the iOS options list, I get this:
Warning: Attempt to present UIImagePickerController: 0x12d192200 on My.WebViewController: 0x12e2883e0 whose view is not in the window hierarchy!
The result is that:
Does anyone have any suggestions? I tried to provide the relevant code, but I can paste more if needed. Thank you.
-- UPDATE --------
Okay, so after more research, there are actually two separate things going on:
The first error is a function of how the "file picker" is handled by a mobile browser. See here ... grand scheme of things, not a big deal.
The second error Attempt to present UIImagePickerController...
-- the more debilitating of the two -- is uglier.
If a ViewController with a WKWebView is presented from another ViewController then, upon the User trying to "pick" an image (from library or camera), iOS will attempt to present the UIImagePicker from your WKWebView ViewController, which is what you want.
Unfortunately, for a reason I don't yet know, the act of the User trying to "pick" an image also causes iOS to dismiss the presented view controller ... which, in this case, is your WKWebView controller :( As such, the WKWebView ViewController dismisses, so it then isn't in the window hierarchy when it attempts to present the UIImagePicker -- hence, the error.
My solution (which is pretty hacky, but works for my particular use case), is as follows; I hope this helps someone:
This essentially makes it so the WKWebView cannot be dismissed, sidestepping the problem.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("Browser") as! WebViewController
UIApplication.sharedApplication().keyWindow?.rootViewController = vc
self.presentViewController(vc, animated: false, completion: { () -> Void in
self.dismissViewControllerAnimated(false, completion: nil)
})
A view controller that manages the system interfaces for taking pictures, recording movies, and choosing items from the user's media library.
kUTTypeImage is actually default for the mediaTypes property. It states, that one can only pick still images. If you are ok with this default, you don't need to set it explicitly in your code.
storyboard file and add two elements inside the view controller. The first one is a button, which will show up an image picker modal whenever it gets pressed. The second one is an image view. I'm going to put a placeholder image at first, but once the user selected an image, we'll display that image to that view.
The system Photos picker is the best way for most apps to access photos and videos on iOS. The picker runs out of process, so your app doesn't need to request any library access to use it. It has an intuitive UI and an easy-to-use API.
If you are doing int in viewDidLoad(){}
function currently then try to move code into override viewDidAppear(animated: Bool) {}
I had the same problem today and it fixed it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With