gpt4 book ai didi

ios - 在 SCNNode 上加载 WebView CALayer 的问题

转载 作者:可可西里 更新时间:2023-11-01 04:45:04 26 4
gpt4 key购买 nike

我正在寻求帮助来弄清楚如何解决这个问题。 SceneKit 允许您将 CALayer 设置为 SCNNode 外观的内容。是否可以从 UIWebView 获取 CALayer 并将其呈现为 SCNMaterial 的内容?

我正在尝试将 SCNNode 的扩散内容更改为函数中的 WebView 层 - (void)webViewDidFinishLoad:(UIWebView *)webView 完成,但代码崩溃。

但我收到此错误:43282] bool _WebTryThreadLock(bool),0x7fae33f33680:试图从主线程或 Web 线程以外的线程获取 Web 锁。这可能是从辅助线程调用 UIKit 的结果。现在崩溃...

这是我的引用代码

//
// GameViewController.h
// WebViewLayerTest
//

#import <UIKit/UIKit.h>
#import <SceneKit/SceneKit.h>

@interface GameViewController : UIViewController <UIWebViewDelegate,SCNNodeRendererDelegate>
@property (nonatomic, retain) IBOutlet UIWebView *webView;
@property (nonatomic,retain) SCNBox *box;
-(void) storeLayer;
@end



//
// GameViewController.m
// WebViewLayerTest
//
//

#import "GameViewController.h"
#import <QuartzCore/QuartzCore.h>

@implementation GameViewController

- (void)viewDidLoad
{
[super viewDidLoad];

self.webView = [[UIWebView alloc] initWithFrame:CGRectMake(10, 10, self.view.bounds.size.width-20.0, self.view.bounds.size.height-30.0)];

NSString *urlAddress = @"https://www.google.com/";
NSURL *url = [NSURL URLWithString:urlAddress];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:requestObj];

self.webView.delegate = self;

// create a new scene

SCNScene *scene = [SCNScene scene];

// create and add a camera to the scene
SCNNode *cameraNode = [SCNNode node];
cameraNode.camera = [SCNCamera camera];
[scene.rootNode addChildNode:cameraNode];

// // place the camera
cameraNode.position = SCNVector3Make(0, 0, 15);

// create and add a light to the scene
SCNNode *lightNode = [SCNNode node];
lightNode.light = [SCNLight light];
lightNode.light.type = SCNLightTypeOmni;
lightNode.position = SCNVector3Make(0, 10, 10);
[scene.rootNode addChildNode:lightNode];

// create and add an ambient light to the scene
SCNNode *ambientLightNode = [SCNNode node];
ambientLightNode.light = [SCNLight light];
ambientLightNode.light.type = SCNLightTypeAmbient;
ambientLightNode.light.color = [UIColor darkGrayColor];
[scene.rootNode addChildNode:ambientLightNode];


self.box = [SCNBox boxWithWidth:1.0 height:1.0 length:1.0 chamferRadius:0.05];
self.box.firstMaterial.diffuse.contents = [UIColor blueColor];

SCNNode* ship = [SCNNode nodeWithGeometry:self.box];
// // animate the 3d object
[ship runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:2 z:0 duration:1]]];
//
// // retrieve the SCNView
SCNView *scnView = (SCNView *)self.view;
//

[scene.rootNode addChildNode:ship];
// // set the scene to the view
scnView.scene = scene;

// allows the user to manipulate the camera
scnView.allowsCameraControl = YES;

// show statistics such as fps and timing information
scnView.showsStatistics = YES;

// configure the view
scnView.backgroundColor = [UIColor blackColor];




// add a tap gesture recognizer
// UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
// NSMutableArray *gestureRecognizers = [NSMutableArray array];
// [gestureRecognizers addObject:tapGesture];
// [gestureRecognizers addObjectsFromArray:scnView.gestureRecognizers];
// scnView.gestureRecognizers = gestureRecognizers;
}

- (void) handleTap:(UIGestureRecognizer*)gestureRecognize
{
// retrieve the SCNView
SCNView *scnView = (SCNView *)self.view;

// check what nodes are tapped
CGPoint p = [gestureRecognize locationInView:scnView];
NSArray *hitResults = [scnView hitTest:p options:nil];

// check that we clicked on at least one object
if([hitResults count] > 0){
// retrieved the first clicked object
SCNHitTestResult *result = [hitResults objectAtIndex:0];

// get its material
SCNMaterial *material = result.node.geometry.firstMaterial;

// highlight it
[SCNTransaction begin];
[SCNTransaction setAnimationDuration:0.5];

// on completion - unhighlight
[SCNTransaction setCompletionBlock:^{
[SCNTransaction begin];
[SCNTransaction setAnimationDuration:0.5];

material.emission.contents = [UIColor blackColor];

[SCNTransaction commit];
}];

material.emission.contents = [UIColor redColor];

[SCNTransaction commit];
}
}

- (void)webViewDidFinishLoad:(UIWebView *)webView {

NSLog(@"Finished Loading");

// self.box.firstMaterial.diffuse.contents = _webView.layer;

dispatch_async(dispatch_get_main_queue(),^ {
self.box.firstMaterial.diffuse.contents = _webView.layer;
} );
// [self performSelectorOnMainThread:@selector(storeLayer) withObject:nil waitUntilDone:YES];

}

-(void) storeLayer{
self.box.firstMaterial.diffuse.contents = _webView.layer;
}

- (BOOL)shouldAutorotate
{
return YES;
}

- (BOOL)prefersStatusBarHidden {
return YES;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
return UIInterfaceOrientationMaskAllButUpsideDown;
} else {
return UIInterfaceOrientationMaskAll;
}
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}

@end

最佳答案

我遇到了同样的问题,我通过以下方法解决了。

<强>1。实验发现可以直接使用CALayer设置diffuse.contents,但UIView不可以

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
guard let imageAnchor = anchor as? ARImageAnchor else { return }
let testLayer = CALayer()
testLayer.frame = self.view.bounds
testLayer.backgroundColor = UIColor.blue.cgColor

let referenceImage = imageAnchor.referenceImage
let plane = SCNPlane(width: referenceImage.physicalSize.width,
height: referenceImage.physicalSize.height)
plane.firstMaterial?.diffuse.contents = testLayer
let planeNode = SCNNode(geometry: plane)
planeNode.eulerAngles.x = -.pi / 2

node.addChildNode(planeNode)
}

<强>2。当 webview 完成加载时获取 webview 快照。

func captureWebview() -> UIImage{
var image : UIImage!
UIGraphicsBeginImageContextWithOptions(webView.scrollView.contentSize, webView.scrollView.isOpaque, 0.0)
let savedContentOffset = webView.scrollView.contentOffset
let savedFrame = webView.scrollView.frame
webView.scrollView.contentOffset = CGPoint.zero
webView.scrollView.frame = CGRect(x: 0, y: 0, width: webView.scrollView.contentSize.width,height: webView.scrollView.contentSize.height)

webView.scrollView.layer.render(in: UIGraphicsGetCurrentContext()!)
image = UIGraphicsGetImageFromCurrentImageContext()

webView.scrollView.contentOffset = savedContentOffset
webView.scrollView.frame = savedFrame

UIGraphicsEndImageContext()

return image
}

<强>3。将 webview 快照设置为 diffuse.contents

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
guard let imageAnchor = anchor as? ARImageAnchor else { return }

let referenceImage = imageAnchor.referenceImage
let plane = SCNPlane(width: referenceImage.physicalSize.width,
height: referenceImage.physicalSize.height)
plane.firstMaterial?.diffuse.contents = self.testImage
let planeNode = SCNNode(geometry: plane)
planeNode.eulerAngles.x = -.pi / 2

node.addChildNode(planeNode)


}

关于ios - 在 SCNNode 上加载 WebView CALayer 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41865319/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com