在显示然后隐藏 UIView 覆盖层后,UIWebView 屏幕点击区域停止工作
UIWebView screen taps in area cease to work after showing then hiding a UIView overlay
我一直在开发一款具有全屏 UIWebView 的应用程序,其中包含基于 HTML 的应用程序。它的特点是使用 JS 和本机 Obj-C 代码之间的本机桥接进行工作 QR 码扫描。点击一个按钮会启动这个 UIView,它大约是整个显示尺寸的一半,作为一个覆盖层,在其中你可以看到视频源,当检测到 QR 代码时,它会传回代码并关闭 UIView。这很管用。
但是 UIWebview 然后遇到了一个奇怪的问题,UIView 下面的任何元素都变得不可点击。好像UIView的幽灵还在。
知道为什么会发生这种情况吗?
- (void)handleCall:(NSString*)functionName callbackId:(int)callbackId args:(NSArray*)args
{
if ([functionName isEqualToString:@"setBackgroundColor"]) {
....... SNIP ........
}
else if ([functionName isEqualToString:@"scanQRCode"]) {
_viewPreview = [[UIView alloc] initWithFrame:CGRectMake(256, 192, 512, 384)];
[self addSubview:self.viewPreview];
[self bringSubviewToFront:_viewPreview];
_captureSession = nil;
if (!_isReading) {
if ([self startReading]) {
NSLog(@"Read barcode: %@", @"started");
}
}
else{
[self stopReading];
[_viewPreview removeFromSuperview];
[_viewPreview release];
}
_isReading = !_isReading;
}
else
{
NSLog(@"Unimplemented method '%@'",functionName);
[uniReader requestSwipe];
[self returnResult:callbackId args:nil];
}
}
- (BOOL)startReading {
NSError *error;
AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
if (!input) {
NSLog(@"%@", [error localizedDescription]);
return NO;
}
_captureSession = [[AVCaptureSession alloc] init];
[_captureSession addInput:input];
AVCaptureMetadataOutput *captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init];
[_captureSession addOutput:captureMetadataOutput];
dispatch_queue_t dispatchQueue;
dispatchQueue = dispatch_queue_create("myQueue", NULL);
[captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatchQueue];
[captureMetadataOutput setMetadataObjectTypes:[NSArray arrayWithObject:AVMetadataObjectTypeQRCode]];
_videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];
[_videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
[_videoPreviewLayer setFrame:_viewPreview.layer.bounds];
[_viewPreview.layer addSublayer:_videoPreviewLayer];
// Since the app is landscape only, it is necessary to rotate the preview view to match
[_videoPreviewLayer.connection setVideoOrientation:AVCaptureVideoOrientationLandscapeLeft];
// Start video capture.
[_captureSession startRunning];
return YES;
}
-(void)stopReading{
[_captureSession stopRunning];
_captureSession = nil;
NSLog(@"Read barcode: %@", @"Stop scanning");
[_videoPreviewLayer removeFromSuperlayer];
}
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection: (AVCaptureConnection *)connection{
// Check if the metadataObjects array is not nil and it contains at least one object.
if (metadataObjects != nil && [metadataObjects count] > 0) {
// Get the metadata object.
AVMetadataMachineReadableCodeObject *metadataObj = [metadataObjects objectAtIndex:0];
NSString *barcodeString = metadataObj.stringValue;
NSLog(@"Detected QR: %@", barcodeString);
NSString *javaScript = [NSString stringWithFormat:@"setQR('%@')", barcodeString];
if ([[metadataObj type] isEqualToString:AVMetadataObjectTypeQRCode]) {
// If the found metadata is equal to the QR code metadata then update the status label's text,
// stop reading and change the bar button item's title and the flag's value.
// Everything is done on the main thread.
[self performSelectorOnMainThread:@selector(stopReading) withObject:nil waitUntilDone:NO];
_isReading = NO;
[self performSelectorOnMainThread:@selector(stringByEvaluatingJavaScriptFromString:) withObject:javaScript waitUntilDone:NO];
}
}
}
@end
scanQRCode 是否被调用了两次:一次用于添加,一次用于移除覆盖?如果是这样,那么您总是在开始时添加一个新的叠加视图。任何 stopReading 都会从其超级视图(原始覆盖)中删除 运行 视频,然后从屏幕上删除最新的覆盖。这将使原始叠加 window 没有任何内容,这可能是您的问题?
我一直在开发一款具有全屏 UIWebView 的应用程序,其中包含基于 HTML 的应用程序。它的特点是使用 JS 和本机 Obj-C 代码之间的本机桥接进行工作 QR 码扫描。点击一个按钮会启动这个 UIView,它大约是整个显示尺寸的一半,作为一个覆盖层,在其中你可以看到视频源,当检测到 QR 代码时,它会传回代码并关闭 UIView。这很管用。
但是 UIWebview 然后遇到了一个奇怪的问题,UIView 下面的任何元素都变得不可点击。好像UIView的幽灵还在。
知道为什么会发生这种情况吗?
- (void)handleCall:(NSString*)functionName callbackId:(int)callbackId args:(NSArray*)args
{
if ([functionName isEqualToString:@"setBackgroundColor"]) {
....... SNIP ........
}
else if ([functionName isEqualToString:@"scanQRCode"]) {
_viewPreview = [[UIView alloc] initWithFrame:CGRectMake(256, 192, 512, 384)];
[self addSubview:self.viewPreview];
[self bringSubviewToFront:_viewPreview];
_captureSession = nil;
if (!_isReading) {
if ([self startReading]) {
NSLog(@"Read barcode: %@", @"started");
}
}
else{
[self stopReading];
[_viewPreview removeFromSuperview];
[_viewPreview release];
}
_isReading = !_isReading;
}
else
{
NSLog(@"Unimplemented method '%@'",functionName);
[uniReader requestSwipe];
[self returnResult:callbackId args:nil];
}
}
- (BOOL)startReading {
NSError *error;
AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
if (!input) {
NSLog(@"%@", [error localizedDescription]);
return NO;
}
_captureSession = [[AVCaptureSession alloc] init];
[_captureSession addInput:input];
AVCaptureMetadataOutput *captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init];
[_captureSession addOutput:captureMetadataOutput];
dispatch_queue_t dispatchQueue;
dispatchQueue = dispatch_queue_create("myQueue", NULL);
[captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatchQueue];
[captureMetadataOutput setMetadataObjectTypes:[NSArray arrayWithObject:AVMetadataObjectTypeQRCode]];
_videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];
[_videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
[_videoPreviewLayer setFrame:_viewPreview.layer.bounds];
[_viewPreview.layer addSublayer:_videoPreviewLayer];
// Since the app is landscape only, it is necessary to rotate the preview view to match
[_videoPreviewLayer.connection setVideoOrientation:AVCaptureVideoOrientationLandscapeLeft];
// Start video capture.
[_captureSession startRunning];
return YES;
}
-(void)stopReading{
[_captureSession stopRunning];
_captureSession = nil;
NSLog(@"Read barcode: %@", @"Stop scanning");
[_videoPreviewLayer removeFromSuperlayer];
}
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection: (AVCaptureConnection *)connection{
// Check if the metadataObjects array is not nil and it contains at least one object.
if (metadataObjects != nil && [metadataObjects count] > 0) {
// Get the metadata object.
AVMetadataMachineReadableCodeObject *metadataObj = [metadataObjects objectAtIndex:0];
NSString *barcodeString = metadataObj.stringValue;
NSLog(@"Detected QR: %@", barcodeString);
NSString *javaScript = [NSString stringWithFormat:@"setQR('%@')", barcodeString];
if ([[metadataObj type] isEqualToString:AVMetadataObjectTypeQRCode]) {
// If the found metadata is equal to the QR code metadata then update the status label's text,
// stop reading and change the bar button item's title and the flag's value.
// Everything is done on the main thread.
[self performSelectorOnMainThread:@selector(stopReading) withObject:nil waitUntilDone:NO];
_isReading = NO;
[self performSelectorOnMainThread:@selector(stringByEvaluatingJavaScriptFromString:) withObject:javaScript waitUntilDone:NO];
}
} }
@end
scanQRCode 是否被调用了两次:一次用于添加,一次用于移除覆盖?如果是这样,那么您总是在开始时添加一个新的叠加视图。任何 stopReading 都会从其超级视图(原始覆盖)中删除 运行 视频,然后从屏幕上删除最新的覆盖。这将使原始叠加 window 没有任何内容,这可能是您的问题?