Cocoa problem

Discussion in 'Mac Programming' started by MacRohde, Jun 18, 2007.

  1. MacRohde macrumors regular

    MacRohde

    Joined:
    Jun 1, 2004
    Location:
    Copenhagen, Denmark
    #1
    I'm trying to get into Cocoa, and for that I'm using the "Learning Cocoa with Objective-C"-book. So far so good.

    In chapter 8 I have a problem. Big problem.

    I have a custom view called DotView.

    When drawn the view sports a big dot with a specified radius and color. Whenever there's a mouse click the dot gets redrawn at the new position. There's also a slider and when activated the dot's radius is changed to the slider setting, and the view is redrawn. Well that's the idea anyway.

    The mouse clicks works fine: the mouseDown method is called and it sets the new postion and the call to setNeedsDisplay: results in a call to drawRect: Great! The dot is redrawn at the new position.

    The problem is the slider. In Interface Builder it is set up to to call a setRadius: method. And it does. And the radius instance field is set correctly. But, and this is the problem, this time the call to setNeedsDisplay: has no effect (i.e. drawRect: doesn't get called) and, even worse, next time drawRect: is called (via mouseDown) the old default radius is used and not the new one set in a previous setRadius:.

    It's like there's two different "versions" of the radius instance field: one used in the mouseDown/drawRect combo, and another one used in setRadius:. I can't help noticing that the stuff that works is when using the stuff inherited by NSResponder.

    Any ideas?
     
  2. HiRez macrumors 603

    HiRez

    Joined:
    Jan 6, 2004
    Location:
    Western US
    #2
    Hard to tell without seeing your code, could be a number of things. Could you post it (at least the setRadius: and drawRect: methods)? But, I have had problems in the past with setNeedsDisplay: being unresponsive. I don't think that's necessarily your problem since you say the radius is the wrong size when it gets repainted anyway, but you might try calling display: instead of setNeedsDisplay: for a test, that should force an immediate redraw.
     
  3. MacRohde thread starter macrumors regular

    MacRohde

    Joined:
    Jun 1, 2004
    Location:
    Copenhagen, Denmark
    #3
    Hi, thanks for the reply. I've tried using display: with no avail.

    This is the setRadius: code (the method is setup to be called by the slider, and does gets called)

    Code:
    -(IBAction) setRadius:(id)sender
    {
      radius = [sender floatValue];
      [self setNeedsDisplay:YES];
    }
    radius is an instance field in the DotView class which inherits from NSView.

    the drawRect method draws the dot and makes use of the radius instance field, but as I wrote in the original post the radius in drawRect is set to its old default value that has been set in initWithFrame: wheres whenevner I enters setRadius: radius has the correct value both before and after it's being set by [sender floatValue].
     
  4. garethlewis2 macrumors 6502

    Joined:
    Dec 6, 2006
    #4
    What did you set the properties of the slider to in Interface Builder?

    Normally for what you are doing, you would want the slider to be set to keep sending messages everytime it is pressed. Do you have it connected to the controller object?
     
  5. MacRohde thread starter macrumors regular

    MacRohde

    Joined:
    Jun 1, 2004
    Location:
    Copenhagen, Denmark
    #5

    I have an outloet in the DotView class connected to the slider, and I have the slider connected to the setRadius: action in the same class.

    Also I have the slider set to send messages continously.
     
  6. MongoTheGeek macrumors 68040

    MongoTheGeek

    Joined:
    Sep 13, 2003
    Location:
    Its not so much where you are as when you are.
    #6
    Is the radius actually being used as the radius to draw the dot?

    I know it sounds like a stupid thing to ask but it seems to be all thats left.
     
  7. cbougher macrumors member

    Joined:
    Oct 19, 2006
    Location:
    Atlanta, GA
    #7
    This may sound like a silly question but are you using a controller to communicate changes in the radius from the slider to the view? If so maybe you could post that code. If not that may be the issue.
     
  8. MacRohde thread starter macrumors regular

    MacRohde

    Joined:
    Jun 1, 2004
    Location:
    Copenhagen, Denmark
    #8
    No not really, I mean there really isn't a model here so everything happens in the view. The view class (DotView) has the outlets and actions.

    Is that a problem?
     
  9. MacRohde thread starter macrumors regular

    MacRohde

    Joined:
    Jun 1, 2004
    Location:
    Copenhagen, Denmark
    #9
    Yes it is. I've checked and double checked that. :)

    But I just found the book's examples on a web page so I'm gonna cross reference that with my code to see where the issue lies. Unfortunately my Mac's HD just broke so it will have to wait. Pretty annoying since I really woud like to know where I erred.
     
  10. cbougher macrumors member

    Joined:
    Oct 19, 2006
    Location:
    Atlanta, GA
    #10
    I don't know. Maybe. The way I learned a controller is always used. I'll try to replicate this project when I get home to my Mac and post my solution tonight. It may help.
     
  11. MacRohde thread starter macrumors regular

    MacRohde

    Joined:
    Jun 1, 2004
    Location:
    Copenhagen, Denmark
    #11
    Thanks for the effort, but fortunmately I found the error.

    What I did, which was wrong, was that I instantiated my view class and did all the connection to and from this and the Window's GUI.

    What I shoul've done was to not instantiate the view, and insted drag the connections to and from the CustomView control and the other controls in the Window itself.

    I always thought one should instantiate the classes one creates in Interface Builder.

    Oh well - now I know. And I solved the problem so I'm happy :):)
    Again thanks for all the help and suggestions; you're a helpful bunch.
     
  12. garethlewis2 macrumors 6502

    Joined:
    Dec 6, 2006
    #12
    Ah. You made the classic school boy error.

    Nearly every programmer I know who starts out with Cocoa scratches their head when they come across IB. It takes them an age to understand that when you drag an NSView, that is the object you will use, not picture of it, but the actual object. They start going cross-eyed when I try to explain how to add a pop-up box is loaded and at run-time needs to be bound to the parent window. If they are from a Visual C++ background, they just go in a corner and cry.
     
  13. MacRohde thread starter macrumors regular

    MacRohde

    Joined:
    Jun 1, 2004
    Location:
    Copenhagen, Denmark
    #13
    He he, that sums it up nicely.

    I was under the impression that I needed to instantiate the view, but I didn't - I assume then that I only would instantiate classes which doesn't have a visual appearance on the GUI, like a controller.

    And yes this is very different from .NET which is what I do at my day job; but it's always educational to learn a different way of doing things.
     
  14. MongoTheGeek macrumors 68040

    MongoTheGeek

    Joined:
    Sep 13, 2003
    Location:
    Its not so much where you are as when you are.
    #14
    Yes.

    It really is the power of Cocoa/Yellow Box/NextStep. The nib is a runnable application and contains the objects
     

Share This Page