Help needed drawing to NSView

Discussion in 'Mac Programming' started by jbcandkc, Apr 30, 2010.

  1. jbcandkc macrumors member

    Joined:
    Nov 1, 2006
    #1
    I am working on a small learning project and I've been stuck for the last 2 days. I am trying to draw in an NSView using coordinates from text fields in my GUI but get an error "error: 'textField1' undeclared (first use in this function)". I did an "#import" for my interface controller .h file but that hasn't helped.

    I have attached the project. The project is Chapter 8 - Exercise 6 from Programming in Objective-C 2.0 (Kochan). I did the exercise, then decided to add a GUI (that worked) then decided to draw the rectangles to make sure my code was correct. I can draw in the NSView with no problem, I just can't get it to pull values from the textFields.

    Thanks for any help.
    (XCode 3.1.2 on Leopard)
     

    Attached Files:

  2. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    I haven't looked at the project but from your description you're doing it wrong. Your view should not be pulling values from other views. It should have properties (instance variables) that a controller sets. That controller can pull the values from the GUI.
     
  3. kaydell.leavitt macrumors regular

    Joined:
    Apr 19, 2010
    #3
    I believe that the problem is that there are two different classes. The text fields are defined in one class and you're trying to use them in the other class. The following code gets a textField from the other class.

    Code:
    	int i1 = getInt([appInterface textField1]);
    
    Code:
    int getInt(NSTextField *textField) {
    	NSString *string = [textField stringValue];
    	int i = [string integerValue];
    	return i;
    }
    
    Code:
    #import <Cocoa/Cocoa.h>
    
    @class AppInterface;
    
    @interface MyCanvas : NSView
    {
    	AppInterface *appInterface;
    }
    @property (nonatomic, retain) AppInterface *appInterface;
    @end
    
    The above code is better because it compiles now and it's looking for the textFields in the right place, but what is left to be done is to get the variable appInterface set so that it isn't nil.

    -- Kaydell :)
     
  4. jbcandkc thread starter macrumors member

    Joined:
    Nov 1, 2006
    #4
    Sorry about the long post, BUT I am back on this project, although I could probably change the title to "How do I access my models ivars from my NSView drawRect method"

    To simplify my project, I am now just trying to draw a rectangle from 4 numbers in textfields (xorigin, yorigin, width and height). I have started from scratch using robbieduncan's advise. Here is what I have done so far.

    I created a MODEL class called Model which inherits from NSObject. It has 4 integer instance variables (x, y, h, w) and each has a setter and getter method.

    My VIEW in Interface Builder has 4 text fields (x,y,width,height), a button to trigger the drawing of the rectangle and a custom view.

    My CONTROLLER is a class called Controller which inherits from NSObject. The controller .h is...
    Code:
    //Controller.h
    #import <Cocoa/Cocoa.h>
    #import "Model.h"
    @interface Controller : NSObject
    {
    	IBOutlet NSTextField* fieldX;
    	IBOutlet NSTextField* fieldY;
    	IBOutlet NSTextField* fieldW;
    	IBOutlet NSTextField* fieldH;
    	IBOutlet NSView *mainView;
    	Model *theModel;
    }
    - (IBAction) draw: (id) sender;
    @end
    And the controller .m is...
    Code:
    //Controller.m
    #import "Controller.h"
    @implementation Controller
    - (void) awakeFromNib
    {
    	NSLog (@"    awakeFromNib has started");
    	theModel = [[Model alloc] init];
    }
    - (IBAction) draw: (id) sender;
    {
    	NSLog (@"    draw has started");
    	NSLog (@"x=%i - y=%i - w=%i - h=%i", fieldX.integerValue, fieldY.integerValue, fieldW.integerValue, fieldH.integerValue);
    	[theModel setX: [fieldX integerValue]];
    	[theModel setY: [fieldY integerValue]];
    	[theModel setW: [fieldW integerValue]];
    	[theModel setH: [fieldH integerValue]];
    	NSLog (@"tMx=%i - tMy=%i - tMw=%i - tMh=%i", [theModel x], [theModel y], [theModel w], [theModel h]);
    	[mainView setNeedsDisplay:YES];	// Invalidate the mainView area, so it will get redrawn
    	NSLog (@"    draw has ended");
    }
    @end
    Finally, I have a class called subView which inherits from NSView. It contains the 2 methods that Xcode puts in there. The drawRect: method is...
    Code:
    - (void)drawRect:(NSRect)rect
    {
        // Drawing code here.
    	NSLog (@"    start drawRect");
    	// Draw the bounds of the View
    	NSRect bounds = [self bounds];
    	[[NSColor redColor] set];
    	[NSBezierPath strokeRect: bounds];
    	NSLog (@"    end drawRect");
    }
    and according to my NSLogs, all methods are getting called and the CONTROLLER is talking to the MODEL, the drawRect is drawing the bounds...Everything works! My next step is to draw the rectangle using the ivars in my model, but when I try to put...
    Code:
    NSRect myRect = NSMakeRect ([theModel x], [theModel y], [theModel w], [theModel h]);
    [[NSColor redColor] set];
    [NSBezierPath strokeRect: myRect];
    Xcode says "error: 'theModel' undeclared (first use in this function).
    What do I need to do to have my drawRect method by able to access the instance variables from theModel???
     
  5. misee macrumors member

    Joined:
    Jul 4, 2010
    #5
    I haven't seen your views header file, so this is just an educated guess: your view doesn't have an ivar called theModel, hence the error message.

    For this simple project, you don't really need a model, so try to focus just on the controller and the view. You should also give your view class ivars for the origin, widht and height and then set those via the controller.
     
  6. cromwell64 macrumors regular

    Joined:
    Jun 30, 2008
    #6
    Code:
    Model *theModel = [[Model alloc] init];
    shouldn't the line look like that instead so that you actually have a pointer to a model?

    but it seems like maybe you are making this more complicated than it needs to be.
     
  7. misee macrumors member

    Joined:
    Jul 4, 2010
    #7
    No, he has an ivar called theModel (see Controller.h).
     
  8. jbcandkc thread starter macrumors member

    Joined:
    Nov 1, 2006
    #8
    I tried several different ways... the controller and the view, just the view and have it do the controlling...nothing worked.

    I'm posting the whole project so maybe you could tinker with it and make it work.
    Thanks
     

    Attached Files:

  9. misee macrumors member

    Joined:
    Jul 4, 2010
    #9
    I changed the code so that it works the way I meant.
    Maybe you should by a book about cocoa.
     

    Attached Files:

  10. jbcandkc thread starter macrumors member

    Joined:
    Nov 1, 2006
    #10
    Misee, thanks for the help.
    I have bought a couple of books. If you see my first post, this was originally Chapter 8 Exercise 6 from the Kochan Objective C book. I made a GUI and all was fine. I guess I got a little too far out over my skis with the NSView stuff and multiple classes.
    Jim
     
  11. misee macrumors member

    Joined:
    Jul 4, 2010
    #11
    I haven't read the book - I have the Kochan Objective-C book at home (not the Objective-C 2.0) - but as far as I saw, only a very small part discusses Cocoa, and there it's mainly the iPhone. But what I meant is that if you plan on using Cocoa, you should buy a book that focuses on Cocoa.
     

Share This Page