NSView + NSScrollView, not scrolling

  • I have got a very basic question about NSScrollView. I embedded my
    custom NSView into an NSScrollView using Xcode's "Embed In..." menu
    item. The following is my custom NSView:

    @implementation MyView

    - (void)drawRect:(NSRect)dirtyRect {
        [[NSColor yellowColor] set];
        NSRectFill([self frame]);
    }

    - (void)keyDown:(NSEvent *)theEvent {
        unichar key = [[theEvent characters] characterAtIndex:0];
        NSLog(@"\\U%X pressed", (int)key);

        [self interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
    }

    - (BOOL)acceptsFirstResponder {
        return YES;
    }
    @end

    In "applicationDidFinishLaunching:" I set the frame size of the view
    to something big using setFrameSize.

    What I want — but now working — is scrolling via Page Up/Down key. If
    I understand the doc correctly, I just have to call
    "interpretKeyEvents:" like above  and since MyView does not respond to
    appropriate messages, the responder chain will forward the messages to
    the scroll view. However, it does not scroll. What am I missing?

    Thanks in advance.

    Tae
  • A question that could give a better idea of the issue:

    Is the scroller thumb visible?

    On Sat, May 5, 2012 at 12:31 AM, qvacua <qvacua...> wrote:
    > I have got a very basic question about NSScrollView. I embedded my
    > custom NSView into an NSScrollView using Xcode's "Embed In..." menu
    > item. The following is my custom NSView:
    >
    > @implementation MyView
    >
    > - (void)drawRect:(NSRect)dirtyRect {
    >    [[NSColor yellowColor] set];
    >    NSRectFill([self frame]);
    > }
    >
    > - (void)keyDown:(NSEvent *)theEvent {
    >    unichar key = [[theEvent characters] characterAtIndex:0];
    >    NSLog(@"\\U%X pressed", (int)key);
    >
    >    [self interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
    > }
    >
    > - (BOOL)acceptsFirstResponder {
    >    return YES;
    > }
    > @end
    >
    > In "applicationDidFinishLaunching:" I set the frame size of the view
    > to something big using setFrameSize.
    >
    > What I want — but now working — is scrolling via Page Up/Down key. If
    > I understand the doc correctly, I just have to call
    > "interpretKeyEvents:" like above  and since MyView does not respond to
    > appropriate messages, the responder chain will forward the messages to
    > the scroll view. However, it does not scroll. What am I missing?
    >
    > Thanks in advance.
  • Yes, since I am using a mouse, the scroll bars are visible and using
    the scroll wheel I can scroll.

    Tae

    On Sat, May 5, 2012 at 12:24 PM, Stephane Sudre <dev.iceberg...> wrote:
    > A question that could give a better idea of the issue:
    >
    > Is the scroller thumb visible?
    >
    > On Sat, May 5, 2012 at 12:31 AM, qvacua <qvacua...> wrote:
    >> I have got a very basic question about NSScrollView. I embedded my
    >> custom NSView into an NSScrollView using Xcode's "Embed In..." menu
    >> item. The following is my custom NSView:
    >>
    >> @implementation MyView
    >>
    >> - (void)drawRect:(NSRect)dirtyRect {
    >>    [[NSColor yellowColor] set];
    >>    NSRectFill([self frame]);
    >> }
    >>
    >> - (void)keyDown:(NSEvent *)theEvent {
    >>    unichar key = [[theEvent characters] characterAtIndex:0];
    >>    NSLog(@"\\U%X pressed", (int)key);
    >>
    >>    [self interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
    >> }
    >>
    >> - (BOOL)acceptsFirstResponder {
    >>    return YES;
    >> }
    >> @end
    >>
    >> In "applicationDidFinishLaunching:" I set the frame size of the view
    >> to something big using setFrameSize.
    >>
    >> What I want — but now working — is scrolling via Page Up/Down key. If
    >> I understand the doc correctly, I just have to call
    >> "interpretKeyEvents:" like above  and since MyView does not respond to
    >> appropriate messages, the responder chain will forward the messages to
    >> the scroll view. However, it does not scroll. What am I missing?
    >>
    >> Thanks in advance.

  • On May 5, 2012, at 3:31 AM, qvacua wrote:
    > - (void)drawRect:(NSRect)dirtyRect {
    > [[NSColor yellowColor] set];
    > NSRectFill([self frame]);
    > }

    Using [self frame] is a bug. [self frame] returns a rectangle in the *superview's* coordinate system, whereas NSRectFill expects a rectangle in *self's* coordinate system. Does it help if you correct this to NSRectFill([self bounds])?

    --Andy
  • No, it does not help. I think since I am not scaling the view or sth.
    like that, the difference between frame and bounds should be
    irrelevant for this problem.

    Tae

    On Sat, May 5, 2012 at 6:12 PM, Andy Lee <aglee...> wrote:
    > On May 5, 2012, at 3:31 AM, qvacua wrote:
    >> - (void)drawRect:(NSRect)dirtyRect {
    >>    [[NSColor yellowColor] set];
    >>    NSRectFill([self frame]);
    >> }
    >
    > Using [self frame] is a bug. [self frame] returns a rectangle in the *superview's* coordinate system, whereas NSRectFill expects a rectangle in *self's* coordinate system. Does it help if you correct this to NSRectFill([self bounds])?
    >
    > --Andy
    >
  • On May 5, 2012, at 3:31 AM, qvacua wrote:
    > - (void)keyDown:(NSEvent *)theEvent {
    > unichar key = [[theEvent characters] characterAtIndex:0];
    > NSLog(@"\\U%X pressed", (int)key);
    >
    > [self interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
    > }
    >
    > - (BOOL)acceptsFirstResponder {
    > return YES;
    > }
    > @end
    >
    > In "applicationDidFinishLaunching:" I set the frame size of the view
    > to something big using setFrameSize.
    >
    > What I want — but now working — is scrolling via Page Up/Down key. If
    > I understand the doc correctly, I just have to call
    > "interpretKeyEvents:" like above

    Remove your override of keyDown: and the scrolling should just work. At least it does in a test I just did. I'm a little puzzled since I assume your code comes from this example in the docs:

    <https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Eve
    ntOverview/HandlingKeyEvents/HandlingKeyEvents.html#//apple_ref/doc/uid/100
    00060i-CH7-SW13
    >

    In my test I was surprised to find that the view's doCommandBySelector: doesn't get called. Either something's changed or there's something I misunderstood. I don't see how the key events get mapped to the page-scrolling methods without a call to doCommandBySelector:, which I thought did that mapping.

    Here are all the methods I implemented in my view class. Feel free to use the drawing code so that you can see the scrolling more vividly.

    - (void)drawRect:(NSRect)dirtyRect
    {
        NSRect boxRect = NSMakeRect(0, 0, 200, 30);

        for (NSInteger boxIndex = 0; boxIndex < 100; boxIndex++, boxRect.origin.y += 30)
        {
            // Draw colored background.
            if (boxIndex & 1)
            {
                [[NSColor yellowColor] set];
            }
            else
            {
                [[NSColor orangeColor] set];
            }
            NSRectFill(boxRect);

            // Draw box number.
            NSString *s = [NSString stringWithFormat:@"%ld", boxIndex + 1];
            [s drawInRect:boxRect withAttributes:nil];
        }
    }

    - (BOOL)isFlipped
    {
        return YES;
    }

    - (BOOL)acceptsFirstResponder
    {
        return YES;
    }

    - (void)doCommandBySelector:(SEL)aSelector
    {
        NSLog(@"<%@: %p> -- %s -- will try to do command %@", [self className], self, __PRETTY_FUNCTION__, NSStringFromSelector(aSelector));
        [super doCommandBySelector:aSelector];
    }

    --Andy
previous month may 2012 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 31      
Go to today