PDA

View Full Version : CG on iPhone question




Buschmaster
Mar 19, 2008, 02:01 PM
I'm trying to follow along with the guides and I thought I would be creating a rectangle with the following code in my DrawBox.m:
- (void)drawRect:(CGRect)rect {
// Drawing code here.
CGContextRef myContext = UICurrentContext();

CGRect ourRect = CGRectMake(40, 40, 240, 120);

CGContextSetRGBFillColor(context, 0.0,0.0,1.0,1.0);
CGContextFillRect(context, ourRect);

CGContextSetRGBStrokeColor(context, 0.0, 1.0, 0.0, 1.0);
CGContextStrokeRectWithWidth(context, ourRect, 10);
}


However, I get an error pertaining to the use of 'context.' It says it is undeclared but I'm not sure where to declare it or how. Should I declare it in DrawBox.h? The guides are confusing me even more so, so hopefully one of you could help me and I can continue on my way of learning?

Thanks!

P.S. I am fairly new to Objective-C and I know a lot of Java and Python, so if anyone could show me a little bit of what I'm doing in Java with declaring context that would be great, too.



TEG
Mar 19, 2008, 02:06 PM
Are you including the files that Context is set in?

# include <asdf.h> (replace asdf.h with the appropriate header file)

Buschmaster
Mar 19, 2008, 02:15 PM
Context isn't set. I'm including the header file, but I'm not sure what to do with 'context'.

TEG
Mar 19, 2008, 02:21 PM
Context must contain a value from somewhere. Either passed in from a call of this method or set in the method.

TEG

Sayer
Mar 19, 2008, 02:23 PM
You need to use the myContext variable, which you set using UICurrentContext(), instead of "context".

Buschmaster
Mar 19, 2008, 02:39 PM
Changing myContext up in:
CGContextRef context = UICurrentContext();

Making the whole thing:
- (void)drawRect:(CGRect)rect {
// Drawing code here.
CGContextRef context = UICurrentContext();

CGRect ourRect = CGRectMake(40, 40, 240, 120);

CGContextSetRGBFillColor(context, 0.0,0.0,1.0,1.0);
CGContextFillRect(context, ourRect);

CGContextSetRGBStrokeColor(context, 0.0, 1.0, 0.0, 1.0);
CGContextStrokeRectWithWidth(context, ourRect, 10);

Gives me two warnings and a build error:

Warning: Implicit declaration of function UICurrentContext
Warning: Initialization makes pointer from integer without a cast
and
"_UICurrentContext", referenced from:
-[DrawBox drawRect:] in DrawBox.o
symbol(s) not found
collect2: id returned, 1 exit status

lucasgladding
Mar 19, 2008, 08:47 PM
Is the class a subclass of UIView? Everything else looks right to me. I don't think you need to import anything for core graphics like you would for Mac OS X development - everything should come with UIView. Details about the header file might be helpful here.

Everything else looks like it should based on the UIView documentation.

Best of luck

admanimal
Mar 19, 2008, 10:07 PM
It sounds like UIView.h is not being imported anywhere.

diehard89
Mar 20, 2008, 12:56 AM
Try this it works for me

CGContextRef context = UICurrentContext();

change to

CGContextRef context = UIGraphicsGetCurrentContext();

Alfons
Mar 20, 2008, 07:33 AM
I got it working, but i get this warning and I can't fix it. "warning:local declaration of 'myContext' hides instance variable."

and here is my code


CGContextRef myContext = UIGraphicsGetCurrentContext();

// Draw the intermediate lines
CGContextSetGrayStrokeColor(myContext, 1, 1.0);
CGContextBeginPath(myContext);
for (UIView *viewAtIndex in self.subviews){
UIView *tempView = [self.subviews objectAtIndex:0];


CGContextMoveToPoint(myContext,tempView.center.x ,tempView.center.y);
tempView = [self.subviews objectAtIndex:1];


CGContextAddLineToPoint(myContext, tempView.center.x,tempView.center.y);

CGContextStrokePath(myContext);

Anyone?

BigJimSlade
Mar 20, 2008, 07:51 AM
Have you defined myContext as an instance variable in your class interface by any chance?

lucasgladding
Mar 20, 2008, 07:52 AM
Do you have myContext declared in your header file interface? If so, it should be removed.

Best of luck

I got it working, but i get this warning and I can't fix it. "warning:local declaration of 'myContext' hides instance variable."

and here is my code


CGContextRef myContext = UIGraphicsGetCurrentContext();

// Draw the intermediate lines
CGContextSetGrayStrokeColor(myContext, 1, 1.0);
CGContextBeginPath(myContext);
for (UIView *viewAtIndex in self.subviews){
UIView *tempView = [self.subviews objectAtIndex:0];


CGContextMoveToPoint(myContext,tempView.center.x ,tempView.center.y);
tempView = [self.subviews objectAtIndex:1];


CGContextAddLineToPoint(myContext, tempView.center.x,tempView.center.y);

CGContextStrokePath(myContext);

Anyone?

admanimal
Mar 20, 2008, 10:08 AM
Not to be a jerk, but if people are having trouble understanding what an undeclared variable is, or how and where variables should be declared, it might be a good idea to step away from the SDK for a bit and just do some simple Objective-C programming that removes the complexities of the SDK and allows you to get the hang of general issues first.

Alfons
Mar 20, 2008, 12:44 PM
I think the SDK is a great way to have some fun and experiment for us that never programmed in Xcode before. But I do agree with you that it's a good way to learn from the ground up, and that's why I picked up Cocoa programming for OS X today.

Buschmaster
Mar 25, 2008, 09:43 PM
I've done my share of desktop programming. I'm just kinda new to Objective-C. Not really "new" just don't use it a lot so I fall into Java habits and get confused.

However, with the iPhone SDK I will be using it more now.

Here's what I have now and it builds successfully but doesn't draw the actual box like I'd like it to. I'm hoping after I figure out how to draw the box I'll make it watch for a tap and when the box is tapped it'll change colors or something. Just learning the ropes! Anyway, here it is...

This is in MyView.m:
- (void)drawBox:(CGRect)rect {
// Drawing code here.
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect box = CGRectMake(40, 40, 240, 120);
CGContextSetRGBFillColor(context, 0.0,0.0,1.0,1.0);
CGContextFillRect(context, box);

CGContextSetRGBStrokeColor(context, 0.0, 1.0, 0.0, 1.0);
CGContextStrokeRectWithWidth(context, box, 10);


}

And MyView.h:
@interface MyView : UIView {

}

-(void)DisplayLabel;
-(void)drawBox:(CGRect)rect;

And my delegate.m:
// Show the label
[contentView DisplayLabel];

// Show the box
CGRect rect = CGRectMake(00, 00, 320, 480);
[contentView drawBox:rect];


delegate.h remains the same.

Any ideas as to why the box isn't showing up?

Buschmaster
Mar 25, 2008, 10:24 PM
If I'm understanding the question correctly the snippet above in drawRect is from MyView.m

Here is the whole file:
//
// MyView.m
// ClickBox
//
// Created by ########## on 3/25/08.
// Copyright __MyCompanyName__ 2008. All rights reserved.
//

#import "MyView.h"

@implementation MyView

- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
// Initialization code here.
}
return self;
}

-(void) DisplayLabel {
CGRect frame = CGRectMake(00,20,320,40);

UILabel *label = [[ UILabel alloc ] initWithFrame: frame ];
label.textAlignment = UITextAlignmentCenter;
label.text = @"Click it!";
label.font = [ UIFont boldSystemFontOfSize: 25.00 ];
label.textColor = [ UIColor colorWithRed: 100.0/255.0 green: 255.0/255.0 blue: 100.0/255.0 alpha: 1.0 ];
label.backgroundColor = [ UIColor clearColor ];

[self addSubview: label];
[ label release ];
}

- (void)drawBox:(CGRect)rect {
// Drawing code here.
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect box = [self bounds];
CGContextSetRGBFillColor(context, 0.0,0.0,1.0,1.0);
CGContextFillRect(context, box);

CGContextSetRGBStrokeColor(context, 0.0, 1.0, 0.0, 1.0);
CGContextStrokeRectWithWidth(context, box, 10);

}

@end

Buschmaster
Mar 25, 2008, 10:42 PM
Ok, so I changed my myView.m part to this:
- (void)drawBox {
// Drawing code here.
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect box = CGRectMake(40, 40, 240, 120);
CGContextSetRGBFillColor(context, 0.0,0.0,1.0,1.0);
CGContextFillRect(context, box);

CGContextSetRGBStrokeColor(context, 0.0, 1.0, 0.0, 1.0);
CGContextStrokeRectWithWidth(context, box, 10);

}

and changed the other appropriate parts to now match it and still.... nothing.

I'm a bit confused as to why it isn't working. I'll keep trying stuff and see what happens.

Buschmaster
Mar 25, 2008, 11:12 PM
Thanks for the helpful tip!

With this now placed in my app deletgate.m it works, but is there a more efficient way?
CGRect rect = CGRectMake(40, 40, 240, 120);

// Show the box
[contentView drawRect:rect];


Off to read the suggested homework! :)

Buschmaster
Mar 25, 2008, 11:17 PM
Oh. Well... no code is more efficient than wasteful useless code for sure!

Well, thanks a ton for the help!

kainjow
Mar 25, 2008, 11:30 PM
Great, glad you got it working :)

Buschmaster
Mar 25, 2008, 11:45 PM
Yeah! That part is working great, now it's onto more!

I'm going to make it so when you touch it displays a blip right where you touched. Just so I understand cocoa touch a bit better.

I'm sure I'll have more questions. ;)

For one, my controller doesn't seem to be included. I went to file and added a new UIViewController subclass which I called ClickControl. And so I added this to the ClickBoxAppDelegate.m:
#import "ClickBoxAppDelegate.h"
#import "MyView.h"
#import "ClickControl.h"

What did I do wrong there? :confused: The only reason it would seem it isn't including it is because I have this:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}

among other things in ClickControl.m and that one in particular should be exactly right. Even if I messed the click controls up I should be able to go into the simulator and rotate the device, correct? It does nothing when I tell it to rotate left or right as if I haven't accounted for it.

kainjow
Mar 26, 2008, 06:54 AM
See this thread (http://forums.macrumors.com/showthread.php?t=457980) for getting the rotation to work.

You say your controller isn't included. How are you creating it? You need to initialized an instance of the ClickControl class somewhere in your code.

Buschmaster
Mar 26, 2008, 02:32 PM
See this thread (http://forums.macrumors.com/showthread.php?t=457980) for getting the rotation to work.

You say your controller isn't included. How are you creating it? You need to initialized an instance of the ClickControl class somewhere in your code.
I did that, and I think I utilized the rotation correctly. The Aspen Simulator doesn't rotate when I tell it to, yet, though. Here is all of my code in my ClickControl.m
//
// ClickControl.m
// ClickBox
//
// Created by ######## on 3/25/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//

#import "ClickControl.h"


@implementation ClickControl

/*
- (id)init
{
if (self = [super init]) {
// Initialize your view controller.
self.title = @"ClickControl";
}
return self;
}

*/
- (void)loadView
{

// Create a custom view hierarchy.
UIView *controllerView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];

controllerView.autoresizesSubviews=YES;

controllerView.autoresizingMask=(UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth);

self.view = controllerView;

// the view hierarchy is now retaining the view, so we can release it here
[controllerView release];



}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}

/*
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview.
// Release anything that's not essential, such as cached data.
}

- (void)dealloc
{
[super dealloc];
}

}

*/

@end


I think my problem might be stemming from the fact that MyView draws the elements while ClickControl will be the class that watches for rotation and touches.

If there is other code that will help, let me know.

AvengerB
Jul 8, 2008, 05:47 AM
Thanks for the helpful tip!

With this now placed in my app deletgate.m it works, but is there a more efficient way?
CGRect rect = CGRectMake(40, 40, 240, 120);

// Show the box
[contentView drawRect:rect];


Off to read the suggested homework! :)


I have exactly the same problem.
How did u solve the error?

Line Location Tool:0: collect2: ld returned 1 exit status
Line Location Tool:0: symbol(s) not found
Line Location Tool:0: -[TestView drawRect:] in TestView.o
Line Location Tool:0: "_CGContextFillRect", referenced from:
Line Location Tool:0: -[TestView drawRect:] in TestView.o
Line Location Tool:0: "_CGContextSetRGBFillColor", referenced from:


here is my Code
TestView.h



#import <UIKit/UIKit.h>

@interface TestView : UIView {

}

@end


TestView.m




#import <UIKit/UIKit.h>
#import <CoreFoundation/CoreFoundation.h>
#import <CoreGraphics/CoreGraphics.h>
#import "TestView.h"


@implementation TestView


- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
// Initialization code
}
return self;
}

- (void)drawRect:(CGRect)rect
{
CGRect aRect;
aRect.origin.x=0;
aRect.origin.y=0;
aRect.size.width=20;
aRect.size.height=20;
UIRectFill(aRect);

//Get Window Graphics Context
CGContextRef aContext= UIGraphicsGetCurrentContext();

//Draw on the Layer
aRect.origin.x=20;
aRect.origin.y=20;
aRect.size.width=100;
aRect.size.height=100;
CGContextSetRGBFillColor(aContext, 255.0, 0.0,0.0,1.0);
CGContextFillRect(aContext,aRect);

}

- (void)dealloc {
[super dealloc];
}


@end



What am i Supposed to Add in the header file?
I have tried adding all the Header Files ..nothing seems to work. Please help me understand.

AvengerB
Jul 8, 2008, 06:19 AM
Thanks for the helpful tip!

With this now placed in my app deletgate.m it works, but is there a more efficient way?
CGRect rect = CGRectMake(40, 40, 240, 120);

// Show the box
[contentView drawRect:rect];


Off to read the suggested homework! :)

Finally solved..
The problem :/ The damn framework.
I had to add the framework CoreGraphics which is kept in the worst possible location 15 directories below the root directory. I believe this is the worst directory hierarchy ever in programming history..

ONe needs to select the Add the FrameWork "CoreGraphics" to the Project To get all CG functions working which i my opinion is very lame.
It should just be an import of CoreGraphics that should really do the trick. And this has not been mentioned anywhere in the goddamn API documentations.
Ohh Btw u wont find the coregraphics framework if u try searching the directories..best is to open the QuartzDemo project and look that FrameWork "Coregraphics" and open in Finder. Then follow the Directory and u will eventually find it..do the same for ur project.




Not that i have let my anger out....

I think as i am new to MAC OS X its very valid that i found it so hard.
Sorry for any anger venting ...:P just needed to get it out of my system.

oticon6
Jul 13, 2008, 03:47 PM
Finally solved..
The problem :/ The damn framework.
I had to add the framework CoreGraphics which is kept in the worst possible location 15 directories below the root directory. I believe this is the worst directory hierarchy ever in programming history..

ONe needs to select the Add the FrameWork "CoreGraphics" to the Project To get all CG functions working which i my opinion is very lame.
It should just be an import of CoreGraphics that should really do the trick. And this has not been mentioned anywhere in the goddamn API documentations.
Ohh Btw u wont find the coregraphics framework if u try searching the directories..best is to open the QuartzDemo project and look that FrameWork "Coregraphics" and open in Finder. Then follow the Directory and u will eventually find it..do the same for ur project.




Not that i have let my anger out....

I think as i am new to MAC OS X its very valid that i found it so hard.
Sorry for any anger venting ...:P just needed to get it out of my system.

I think that's a bug in Xcode. The active architecture is set as i386, whereas it should be armv6, as in the Project Settings, and consequently when you go to Add a Framework it gives you the wrong damn list.

Thanks for the tip though, you've ended about an hour of wanting to claw my eyes out.

iphonedev100
Jul 13, 2008, 04:10 PM
Select a framework already in your project (on the left). Control-click to have it reveal in finder. Drag over any frameworks you want (no searching needed). Don't click the checkbox to actually copy it.