单击按钮时 UIWebView 打开相机和图像
UIWebView opening the camera and images when a button is clicked
我目前正在将一个 webApp 包装成一个应用程序。在网络应用程序中有一个按钮,单击该按钮会自动询问您是否要转到存储图像的相机,选择后将为您上传图像。在 phone 浏览器的网络应用程序中,这按预期工作。
现在我已经将 webApp 包装在 UIWebView 中,此功能不再有效。选择上述任一选项时,它实际上似乎关闭了 UIWebview。有谁知道通过 UIWebView 使其工作的程序是什么。
我必须给予许可吗?或者还有更多功能,比如在单击按钮时检测 HTML 并从 UIWebView 处理它。
按钮上的 HTML 看起来像这样。
<input type="file" required id="file" name="file" accept="image/*" multiple>
添加代码
WebViewController.h
#import <UIKit/UIKit.h>
@interface WebViewController : UIViewController <UIWebViewDelegate,UINavigationControllerDelegate, UIImagePickerControllerDelegate>
{
UIViewController *viewController;
}
.......
WebViewController.m
#import "WebViewController.h"
#import <AssetsLibrary/AssetsLibrary.h>
#import "AppDelegate.h"
@end
@implementation WebViewController
- (void)viewDidLoad
{
[super viewDidLoad];
viewController = [[UIViewController alloc] init];
NSString *fullURL = self.mainURL; // get this from defualts - have removed code for this
NSURL *url = [NSURL URLWithString:fullURL];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[_viewWeb loadRequest:requestObj];
ALAssetsLibrary *lib = [[ALAssetsLibrary alloc] init];
[lib enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
NSLog(@"%i",[group numberOfAssets]);
} failureBlock:^(NSError *error) {
if (error.code == ALAssetsLibraryAccessUserDeniedError) {
NSLog(@"user denied access, code: %i",error.code);
}else{
NSLog(@"Other error code: %i",error.code);
}
}];
}
-(void)webViewDidStartLoad:(UIWebView *)viewWeb
{
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
}
- (void)webViewDidFinishLoad:(UIWebView *)viewWeb
{
}
//Note: I check to make sure the camera is available. If it is not (iPod touch or Simulator) I show the photo library instead.
-(void) showCamera
{
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
}
else
{
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
imagePicker.delegate = self;
[viewController presentViewController:imagePicker animated:YES completion:nil];
}
//Here we intercept any time the webview tries to load a document. When the user hits our "showcamera: url" we go to work.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:
(UIWebViewNavigationType)navigationType
{
if ([request.URL.scheme isEqualToString:@"myApp"])
{
if ([request.URL.host isEqualToString:@"myFunction"])
{
[self showCamera];
}
return NO;
}
return YES;
}
//After the imagepicker has done it's thing, we pass the data back to the webview to be displayed.
//If we wanted to be fancy here, we could have done this via Javascript so we could dynamically insert an image without reloading the page.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[viewController dismissViewControllerAnimated:YES completion:nil];
UIImage* image = [info objectForKey:UIImagePickerControllerOriginalImage];
NSData *imageData = UIImageJPEGRepresentation (image, 0.5);
NSURL *tmp = [NSURL URLWithString:@"ignore"];
[_viewWeb loadData:imageData MIMEType:@"image/jpeg" textEncodingName:@"UTF-8" baseURL:tmp];
}
@end
我删除了一些不相关的代码
作为替代方法,您可以尝试使用 UIWebViewDelegate 的方法 webView:shouldStartLoadWithRequest:navigationType:
来捕获自定义事件:
在你的HTML中:
<a href="myApp://myFunction">Do something</a>
<button onclick="window.location.href='myApp://myFunction'">Do some action</button>
然后:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if ([request.URL.scheme isEqualToString:@"myApp"]) {
if ([request.URL.host isEqualToString:@"myFunction"]) {
// do something
}
return NO;
}
return YES;
}
我已经设法解决了这个问题,它可以追溯到 iOS 8 中发现但仍未修复的错误。它与 UIWebView 的呈现方式有关。
添加此代码修复它。
-(void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion
{
if ( self.presentedViewController)
{
[super dismissViewControllerAnimated:flag completion:completion];
}
}
对于任何对此感到困惑或挣扎的人请注意,您不需要开始摆弄 UIImagePicker 或 UIWebView 委托。您的网络视图应负责打开相机库或相机。这是一个真正令人痛苦的问题,因此希望这可以帮助处于我位置的其他人。您还可以看到 THIS 问题,因为这是我得到答案的地方。也感谢安德烈的帮助
我目前正在将一个 webApp 包装成一个应用程序。在网络应用程序中有一个按钮,单击该按钮会自动询问您是否要转到存储图像的相机,选择后将为您上传图像。在 phone 浏览器的网络应用程序中,这按预期工作。
现在我已经将 webApp 包装在 UIWebView 中,此功能不再有效。选择上述任一选项时,它实际上似乎关闭了 UIWebview。有谁知道通过 UIWebView 使其工作的程序是什么。
我必须给予许可吗?或者还有更多功能,比如在单击按钮时检测 HTML 并从 UIWebView 处理它。
按钮上的 HTML 看起来像这样。
<input type="file" required id="file" name="file" accept="image/*" multiple>
添加代码
WebViewController.h
#import <UIKit/UIKit.h>
@interface WebViewController : UIViewController <UIWebViewDelegate,UINavigationControllerDelegate, UIImagePickerControllerDelegate>
{
UIViewController *viewController;
}
.......
WebViewController.m
#import "WebViewController.h"
#import <AssetsLibrary/AssetsLibrary.h>
#import "AppDelegate.h"
@end
@implementation WebViewController
- (void)viewDidLoad
{
[super viewDidLoad];
viewController = [[UIViewController alloc] init];
NSString *fullURL = self.mainURL; // get this from defualts - have removed code for this
NSURL *url = [NSURL URLWithString:fullURL];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[_viewWeb loadRequest:requestObj];
ALAssetsLibrary *lib = [[ALAssetsLibrary alloc] init];
[lib enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
NSLog(@"%i",[group numberOfAssets]);
} failureBlock:^(NSError *error) {
if (error.code == ALAssetsLibraryAccessUserDeniedError) {
NSLog(@"user denied access, code: %i",error.code);
}else{
NSLog(@"Other error code: %i",error.code);
}
}];
}
-(void)webViewDidStartLoad:(UIWebView *)viewWeb
{
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
}
- (void)webViewDidFinishLoad:(UIWebView *)viewWeb
{
}
//Note: I check to make sure the camera is available. If it is not (iPod touch or Simulator) I show the photo library instead.
-(void) showCamera
{
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
}
else
{
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
imagePicker.delegate = self;
[viewController presentViewController:imagePicker animated:YES completion:nil];
}
//Here we intercept any time the webview tries to load a document. When the user hits our "showcamera: url" we go to work.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:
(UIWebViewNavigationType)navigationType
{
if ([request.URL.scheme isEqualToString:@"myApp"])
{
if ([request.URL.host isEqualToString:@"myFunction"])
{
[self showCamera];
}
return NO;
}
return YES;
}
//After the imagepicker has done it's thing, we pass the data back to the webview to be displayed.
//If we wanted to be fancy here, we could have done this via Javascript so we could dynamically insert an image without reloading the page.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[viewController dismissViewControllerAnimated:YES completion:nil];
UIImage* image = [info objectForKey:UIImagePickerControllerOriginalImage];
NSData *imageData = UIImageJPEGRepresentation (image, 0.5);
NSURL *tmp = [NSURL URLWithString:@"ignore"];
[_viewWeb loadData:imageData MIMEType:@"image/jpeg" textEncodingName:@"UTF-8" baseURL:tmp];
}
@end
我删除了一些不相关的代码
作为替代方法,您可以尝试使用 UIWebViewDelegate 的方法 webView:shouldStartLoadWithRequest:navigationType:
来捕获自定义事件:
在你的HTML中:
<a href="myApp://myFunction">Do something</a>
<button onclick="window.location.href='myApp://myFunction'">Do some action</button>
然后:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if ([request.URL.scheme isEqualToString:@"myApp"]) {
if ([request.URL.host isEqualToString:@"myFunction"]) {
// do something
}
return NO;
}
return YES;
}
我已经设法解决了这个问题,它可以追溯到 iOS 8 中发现但仍未修复的错误。它与 UIWebView 的呈现方式有关。
添加此代码修复它。
-(void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion
{
if ( self.presentedViewController)
{
[super dismissViewControllerAnimated:flag completion:completion];
}
}
对于任何对此感到困惑或挣扎的人请注意,您不需要开始摆弄 UIImagePicker 或 UIWebView 委托。您的网络视图应负责打开相机库或相机。这是一个真正令人痛苦的问题,因此希望这可以帮助处于我位置的其他人。您还可以看到 THIS 问题,因为这是我得到答案的地方。也感谢安德烈的帮助