我在同步一组函数调用时遇到了一些问题。我想要实现的是
除了屏幕截图中没有删除第一个视图外,一切正常。我不确定是什么导致了这个问题。第一个视图确实有一些基本的核心动画。我已经覆盖了drawRect方法来应用一些自定义动画。我已经尝试在以下内容中运行代码,认为问题可能是由于runloop无法在屏幕截图之前删除视图。
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
}];
这是我处理转换的整个功能。在调试器中运行它并在函数开头设置断点并逐行跳过它时,在屏幕捕获期间始终会删除第一个视图。因此,为什么我觉得这是导致我问题的同步问题。
- (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是异步调用吗?
我可以做些什么来让视图完成删除?
任何指针都将非常感激。提前谢谢。
答案 0 :(得分:1)
屏幕的所有更新都是异步进行的。您可以更改屏幕状态,然后在下一次通过事件循环时,您的更改将呈现在屏幕上。在您的代码中,您应用更改,然后在更改发生之前捕获屏幕的CURRENT状态。
获取捕获屏幕截图的代码,将其放在单独的方法中,然后使用[self performSelect: @selector(screenshot) witObject: nil afterDelay: 0]
调用它。在应用了屏幕更改后,该调用将您的选择器排队,以便在下一次通过事件循环的END处调用。
您也可以使用
dispatch_after(DISPATCH_TIME_NOW, 0, dispatch_get_main_queue(), ^
{
//Code to execute after servicing the event loop
}
);
我在NSObject上有一个类,它实现了一个方法performBlockOnMainQueue:afterDelay:它使用的代码与上面的dispatch_after调用非常相似。由于它使用块,因此延迟后要调用的代码是内联的,并且可以访问封闭范围内的变量。
中找到NSObject + performBlockAfterDelay类别