【问题标题】:Force NSView to redraw programmatically强制 NSView 以编程方式重绘
【发布时间】:2013-11-12 16:24:47
【问题描述】:

我的应用有两种不同的状态,每个状态都用一个 NSView 表示。

所以一次只显示一个视图,问题是当我在视图之间切换时,应用程序不会显示新状态,直到我手动调整窗口大小!

我搜索了这个问题并提供了不止一个解决方案,但没有一个对我有用:

[myView setNeedsDisplay:YES];
[myView display];
[[myView.window contentView] setNeedsDisplay:YES];


[mySubView1 setHidden:YES]; || [mySubView1 removeFromSuperView];

我什至将 myView 定义为 Outlet,但没有任何效果。

这是我的代码

if (appState == 1) {

    [self.splitView setFrameSize:CGSizeMake(self.splitView.frame.size.width, self.view.frame.size.height - 250)];

    [self.mySubView1 setHidden:NO];
    [self.mySubView2 setHidden:YES];

    [self.mySubView2 removeFromSuperview];
    [self.mySubView1 addSubview:self.inCallView];
}
else
{
    [self.splitView setFrameSize:CGSizeMake(self.splitView.frame.size.width, self.view.frame.size.height - 70)];

    [self.mySubView1 setHidden:YES];
    [self.mySubView2 setHidden:NO];

    [self.mySubView1 removeFromSuperview];
    [self.mySubView2 addSubview:self.chatHeaderView];
}
// I need to redraw here
[self.view setNeedsDisplay:YES];
[self.mySubView1 setNeedsDisplay:YES];
[self.mySubView2 setNeedsDisplay:YES];
// and nothing happened until I resize my window manually 

【问题讨论】:

  • setNeedsDisplay:YES 是正确的方法。
  • 我试过了,可惜没用:(
  • 请使用它并显示您正在使用它的代码,我相信有人可以从那里拿走它。

标签: objective-c macos cocoa nsview


【解决方案1】:

我找到了,代码很好,不需要调用任何重绘方法,唯一的问题任何UI动作都需要在MAIN线程中完成

所以最终的代码是:

dispatch_async( dispatch_get_main_queue(), ^{
    if (appState == 1) {
        [self.splitView setFrameSize:CGSizeMake(self.splitView.frame.size.width, self.view.frame.size.height - 250)];

        [self.mySubView1 setHidden:NO];
        [self.mySubView2 setHidden:YES];
    }
    else
    {
        [self.splitView setFrameSize:CGSizeMake(self.splitView.frame.size.width, self.view.frame.size.height - 70)];

        [self.mySubView1 setHidden:YES];
        [self.mySubView2 setHidden:NO];
    }
});

谢谢各位。

【讨论】:

    【解决方案2】:

    执行子视图删除或添加操作将自动调用setNeedsDisplay:YES,因此手动调用它没有效果也就不足为奇了。

    需要检查的一些事项:

    1. 检查视图属性中的 nil 值。我看到您正在删除视图,这将导致超级视图释放它,如果您没有使用强大的属性(或其他地方)保留它,它将被释放。
    2. 确保您没有与自动布局作斗争。暂时关闭自动布局以确认它不会导致您的问题。
    3. 您只是在设置帧大小。您需要确保它也具有预期的来源。

    此外,如果您要删除视图,则无需费心致电setHidden:

    【讨论】:

    • 谢谢布拉德,我再次检查了您的所有积分;我想告诉我手动调整窗口大小时每件事都很好(窗口重绘它自己)。是的,没有必要设置隐藏-我将删除它-,再次感谢:)
    • 不,问题是我必须手动调整窗口大小才能得到结果。这意味着它不是零;并且自动布局和原点正如预期的那样。只想重绘它而不让用户改变窗口的大小
    猜你喜欢
    • 1970-01-01
    • 2014-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-16
    • 1970-01-01
    • 2012-08-06
    • 1970-01-01
    相关资源
    最近更新 更多