Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

jpefjr

macrumors regular
Original poster
Jul 8, 2008
230
42
After 20+ years of programming unix server software (TCP/IP, pthreads, IPC, etc.) I decided to go back to my roots and play around with graphics on my Apple. Of course my roots involved first BASIC then 6502 assembly in my Apple ][e. Now I'm trying to get my feet wet writing code using Cocoa on my Mac.

I've read through much of "Programming in Objective-C 2.0" and have a grasp of the syntax and structure of Objective-C. Last night, following an example I found online of drawing text in a window, I used Interface Builder to create a window and a custom view inherited off of NSView. I implemented the drawRect: method and created a bunch of NSRect structures (origin.x was iterated over the width of the view and origin.y was a random number up to the height of the view) and used NSRectFill to draw the rectangles. I ended up putting the NSRect structure (encoded in NSValue) into an NSMutableArray.

So here's my question - can anyone give me some pointers to online docs on how to best go about redrawing the rectangles as I swap them in a sort? I'm want to graph out several sorting algorithms starting with the simple bubble sort.

As near as I can tell NSApplicationMain calls into my view's drawRect: method and as soon as drawRect returns the view is rendered on screen. I guess what I'm looking for is a way to get NSApplicationMain to call into my code periodically - maybe through use of an NSTimer? - which will perform sorting of the NSRect structures in the NSMutableArray. I'm also guessing that every time I swap a pair of rectangles I need to call my view's setNeedsDisplay: method and then return so that NSApplicationMain can handle calling my drawRect and then rerendering the screen?

Any help you can give is very much appreciated. As you can tell I'm new to this whole model view controller GUI thing.
 
For not too complex animation the method you outlined will be fine: use a timer to iterate over the steps you want to animate calling setNeedsDisplay: each time.
 
Thanks Robbie. I realize there are better ways of doing animations but like you said this is a pretty simple animation and I'm trying to get an understanding of the basics before proceeding on to more complex classes and methodologies.

One more quick question, would it work to add the following to my custom view's @interface:

NSTimer *myTimer;

And then add the following to my view's initWithFrame: method:

myTimer = [NSTimer scheduledTimerWithTimeInterval:.05 target:self selector:mad:selector(swapRects) userInfo:nil repeats:YES];

Or is there a better place to declare and define the NSTimer object?
 
That might work. But I'd not recommend it. For starters that will not get called if your view loads from a nib (but awakeFromNib: will).
 
So are you recommending I implement an awakeFromNib: method in my view and set the timer there? Or is there another place that you recommend declaring and defining the timer?

Sorry to be so obtuse, I really appreciate your responses.
 
Personally I'd be looking to start the timer when the view became visible. But, for some reason, I'm struggling to find a method/notification for that.

Perhaps start it on the first drawRect:. My reason for starting it only when the view is visible would be that you could, potentially, loose some animation steps whilst everything sets up. Although as the timer only fires every based on the runloop this may not be worth worrying about...
 
Personally I'd be looking to start the timer when the view became visible. But, for some reason, I'm struggling to find a method/notification for that.

Perhaps start it on the first drawRect:. My reason for starting it only when the view is visible would be that you could, potentially, loose some animation steps whilst everything sets up. Although as the timer only fires every based on the runloop this may not be worth worrying about...

Thanks - I got it working. I'm starting the timer in the awakeFromNib method which as you point out isn't really the best place for it. But seeing as my drawRect redraws the entire window every time it's called (I'll have to look into creating a buffer for the view because when I initially implemented only redrawing the points that had been swapped by my sort algorithm all the other points in the window went away every time drawRect was called). The animation looks good enough though. Now on to adding a toolbar at the top of the window to select the sort algorithm and maybe a slider to control the speed. That along with figuring out how to buffer the view so I don't have to redraw all the rectangles every time should keep me busy for another couple days.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.