Having trouble with NSView setNeedsDisplay

  • Hi, all.
    I am trying to add an NSView (view) on an NSWindow (window) but I'm
    having
    a trouble with setNeedsDisplay of NSView.

    In a method, I add a view to a window's contentView, then call
    setFrame: display.
    The view is displayed when the method is called for the first time,
    but it is not
    displayed next time the same method is called.

    I checked [view needsDispay] in the method and as it was NO when the
    view was
    not displayed, I added [view setNeedsDisplay: YES].

    But what was strange was [view needsDisplay] was still NO even after
    [view setNeedsDisplay: YES] was added.

    BOOL beforeSet = [view needsDisplay];
    [view setNeedsDisplay: YES];
    BOOL afterSet = [view needsDisplay];

    I added above code in the method to see if [view needsDisplay] changed,
    and both beforeSet and afterSet were NO.

    There is no code between the lines so [view setNeedsDisplay: YES] seems
    not to be working as I expect, but in what case does this happen and how
    can I set needsDisplay YES?

    The view is connected to an NSView in nib file. As it is displayed when
    the method is called for the first time, it is correctly connected.

    Thank you.

    - Chataka
  • Am 23.11.2007 um 10:27 Uhr schrieb <Chataka...>:

    > I am trying to add an NSView (view) on an NSWindow (window)

    How are you doing this? Show some code.

    > so [view setNeedsDisplay: YES] seems
    > not to be working as I expect,

    All this does, is marking the view for redisplay during the next run
    through the run loop.

    > The view is connected to an NSView in nib file.

    You don't 'connect' views. You need to make your view a subview of the
    content view.

    > As it is displayed when
    > the method is called for the first time,

    What method? Views are drawn in drawRect:. You don't 'call methods' to
    draw them.

    I think you really need to post some code for us to understand your
    problem.

    Also, did you read this?

    http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaViewsGuide/I
    ntroduction/chapter_1_section_1.html


    Andreas
  • > How are you doing this? Show some code.

    Sorry for the vague question.

    What I am trying to do is attaching an NSView to an NSWindow,
    and NSView can be replaced.

    I wrote a method like:

    - (void) replaceView: (NSView *) anOldView
        withView: (NSView *) aNewView
        belowWindow: (NSWindow *) aWindow
    {
    NSRect newViewRect = NSZeroRect;
    NSRect oldViewRect = NSZeroRect;
    float windowDelta = 0;

    //----------------
    //  add new view
    //----------------
    NSArray * subviewArray = [[aWindow contentView] subviews];

    if ( [subviewArray containsObject: aNewView] == NO)
    {
      [[aWindow contentView] addSubview: aNewView];
    }

    //-----------------------------------
    //  calculate new window size delta
    //-----------------------------------
    if ( aNewView != nil )
    {
      newViewRect = [aNewView frame];
      windowDelta += [aNewView convertSize: newViewRect.size toView:
    nil].height;
    }

    if ( anOldView != nil )
    {
      oldViewRect = [anOldView frame];
      windowDelta -= [anOldView convertSize: oldViewRect.size toView:
    nil].height;
    }

    //-----------------------------------
    //  update window size and position
    //-----------------------------------
    NSRect newWindowRect = [aWindow frame];
    newWindowRect.size.height += windowDelta;
    newWindowRect.origin.y -= windowDelta;
    newViewRect.origin.y = 0.0;

    //-------------------
    //  remove old view
    //-------------------
    if ( ( anOldView != nil )
        && ( anOldView != aNewView ) )
    {
      [anOldView removeFromSuperview];
    }

    //--------------------------
    //  offset origin and show
    //--------------------------
    NSPoint newViewOrigin;
    newViewOrigin.x = newViewRect.origin.x;
    newViewOrigin.y = -windowDelta;
    [aNewView setFrameOrigin: newViewOrigin];

    // (wrote test code here)

    [aWindow setFrame: newWindowRect display: YES];
    }

    When this method is called for the first time (aNewView is a new view
    and anOldView is nil), aNewView is displayed in lower part of aWindow.

    But when the method is called next time (aNewView is another view and
    anOldView is previous aNewView), nothing is displayed and the lower
    part of the window is blank.

    Then I checked the value of [aNewView needsDisplay] before the
    [aWindow setFrame: newWindowRect display: YES]; line and it was
    YES when aNewView is displayed, while it was NO when it is not
    displayed.

    So I inserted a test code expecting this works:

    BOOL beforeSet = [aNewView needsDisplay];
    [aNewVew setNeedsDisplay: YES];
    BOOL afterSet = [aNewView needsDisplay];

    but afterSet was always NO.

    I am not familiar with view programming and I'm afraid I misunderstand
    something.

    - Chataka
previous month november 2007 next month
MTWTFSS
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30    
Go to today