PDA

View Full Version : Help Porting Some iOS Code




Blakeasd
Jul 3, 2011, 03:01 PM
Hello,
I have been following along with this tutorial (http://www.cocoanetics.com/2010/05/physics-101-uikit-app-with-box2d-for-gravity/)
and I need some help porting some code to OS X.
1. Is viewDidLoad: the equivalent to awakeFromNib: ?
2. How did the author create those shapes and how can I do this in OS X?

I am only having a problem with the viewDidLoad: stuff.
Thanks!



kainjow
Jul 3, 2011, 03:44 PM
viewDidLoad: is part of UIViewController while awakeFromNib can be called on any object created from a nib. However viewDidLoad: can also be called if the view was created programatically. So awakeFromNib can probably be used in most cases on OS X.

jiminaus
Jul 3, 2011, 05:21 PM
How did the author create those shapes and how can I do this in OS X?


They're UIViews with the background color set to different values.

The Mac OS X equivalent (NSView) doesn't have a background color.

NSTextField does have a background colour. So you could drag Wrapping Labels onto your window instead and just delete the text in the title.

Blakeasd
Jul 4, 2011, 09:33 AM
So for the viewdidLoad: iOS method I create a NSViewController and call
-(void)awakeFromNib: and in that awakeFromNib: method I can use the same iOS code that is in the viewDidLoad? Do I create a different NSView subclass for each of the colored squares and in their awakeFromNib: method I call addPhysicalBodyForView: ?

chown33
Jul 4, 2011, 04:12 PM
NSTextField does have a background colour. So you could drag Wrapping Labels onto your window instead and just delete the text in the title.

Or maybe NSBox or NSColorWell.

See AppKit Framework Reference (http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/ObjC_classic/_index.html).

Blakeasd
Jul 4, 2011, 07:10 PM
I know about the background color, but how exactly do I handle the views I create? I have no idea how to convert this code:
- (void)viewDidLoad
{
[super viewDidLoad];

[self createPhysicsWorld];

for (UIView *oneView in self.view.subviews)
{
[self addPhysicalBodyForView:oneView];
}

tickTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/60.0 target:self selector:@selector(tick:) userInfo:nil repeats:YES];
}

jiminaus
Jul 4, 2011, 08:33 PM
So for the viewdidLoad: iOS method I create a NSViewController and call
-(void)awakeFromNib: and in that awakeFromNib: method I can use the same iOS code that is in the viewDidLoad? Do I create a different NSView subclass for each of the colored squares and in their awakeFromNib: method I call addPhysicalBodyForView: ?

Just create them in Interface Builder. Porting iOS viewdidLoad: to awakeFromNib: is probably good enough for this tutorial. No need to create view controllers. This is a simple tutorial. Just do it in the app delegate.


I know about the background color, but how exactly do I handle the views I create? I have no idea how to convert this code:
- (void)viewDidLoad
{
[super viewDidLoad];

[self createPhysicsWorld];

for (UIView *oneView in self.view.subviews)
{
[self addPhysicalBodyForView:oneView];
}

tickTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/60.0 target:self selector:@selector(tick:) userInfo:nil repeats:YES];
}

Start by changing UIView to NSView.

Blakeasd
Jul 4, 2011, 09:29 PM
Thanks, I think I got it working. Here is my new code:

-(void)awakeFromNib{


[self createPhysicsWorld];
NSView *contentView;
contentView = [window contentView];
for (NSView * oneView in [contentView subviews]){


[self addPhysicalBodyForView:oneView];

}





}


I have one more question, I get an error with this line of code:

physicalView.tag = (int)body;

The author said that this line would "abuse so the tag property", so what does this line of code do and what can I use in place of it? This line compiles in iOS, but not in Mac OS X. I get the error, " Cast from pointer to small type 'int' loses information "
Thanks!

jiminaus
Jul 4, 2011, 09:57 PM
physicalView.tag = (int)body;



Firstly the author was ignorant in type-casting a pointer to an int. Type-cast it to an NSInteger.

Secondly, while NSView has tag, it doesn't have setTag:. NSControl though does have setTag:. All of NSTextField, NSBox and NSColorWell inherit from NSControl, so you should be okay. But you'll need to change addPhysicalBodyForView: to accept an NSControl* instead of an NSView*. You'll then need to guard the call to addPhysicalBodyForView: in awakeFromNib: so it only happens with subviews that are kinds of NSControl.

Blakeasd
Jul 4, 2011, 10:44 PM
Okay, Thanks!
I did everything but this:

You'll then need to guard the call to addPhysicalBodyForView: in awakeFromNib: so it only happens with subviews that are kinds of NSControl.

I am not exactly sure what guarding a call is.

jiminaus
Jul 4, 2011, 10:54 PM
Okay, Thanks!
I did everything but this:

I am not exactly sure what guarding a call is.

Ah sorry. Guarding might be an Ada-ism. Surround the call with an if statement that tests that the view is kind of NSControl.

Blakeasd
Jul 4, 2011, 11:00 PM
I'm still not quite sure what you mean.
Thanks

jiminaus
Jul 4, 2011, 11:11 PM
I'm still not quite sure what you mean.
Thanks


for (NSView * oneView in [contentView subviews]){

if ([oneView isKindOf:@class(NSControl)]) {

[self addPhysicalBodyForView:(NSControl*)oneView];

}

}

Blakeasd
Jul 4, 2011, 11:50 PM
The code you provided didn't compile and gave the following error:
"Unexpected @ in program"
I changed the code to this:

if ([oneView isKindOfClass:[NSControl class]]) {

[self addPhysicalBodyForView:(NSControl*)oneView];

}


Is the code I created correct?

jiminaus
Jul 5, 2011, 12:22 AM
The code you provided didn't compile and gave the following error:
"Unexpected @ in program"
I changed the code to this:

if ([oneView isKindOfClass:[NSControl class]]) {

[self addPhysicalBodyForView:(NSControl*)oneView];

}


Is the code I created correct?

Sorry for getting the @class construct wrong. I am actually away from my beloved Mac. The code you posted looks correct.

Blakeasd
Jul 5, 2011, 10:44 AM
Thanks for all your help! I can't wait to do some cool physics stuff.
:D

Blakeasd
Jul 5, 2011, 12:14 PM
I actually do have another question,
I will be applying a CGAffineTransform to a view (same tutorial) and the author is using an iOS only property

CGAffineTransform transform = CGAffineTransformMakeRotation(- b->GetAngle());
oneView.transform = transform. What is an equivalent way to do this in OS X?

chown33
Jul 5, 2011, 12:24 PM
I actually do have another question,
I will be applying a CGAffineTransform to a view (same tutorial) and the author is using an iOS only property

CGAffineTransform transform = CGAffineTransformMakeRotation(- b->GetAngle());
oneView.transform = transform. What is an equivalent way to do this in OS X?

Look it up in the documentation: NSView Programming Guide (http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaViewsGuide/Coordinates/Coordinates.html%23//apple_ref/doc/uid/TP40002978-CH10-SW1).

Blakeasd
Jul 5, 2011, 12:47 PM
I actually didn't find a method or property that is the equivalent to the iOS property.

robbieduncan
Jul 5, 2011, 12:51 PM
I actually didn't find a method or property that is the equivalent to the iOS property.

To the best of my knowledge there isn't one. The guide you were directed to has a lot of detail on how to achieve a similar thing in OSX (hint it's not as simple as setting a property).

Blakeasd
Jul 5, 2011, 01:41 PM
I can't find anything there about CGAffineTransforms on NSViews. :confused:

robbieduncan
Jul 5, 2011, 01:43 PM
I can't find anything there about CGAffineTransforms on NSViews. :confused:

That's because there isn't such a thing. As it says you are better performing the rotation yourself on the co-ordinate system in drawRect:. If it's not a custom view you can use the obvious methods to set either bounds or frame rotations.

Blakeasd
Jul 5, 2011, 02:05 PM
So I won't be able to use my CGAffineTransformation?

Blakeasd
Jul 5, 2011, 06:01 PM
Here is my new code:


CGAffineTransform transform = CGAffineTransformMakeRotation(- b->GetAngle());

oneView.wantsLayer = YES;
[oneView.layer setAffineTransform:transform];




Can anyone confirm the code I wrote works?
I tried to compile my project and I get no errors, but all the shapes don't fall to the bottom of the window like they should. Could someone PLEASE take a look at my project and find out why it isn't working?
Here is the link to my project: Project Link (http://cl.ly/2T0z2t3y3v0K3N0s3N0W)