Retired Document
Important: This document may not represent best practices for current development. Links to downloads and other resources may no longer be valid.
NSOpenGLView redraw problems after a window is closed and re-opened.
Q: I have an instance of an NSOpenGLView subclass that doesn't draw correctly after I close and then re-open its window. What's happening, and how can I fix it?
A: In Mac OS X, version 10.3 and earlier, NSOpenGLView doesn't redraw properly after the window it's in has been closed and re-opened. One easy work-around is to remove the view from the view hierarchy, and then re-insert it.
In the code below, MyOpenGLView registers itself for the notification that its window will close. In the -prepareForWindowClosing:
method, the view also registers itself for the NSWindowDidUpdateNotification, which will be sent when the window is re-opened.
The -windowReopened:
method retains the view, removes it from the view hierarchy, then re-inserts it and balances the -retain
message with a -release
message.
Listing 1 Resetting NSOpenGLView's drawing environment
@implementation MyOpenGLView |
- (void) awakeFromNib |
{ |
[[NSNotificationCenter defaultCenter] |
addObserver: self |
selector: @selector(prepareForWindowClosing:) |
name: NSWindowWillCloseNotification |
object: [self window]]; |
} |
- (void) prepareForWindowClosing:(NSNotification *) notification |
{ |
// we'll need to know the next time the window updates, |
// which will be when it's re-opened. |
[[NSNotificationCenter defaultCenter] |
addObserver: self |
selector: @selector(windowReopened:) |
name: NSWindowDidUpdateNotification |
object: [self window]]; |
// Make sure we draw right away when the window is re-opened. |
[self setNeedsDisplay:YES]; |
} |
- (void) windowReopened:(NSNotification *)aNotification |
{ |
// Fix up the state of the NSOpenGLView by removing it from and |
// re-adding it to the view hierarchy |
NSView *superviewStash = [self superview]; |
[self retain]; // Must retain before removing from superview |
[self removeFromSuperview]; |
[superviewStash addSubview:self]; |
[self release]; // Must balance all -retain and -release messages. |
// After this, we don't care about window exposed notifications, so |
// we'll stop listening for them |
[[NSNotificationCenter defaultCenter] |
removeObserver:self |
name:NSWindowDidUpdateNotification |
object:[self window]]; |
} |
- (void)dealloc |
{ |
[[NSNotificationCenter defaultCenter] removeObserver:self]; |
[super dealloc]; |
} |
@end |
Document Revision History
Date | Notes |
---|---|
2014-03-06 | Workaround for NSOpenGLView failure to draw after its window is closed and re-opened. |
2004-12-03 | New document that workaround for NSOpenGLView failure to draw after its window is closed and re-opened. |
Copyright © 2004 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2004-12-03