非脏视图被重绘
我确实有一个奇怪的问题。我编写了一个码头视图。
它基本上是一个 NSView,内部有三个垂直子视图。所以我有一个左侧停靠栏、一个中间视图和一个右侧停靠栏。两个底座都是可折叠的。中间视图在折叠时会调整大小。
我正在使用 CoreAnimation 来制作折叠过程的动画。这几乎是正确的。 如果我展开左侧停靠栏,则会调用右侧停靠栏 drawRect
方法,尽管它并不脏。
如果我停用动画器并直接设置新的帧大小,则右侧停靠栏在展开时不会重绘,因此我认为帧的计算是正确的。
这是我用于折叠码头的代码:
- (void) mouseDown:(NSEvent *)event
{
// Exit method if already animating a dock
if(is_animating)
{
return;
}
NSPoint firstPoint = [self convertPoint:[event locationInWindow] fromView:nil];
unsigned long divider = [self mousePointInCollapseRect:firstPoint];
// If not clicked on a divider don't animate anything
if(divider == NSNotFound)
{
return;
}
NSView* main_view = [[self subviews] objectAtIndex:VIEW_MIDDLE];
NSView* collapse_view = [[self subviews] objectAtIndex:(divider == 0)? VIEW_LEFT : VIEW_RIGHT];
NSRect cframe = [collapse_view frame]; // New collapsable frame
NSRect mframe = [main_view frame]; // New main frame
if([self isSubviewCollapsed:collapse_view] == NO)
{
if(divider == 0)
{
cframe.size.width = 0.0;
mframe.origin.x -= (dock_width_left + DIVIDER_THICKNESS);
mframe.size.width += (dock_width_left + DIVIDER_THICKNESS);
}
else
{
mframe.size.width += (collapse_view.frame.size.width + DIVIDER_THICKNESS);
cframe.size.width = 0.0;
cframe.origin.x = mframe.origin.x + mframe.size.width;
}
// Turn off autoresizesSubviews on the collapsible subview
[collapse_view setAutoresizesSubviews:NO];
[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:(ANIMATION_DURATION)];
[[collapse_view animator] setFrame:cframe];
[[main_view animator] setFrame:mframe];
[NSAnimationContext endGrouping];
}
else
{
// Uncollapse dock
if(divider == 0)
{
// Left dock
cframe.size.width = dock_width_left;
mframe.origin.x = (COLLAPSEBAR_THICKNESS + dock_width_left + DIVIDER_THICKNESS);
mframe.size.width -= (dock_width_left + DIVIDER_THICKNESS);
}
else
{
// Right dock
mframe.size.width -= (dock_width_right + DIVIDER_THICKNESS);
cframe.size.width = dock_width_right;
cframe.origin.x = mframe.origin.x + mframe.size.width + DIVIDER_THICKNESS;
}
[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:ANIMATION_DURATION];
[[main_view animator] setFrame:mframe];
[[collapse_view animator] setFrame:cframe];
[NSAnimationContext endGrouping];
//Restore Autoresizing on subview
[self performSelector:@selector(restoreAutoResizingOfSubview:) withObject:collapse_view afterDelay:ANIMATION_DURATION + 0.05];
}
is_animating = YES;
[self performSelector:@selector(animationEnded) withObject:nil afterDelay:ANIMATION_DURATION + 0.05];
}
那么为什么要重绘非脏视图呢?
I do have a strange problem. I programmed a a dockview.
It's basically a NSView with three vertical subviews inside. So I have a left dock, a middle view and a right dock. Both docks are collapsable. The middle view gets resized while collapsing.
I'm using CoreAnimation
to animate the collapsing process. This works almost correct.
If I uncollapse the left dock, the right docks drawRect
method gets called although it's not dirty.
If I deactivate the animator
and set the new frame size directly, the right dock not gets redrawn while uncollapsing so I assume the calculation of the frames is correct.
Here is my code for collapsing the docks:
- (void) mouseDown:(NSEvent *)event
{
// Exit method if already animating a dock
if(is_animating)
{
return;
}
NSPoint firstPoint = [self convertPoint:[event locationInWindow] fromView:nil];
unsigned long divider = [self mousePointInCollapseRect:firstPoint];
// If not clicked on a divider don't animate anything
if(divider == NSNotFound)
{
return;
}
NSView* main_view = [[self subviews] objectAtIndex:VIEW_MIDDLE];
NSView* collapse_view = [[self subviews] objectAtIndex:(divider == 0)? VIEW_LEFT : VIEW_RIGHT];
NSRect cframe = [collapse_view frame]; // New collapsable frame
NSRect mframe = [main_view frame]; // New main frame
if([self isSubviewCollapsed:collapse_view] == NO)
{
if(divider == 0)
{
cframe.size.width = 0.0;
mframe.origin.x -= (dock_width_left + DIVIDER_THICKNESS);
mframe.size.width += (dock_width_left + DIVIDER_THICKNESS);
}
else
{
mframe.size.width += (collapse_view.frame.size.width + DIVIDER_THICKNESS);
cframe.size.width = 0.0;
cframe.origin.x = mframe.origin.x + mframe.size.width;
}
// Turn off autoresizesSubviews on the collapsible subview
[collapse_view setAutoresizesSubviews:NO];
[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:(ANIMATION_DURATION)];
[[collapse_view animator] setFrame:cframe];
[[main_view animator] setFrame:mframe];
[NSAnimationContext endGrouping];
}
else
{
// Uncollapse dock
if(divider == 0)
{
// Left dock
cframe.size.width = dock_width_left;
mframe.origin.x = (COLLAPSEBAR_THICKNESS + dock_width_left + DIVIDER_THICKNESS);
mframe.size.width -= (dock_width_left + DIVIDER_THICKNESS);
}
else
{
// Right dock
mframe.size.width -= (dock_width_right + DIVIDER_THICKNESS);
cframe.size.width = dock_width_right;
cframe.origin.x = mframe.origin.x + mframe.size.width + DIVIDER_THICKNESS;
}
[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:ANIMATION_DURATION];
[[main_view animator] setFrame:mframe];
[[collapse_view animator] setFrame:cframe];
[NSAnimationContext endGrouping];
//Restore Autoresizing on subview
[self performSelector:@selector(restoreAutoResizingOfSubview:) withObject:collapse_view afterDelay:ANIMATION_DURATION + 0.05];
}
is_animating = YES;
[self performSelector:@selector(animationEnded) withObject:nil afterDelay:ANIMATION_DURATION + 0.05];
}
So why gets a non-dirty view redrawn?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论