gpt4 book ai didi

ios - 调用 removeFromSuperlayer 后 CALayer 仍然显示

转载 作者:行者123 更新时间:2023-11-29 12:44:40 32 4
gpt4 key购买 nike

我在同步一组函数调用时遇到了一些问题。我想要实现的是

  1. 显示我的第一个 View 并允许它捕获鼠标坐标
  2. 删除我的第一个 View ,然后根据第一步中的鼠标坐标使用 CGWindowListCreateImage 捕获屏幕截图。
  3. 显示我的第二个观点。

除了第一个 View 在屏幕截图期间未被删除外,一切正常。我不确定是什么导致了这个问题。第一个 View 确实有一些基本的核心动画。我已经覆盖了 drawRect 方法来应用一些自定义动画。我尝试在以下代码中运行代码,认为问题可能是由于运行循环无法在屏幕截图之前删除 View 引起的。

[[NSOperationQueue mainQueue] addOperationWithBlock:^{

}];

这是我处理转换的整个函数。当在调试器中运行它并在函数的开头设置断点并逐行越过它时,第一个 View 总是在屏幕捕获期间被删除。因此,为什么我觉得这是导致我出现问题的同步问题。

- (void)mouseUp:(NSEvent *)theEvent{

//Get point based on screen cordiates not releative to any window or view.
_endPoint = [NSEvent mouseLocation];

//Remove the shape layer from screen
[self.shapeLayer removeAllAnimations];
[self.shapeLayer removeFromSuperlayer];
self.shapeLayer = nil;

//Grab a pointer to the window so we can add the View 2
NSWindow * win = self.view.window;

//Order the window out so that we can capture the screen without capturing our transparent view
//[win orderOut:nil];
//set the current view to hidden so that it does not conflic with the screen capture
//[self.view setHidden:YES];

//proceed to remove it fromt the superview as we nolonger need it
[self.view removeFromSuperview];



//Get the rect of the main screen so we can calculate our capture rectangle
NSRect screenRect = [[NSScreen mainScreen]frame];

//Capture rect

_squareRect = CGMakeRect(blah,balh,blah,blah);

//Capture the screen with the specified rectangle
NSImage * image = [self captureScreen:_squareRect];
[self addToPastBoard:image];

//Create the Edit view and inject the image
EditControlsViewController *editViewController = [[EditControlsViewController alloc]initWithNibName:@"EditControlsViewController" bundle:[NSBundle mainBundle] image:image];

//Set the frame and bounds of the edit view
[editViewController.view setFrame:self.view.window.frame];
[editViewController.view setBounds:self.view.window.frame];
editViewController.view.translatesAutoresizingMaskIntoConstraints = NO;
[editViewController.imgView setImage:image];

//Since our image has been captured order the window back to front;
//[win orderFront:nil];

//Replace the current view with the new view. Since we previously removed our view just add the new
//view as a subview of the content view
[win.contentView addSubview:editViewController.view positioned:NSWindowAbove relativeTo:nil];

NSView * editView = editViewController.view;


NSDictionary *views = NSDictionaryOfVariableBindings(editView);
[win.contentView addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[editView]|"
options:0
metrics:nil
views:views]];

[win.contentView addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[editView]|"
options:0
metrics:nil
views:views]];

//beautiful way to help debug constraints;
//[win visualizeConstraints:[win.contentView constraints]];


}

removeFromSuperLayer 是异步调用吗?

我可以做些什么来让 View 完成删除吗?

任何指针将不胜感激。提前致谢。

最佳答案

屏幕的所有更新都是异步进行的。您对屏幕状态进行了更改,然后在事件循环的下一次传递中,您的更改将呈现到屏幕上。在您的代码中,您应用更改,然后在更改发生之前捕获屏幕的当前状态。

将捕获屏幕截图的代码放在一个单独的方法中,然后使用 [self performSelect: @selector(screenshot) witObject: nil afterDelay: 0] 调用它。在应用屏幕更改后,该调用会将您的选择器排队,以便在事件循环的下一次结束时调用。

你也可以使用

dispatch_after(DISPATCH_TIME_NOW, 0, dispatch_get_main_queue(), ^
{
//Code to execute after servicing the event loop
}
);

我在 NSObject 上有一个类别,它实现了一个方法 performBlockOnMainQueue:afterDelay:,它使用的代码与上面的 dispatch_after 调用非常相似。由于它使用 block ,因此您希望在延迟后调用的代码是内联的,并且可以访问封闭范围内的变量。

编辑:您可以在我的 "RandomBlobs" project on github 中找到 NSObject+performBlockAfterDelay 类别

关于ios - 调用 removeFromSuperlayer 后 CALayer 仍然显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23954110/

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