我有一个普通的 NSView 可以通过拖动窗口边缘来调整大小。
如果在 [NSView animator] 动画期间调整视图大小,它会继续动画到原始动画的最终大小,但不考虑新的窗口大小。
这是一个简单的示例项目。双击开始动画,然后在结束前调整窗口大小。
使动画考虑新帧大小的最佳方法是什么?
我有一个普通的 NSView 可以通过拖动窗口边缘来调整大小。
如果在 [NSView animator] 动画期间调整视图大小,它会继续动画到原始动画的最终大小,但不考虑新的窗口大小。
这是一个简单的示例项目。双击开始动画,然后在结束前调整窗口大小。
使动画考虑新帧大小的最佳方法是什么?
恕我直言,最好的方法是在调整大小阶段开始后立即停止动画。在调整大小阶段,用户可以控制并手动设置窗口的大小。当调整大小阶段结束时,窗口已经设置为所需的大小,因此无需做更多。
这种问题最好用 NSTimer 而不是 animator 函数来解决:
让定时器重复调用一个函数,直到动画“完成”。完成后,结束计时器(无效)。
在每个循环中重复调用的函数会获取窗口的实际帧大小和视图的实际帧大小,并简单地将两者差异的三分之一添加到视图的框架中,例如:
frame.size.height += diffHeight/3.0;
因此,无论发生什么,视图都会越来越接近其目的地。一旦abs(差异)小于例如0.2,您就可以将视图直接设置为所需的大小并结束计时器。这是直接的,只使用很少的代码,你不需要监听任何事件,而它执行得很好。:-)
以下是初始化动画的关键代码(计时器必须是您的类的实例):
if(timer)return;
timer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(resizeView:) userInfo:[NSNumber numberWithBool:status] repeats:YES];
[timer setTolerance:0.02];
我使用单词状态而不是关闭单词,重复调用的函数可能看起来有点像:
- (void)resizeView:(id)userInfo;
{
BOOL status = [(NSNumber *)[userInfo userInfo] boolValue];
double startwid,stopwid;
NSRect newSizeRect = [[self window] frame];
stopwid = newSizeRect.size.width;
if(status){
stopwid -= 100.0;
}
NSRect cbgRect = [self frame];
startwid = cbgRect.size.width;
double diff = stopwid-startwid;
if(fabs(diff)<0.2){
diff = 0;
startwid = stopwid;
[timer invalidate];
timer = nil;
//NSLog(@"stop");
}
//NSLog(@"%f - %f = %f /10 = %f",stopwid,startwid,diff,diff/3.0);
cbgRect.size.width = startwid+diff/3.0;
[self setFrame:cbgRect];
}