아이폰어플개발정보2010. 10. 16. 23:18
[아이폰 앱 개발] Exploring iPhone Graphics Part 1

Exploring iPhone Graphics Part 1

April 9th, 2008 Posted in Software DevelopmentiPhone


The series of articles is going to discuss creating graphics on the iPhone using the SDK. Part 1 will start out with the basics by drawing some simple 2D graphics. In later articles I plan to get into animation, using the accelerometers and maybe even a little OpenGL.

The sample application for this article is very simple. It is just a Cocoa Touch application with a single view. The view’s drawRectmethod contains all of the code. Again, this first article is very introductory.

All drawing is done directly onto a graphics context. For this example we are drawing on the current UI graphics context. You can also create your own graphics context and draw into it but this article won’t be getting into that process.

The first step is to get the graphics context and clear it. Technically since we are only really rendering this scene once and nothing is changing I don’t need to clear it but I will anyway.


1
2
3
4
5

- (void)drawRect:(CGRect)rect
{
    // Get the graphics context and clear it
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextClearRect(ctx, rect);

The UIGraphicsGetCurrentContext function returns the current graphics context for thisUIView object. The CGContextRef value returned from this call is only valid until the drawRect method returns. You should not try to save the value in a variable and use it later.

CGContextClearRect does just what it says. It clears a rectangle. It actually makes the entire rectangle black. I haven’t found a way to clear to a different color.

The first object we are going to draw is a solid square colored red.


1
2
3

    // Draw a red solid square
    CGContextSetRGBFillColor(ctx, 255, 0, 0, 1);
    CGContextFillRect(ctx, CGRectMake(10, 10, 50, 50));

The CGContextSetRGBFillColor function is used to set the current fill color for the context. You give it values for red, green, blue and alpha. There are other ways to set the fill color but this is the easiest I’ve found. We’ll talk about the alpha value later.

You pass CGContextFillRect a rectangle created with CGRectMake and it will draw your rectangle using the current fill color. Nothing to it. Very simple stuff.

This code creates a solid circle colored green.


1
2
3

    // Draw a green solid circle
    CGContextSetRGBFillColor(ctx, 0, 255, 0, 1);
    CGContextFillEllipseInRect(ctx, CGRectMake(100, 100, 25, 25));

Again we use CGContextSetRBGFillColor to set the current fill color.CGContextFillEllipseInRect is passed a rectangle and will draw an ellipse within the bounds of the rectangle. We are giving it a square so our ellipse will end up being a circle.

The following code will draw the outline of a circle in blue:


1
2
3

    // Draw a blue hollow circle
    CGContextSetRGBStrokeColor(ctx, 0, 0, 255, 1);
    CGContextStrokeEllipseInRect(ctx, CGRectMake(200, 200, 50, 50));

This time we use CGContextSetRGBStrokeColor instead of CGContextSetRGBFillColor. The current stroke color is the color used to draw stroke type graphics.CGContextStrokeEllipseInRect is just like CGContextFillEllipseInRect except it draws a hollow circle instead of a filled circle.

This code draws the outline of square in yellow.


1
2
3

    // Draw a yellow hollow rectangle
    CGContextSetRGBStrokeColor(ctx, 255, 255, 0, 1);
    CGContextStrokeRect(ctx, CGRectMake(195, 195, 60, 60));

This code constructs a triangle from a set of three lines.


1
2
3
4
5
6

    // Draw a purple triangle with using lines
    CGContextSetRGBStrokeColor(ctx, 255, 0, 255, 1);
    CGPoint points[6] = { CGPointMake(100, 200), CGPointMake(150, 250),
                          CGPointMake(150, 250), CGPointMake(50, 250),
                          CGPointMake(50, 250), CGPointMake(100, 200) };
    CGContextStrokeLineSegments(ctx, points, 6);

The CGContextStrokeLineSegments function is passed an array of points and will draw lines between each pair of points.

The following code will draw the text string “TrailsintheSand.com”:


1
2
3
4
5
6
7
8
9
10
11
12
13

    // Draw the text TrailsintheSand.com in light blue
    char* text = "TrailsintheSand.com";
    CGContextSelectFont(ctx, "Helvetica", 24.0, kCGEncodingMacRoman);
    CGContextSetTextDrawingMode(ctx, kCGTextFill);
    CGContextSetRGBFillColor(ctx, 0, 255, 255, 1);
 
    CGAffineTransform xform = CGAffineTransformMake(
            1.0,  0.0,
            0.0, -1.0,
            0.0,  0.0);
    CGContextSetTextMatrix(ctx, xform);
 
    CGContextShowTextAtPoint(ctx, 10, 300, text, strlen(text));

When drawing text we need a font. In this case we are selecting a 24 point Helvetica font into the current context with the CGContextSelectFont function.

CGContextSetTextDrawingMode is used to set how the text will be drawn. In this case it is set to kCGTextFill which means the text will be filled with the current fill color. You can draw the text outlined using kCGTextStroke or both filled and outlined with kCGTextFillStroke.

Since we are using kCGTextFill we need to set a fill color.

CGContextShowTextAtPoint draws the text at the specified x,y coordinate within the view. Notice that it takes a C style null terminated string.

You’ll notice that I skipped the call to CGAffineTransformMake function call. If you run this code without it your text will be drawn up-side down but in the correct position on the screen. The CGAffineTransformMake function creates a transformation matrix and theCGContextSetTextMatrix will cause this matrix to be applied to all text drawn on the context. The matrix above will cause to text to be flipped so it is right-side up. It seems strange to me that the default would be upside down. Apparently fonts are stored with a different coordinate system. You can also use transformation matricies to do things like rotate and scale your text.

Now we are going to draw a filled gray transparent rectangle over some of the other graphics that we’ve already drawn.


1
2
3

    // Draw a transparent filled circle over other objects
    CGContextSetRGBFillColor(ctx, 200, 200, 200, 0.5);
    CGContextFillEllipseInRect(ctx, CGRectMake(100, 200, 150, 150));

The last parameter passed to CGContextSetRGBFillColor is the alpha value and controls the transparency of what is drawn. This value ranges from 0 to 1 with 0 being completely transparent and 1 being completely opaque.

The last graphics example is drawing an image.


1
2
3
4
5
6
7
8
9
10

    // Load image from applicaiton bundle
    NSString* imageFileName = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"iphone_sdk.png"];
    CGDataProviderRef provider = CGDataProviderCreateWithFilename([imageFileName UTF8String]);
    CGImageRef image = CGImageCreateWithPNGDataProvider(provider, NULL, true, kCGRenderingIntentDefault);
    CGDataProviderRelease(provider);
 
    // Draw image
    CGContextDrawImage(ctx, CGRectMake(200, 0, 100, 100), image);
    CGImageRelease(image);
}

The image we are going to draw has been added as a resouce to the project (just like a source file) and will be compiled into the application bundle. We get a reference to the bundle by calling the mainBundle: method of NSBundle. Then we get the resourcePath by calling the resourcePath: method on the mainBundle. This returns an NSString object that we call stringByAppendingPathComponent: on passing it the file name to get the full path to the file name.

Now that we have the file name we create a CGDataProviderRef object using theCGDataProviderCreateWithFilename function.

Now we can get the actual CGImageRef object that we’ll use to draw the image. TheCGImageCreateWithPNGDataProvider function takes our provider and turns it into an image.

We are done with the provider so we call CGDataProviderRelease to release its memory and resources.

Finally we can call the CGContextDrawImage function to actually draw the image on the graphics context. We pass it a rectangle that the image will be drawn into. The image will be automatically resized to fit the rectangle with no regard to the image aspect ratio.

Lastly we use CGImageRelease to free up the image.

The only problem with this code is that the image will be drawn up-side down. I assume this is the same reason fonts default to being drawn up-side down. I’ll talk about how to correct this in the next article.

Screenshot:
The next article in this series will go into more detail on drawing images.


http://trailsinthesand.com/exploring-iphone-graphics-part-1

Posted by 오늘마감

댓글을 달아 주세요

아이폰어플개발정보2010. 10. 12. 05:41
Exploring iPhone Graphics Part 1

Exploring iPhone Graphics Part 1

April 9th, 2008 Posted in Software DevelopmentiPhone


The series of articles is going to discuss creating graphics on the iPhone using the SDK. Part 1 will start out with the basics by drawing some simple 2D graphics. In later articles I plan to get into animation, using the accelerometers and maybe even a little OpenGL.

The sample application for this article is very simple. It is just a Cocoa Touch application with a single view. The view’s drawRectmethod contains all of the code. Again, this first article is very introductory.

All drawing is done directly onto a graphics context. For this example we are drawing on the current UI graphics context. You can also create your own graphics context and draw into it but this article won’t be getting into that process.

The first step is to get the graphics context and clear it. Technically since we are only really rendering this scene once and nothing is changing I don’t need to clear it but I will anyway.


1 2 3 4 5 

- (void)drawRect:(CGRect)rect { // Get the graphics context and clear it CGContextRef ctx = UIGraphicsGetCurrentContext(); CGContextClearRect(ctx, rect);

The UIGraphicsGetCurrentContext function returns the current graphics context for thisUIView object. The CGContextRef value returned from this call is only valid until the drawRect method returns. You should not try to save the value in a variable and use it later.

CGContextClearRect does just what it says. It clears a rectangle. It actually makes the entire rectangle black. I haven’t found a way to clear to a different color.

The first object we are going to draw is a solid square colored red.


1 2 3 

 // Draw a red solid square CGContextSetRGBFillColor(ctx, 255, 0, 0, 1); CGContextFillRect(ctx, CGRectMake(10, 10, 50, 50));

The CGContextSetRGBFillColor function is used to set the current fill color for the context. You give it values for red, green, blue and alpha. There are other ways to set the fill color but this is the easiest I’ve found. We’ll talk about the alpha value later.

You pass CGContextFillRect a rectangle created with CGRectMake and it will draw your rectangle using the current fill color. Nothing to it. Very simple stuff.

This code creates a solid circle colored green.


1 2 3 

 // Draw a green solid circle CGContextSetRGBFillColor(ctx, 0, 255, 0, 1); CGContextFillEllipseInRect(ctx, CGRectMake(100, 100, 25, 25));

Again we use CGContextSetRBGFillColor to set the current fill color.CGContextFillEllipseInRect is passed a rectangle and will draw an ellipse within the bounds of the rectangle. We are giving it a square so our ellipse will end up being a circle.

The following code will draw the outline of a circle in blue:


1 2 3 

 // Draw a blue hollow circle CGContextSetRGBStrokeColor(ctx, 0, 0, 255, 1); CGContextStrokeEllipseInRect(ctx, CGRectMake(200, 200, 50, 50));

This time we use CGContextSetRGBStrokeColor instead of CGContextSetRGBFillColor. The current stroke color is the color used to draw stroke type graphics.CGContextStrokeEllipseInRect is just like CGContextFillEllipseInRect except it draws a hollow circle instead of a filled circle.

This code draws the outline of square in yellow.


1 2 3 

 // Draw a yellow hollow rectangle CGContextSetRGBStrokeColor(ctx, 255, 255, 0, 1); CGContextStrokeRect(ctx, CGRectMake(195, 195, 60, 60));

This code constructs a triangle from a set of three lines.


1 2 3 4 5 6 

 // Draw a purple triangle with using lines CGContextSetRGBStrokeColor(ctx, 255, 0, 255, 1); CGPoint points[6] = { CGPointMake(100, 200), CGPointMake(150, 250), CGPointMake(150, 250), CGPointMake(50, 250), CGPointMake(50, 250), CGPointMake(100, 200) }; CGContextStrokeLineSegments(ctx, points, 6);

The CGContextStrokeLineSegments function is passed an array of points and will draw lines between each pair of points.

The following code will draw the text string “TrailsintheSand.com”:


1 2 3 4 5 6 7 8 9 10 11 12 13 

 // Draw the text TrailsintheSand.com in light blue char* text = "TrailsintheSand.com"; CGContextSelectFont(ctx, "Helvetica", 24.0, kCGEncodingMacRoman); CGContextSetTextDrawingMode(ctx, kCGTextFill); CGContextSetRGBFillColor(ctx, 0, 255, 255, 1);   CGAffineTransform xform = CGAffineTransformMake( 1.0, 0.0, 0.0, -1.0, 0.0, 0.0); CGContextSetTextMatrix(ctx, xform);   CGContextShowTextAtPoint(ctx, 10, 300, text, strlen(text));

When drawing text we need a font. In this case we are selecting a 24 point Helvetica font into the current context with the CGContextSelectFont function.

CGContextSetTextDrawingMode is used to set how the text will be drawn. In this case it is set to kCGTextFill which means the text will be filled with the current fill color. You can draw the text outlined using kCGTextStroke or both filled and outlined with kCGTextFillStroke.

Since we are using kCGTextFill we need to set a fill color.

CGContextShowTextAtPoint draws the text at the specified x,y coordinate within the view. Notice that it takes a C style null terminated string.

You’ll notice that I skipped the call to CGAffineTransformMake function call. If you run this code without it your text will be drawn up-side down but in the correct position on the screen. The CGAffineTransformMake function creates a transformation matrix and theCGContextSetTextMatrix will cause this matrix to be applied to all text drawn on the context. The matrix above will cause to text to be flipped so it is right-side up. It seems strange to me that the default would be upside down. Apparently fonts are stored with a different coordinate system. You can also use transformation matricies to do things like rotate and scale your text.

Now we are going to draw a filled gray transparent rectangle over some of the other graphics that we’ve already drawn.


1 2 3 

 // Draw a transparent filled circle over other objects CGContextSetRGBFillColor(ctx, 200, 200, 200, 0.5); CGContextFillEllipseInRect(ctx, CGRectMake(100, 200, 150, 150));

The last parameter passed to CGContextSetRGBFillColor is the alpha value and controls the transparency of what is drawn. This value ranges from 0 to 1 with 0 being completely transparent and 1 being completely opaque.

The last graphics example is drawing an image.


1 2 3 4 5 6 7 8 9 10 

 // Load image from applicaiton bundle NSString* imageFileName = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"iphone_sdk.png"]; CGDataProviderRef provider = CGDataProviderCreateWithFilename([imageFileName UTF8String]); CGImageRef image = CGImageCreateWithPNGDataProvider(provider, NULL, true, kCGRenderingIntentDefault); CGDataProviderRelease(provider);   // Draw image CGContextDrawImage(ctx, CGRectMake(200, 0, 100, 100), image); CGImageRelease(image); }

The image we are going to draw has been added as a resouce to the project (just like a source file) and will be compiled into the application bundle. We get a reference to the bundle by calling the mainBundle: method of NSBundle. Then we get the resourcePath by calling the resourcePath: method on the mainBundle. This returns an NSString object that we call stringByAppendingPathComponent: on passing it the file name to get the full path to the file name.

Now that we have the file name we create a CGDataProviderRef object using theCGDataProviderCreateWithFilename function.

Now we can get the actual CGImageRef object that we’ll use to draw the image. TheCGImageCreateWithPNGDataProvider function takes our provider and turns it into an image.

We are done with the provider so we call CGDataProviderRelease to release its memory and resources.

Finally we can call the CGContextDrawImage function to actually draw the image on the graphics context. We pass it a rectangle that the image will be drawn into. The image will be automatically resized to fit the rectangle with no regard to the image aspect ratio.

Lastly we use CGImageRelease to free up the image.

The only problem with this code is that the image will be drawn up-side down. I assume this is the same reason fonts default to being drawn up-side down. I’ll talk about how to correct this in the next article.

Screenshot:
The next article in this series will go into more detail on drawing images.


http://trailsinthesand.com/exploring-iphone-graphics-part-1

Posted by 오늘마감

댓글을 달아 주세요

아이폰어플개발정보2010. 6. 24. 14:13
Beginning iPhone Development: Exploring the iPhone SDK

CH2. Appeasing the Tiki Gods


In each Nib file (File’s Owner and First Responder), every icon in this window represents a single instance of an  Objective‑ C class that will be created automatically for you when this nib file is loaded. 


File’s Owner: represents the object that loaded the nib file from disk

First Responder: the object with which the user is currently interacting. The first responder changes as the user interacts with the interface.


AppKit (Mac OS X) --- UIKit (iPhone OS)


CH3. Handling Basic Interaction


MVC model - Any object you write should be readily identifiable as belonging in one of the three categories for maximum reusability.


outlet: (IBOutlet) a pointer that points to an object within the nib

IBOutlet keyword in the header files allows IB to make connections from your code to the nib.


action: (IBAction) part of controller class. 


class methods: factory methods, returns an autoreleased object


“if you didn’t allocate it or retain it, don’t release it”


UIViewController --- corresponding nib file

MainWindow.xib --- in Info.plist -- ApplicationDelegate


Your controller class is the file’s owner for the nib file of the same name.


** connecting outlets **

By  control‑ dragging from File’s Owner to an interface object, you are telling Interface Builder that you want to connect one of the File’s Owner’s outlets to this object when the nib file is loaded.


** specifying actions **

The only thing left to do is to identify which actions these buttons trigger and under what circumstances they trigger them.


 Up Inside.  In most of your iPhone applications if you touch the screen and change your mind. You move your finger off the button before lifting up, right? We should give our users the same ability. If our user’s finger is still on the button when it’s lifted off the screen, then we can safely assume that the button tap is intended.


Ch4. More User Interface Fun


* Controls can be used in many ways.

- active: button, ...

- static: label, ...

- passive: e.g., text field, ...


The way to access the data held by a passive control is to use an outlet.


If you want to display the same image at multiple sizes, generally it’s better to have multiple copies of the image at different sizes in your project rather than force the iPhone to do scaling at runtime.


Tags provide an easy,  language-independent way of identifying objects on your interface. The system will never set or change its value.


Opaque: nothing below this view ever needs to be drawn no matter what.

Clip Subviews: is off by default for the sake of performance


When the user taps the Done button, a “did end on exit” event will be generated.

First responder is the control that the user is currently interacting with. When a text field yields first responder status, the keyboard associated with it goes away.


action sheet - <UIActionSheetDelegate>

All action sheets should have a cancel button.

In situations where you want to notify the user without giving a choice of options, an alert sheet (alert view?) is more appropriate.

Action sheets always have a parent, which must be a view that is currently visible to the user. .


* 4 states of a control

- normal: rest of the other three

- highlighted: when it is being used

- disabled

- selected


Ch5. Autorotation and Autosizing


* tackling autorotation

- autosizing

- manually reposition each object

- different view versions for each rotation


* 4 possible roation

- UIInterfaceOrientationPortrait 

- UIInterfaceOrientationPortraitUpsideDown 

- UIInterfaceOrientationLandscapeLeft 

- UIInterfaceOrientationLandscapeRight 


Because every view controller subclass can implement this differently, it is  possible for one application to support autorotation with some of its views but not with others.


Transformations are mathematical descriptions of changes to an object’s size, position, or angle.


Ch6. Multiview Applications


UITabBarController and UINavigationController are subclasses of UIViewController and can do anything other view controllers can do.


A content view is created indirectly by instantiating its controller class and specifying a nib name. Nibs are typically named using the same name as the controller class.


The root controller gets created when the application loads MainWindow.xib.


The window is the only gateway to the user, so anything that needs to be displayed to the user has to get added as a window subview.


Lazy Loading: do not load resources in the viewDidLoad: method until they are actually needed. ** Loading resources on-demand allows us to freely deallocating those resources when low memory situation occurs. **


** When we changed the underlying class of the file’s owner, the existing outlet connections were broken.  **


**Animation Example**


[UIView beginAnimations:@"View Flip" context:nil]; 

[UIView setAnimationDuration:1.25]; 

[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 

[UIView setAnimationTransition: transition forView:self.view cache:YES]; 

[coming viewWillAppear:YES]; //#1

[going viewWillDisappear:YES]; //#1

[going.view removeFromSuperview]; 

[self.view insertSubview: coming.view atIndex:0]; 

[going viewDidDisappear:YES]; //#1

[coming viewDidAppear:YES]; //#1

[UIView commitAnimations]; 


#1: Views that have running animations on them, for example, will often choose to turn those animations off when their view is swapped out and turn them back on when they are swapped back in.


Ch7. Tab Bars and Pickers


The picker asks the delegate for either a string or a view that will be drawn at a given spot on a given component.

Picker datasource methods are used by the picker to get the number of components and the number of rows in each component. The datasource isn’t usually an object designed to hold data; it’s an object that supplies data to the picker.


Tab Bar icons - 24x24 pixels in .png format


* Using Interface Builder

1. Declare var.s in Header file

2. Draw controls and set up the classes and properties

3. Implement the Method file


We use NSInteger rather than int or long, because when we use NSInteger, the compiler automatically chooses whichever size is best for the platform for which we are compiling.


Putting in #pragma mark directives and logically organizing your code will make that  pop- up more efficient to use.


bundle is just a special type of folder whose contents follow a specific structure. Applications and frameworks are both bundles.


** fonts on iPhone **

American TypewriterAppleGothicArialArial Rounded MT BoldArial Unicode MS,CourierCourier New, DB LCD Temp, Georgia, Helvetica, Helvetica NeueHiragino Kaku Gothic ProN W3Hiragino Kaku Gothic ProN W6Marker FeltSTHeiti JSTHeiti KSTHeiti SCSTHeiti TCTimes New RomanTrebuchet MSVerdanaZapfino


** convenience class methods use the autorelease pool.


NSString *path = [[NSBundle mainBundle] pathForResource:@"crunch" ofType:@"wav"]; 

SystemSoundID soundID; 

AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:path], &soundID); 

AudioServicesPlaySystemSound(soundID);


Ch8. Introduction to Table Views

A table view is the object that displays the visible part of a table, and a table view cell is responsible for displaying a single row of the table.


Table views get their configuration data from an object that conforms to the UITableViewDelegate protocol and their row data from an object that conforms to the UITableViewDataSource protocol.


* 2 methods that implement the UITableViewCell

- add subviews to UITableViewCell

- subclass UITableViewCell


* 2 types of table view

- grouped table

- indexed (with or without index)


section: group in a table


Mutable copy: shallow copy


It is not safe to remove objects from a collection while iterating that collection.


It’s very important to avoid using convenience methods inside of loops as much as possible, because they will put something into the autorelease pool every time through the loop. However, the autorelease pool can’t get flushed until we’re all done with our loop.


Ch9. Navigation Controllers and Table Views


UINavigationController is implemented as a stack

disclosure indicator vs. detail disclosure control


If tapping a row takes you to another view entirely, one that is not a more detailed view of that row, use a disclosure indicator (gray arrow) to mark the row. 


** 6 styles of cell **

+ Detail Disclosure button

// showing disclosure button

- (UITableViewCellAccessoryType)tableView:(UITableView *)tableView accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath 

    return UITableViewCellAccessoryDetailDisclosureButton; 

}

// responding disclosure detail button

- (void)tableView:(UITableView *)tableView 

accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath 


+ Checked

newCell.accessoryType = UITableViewCellAccessoryCheckmark;


+ Adding Controls

// add control to the accessory pane

UISwitch *switchControl = [[UISwitch alloc] init];

switchControl.tag = kSwitchTag;

cell.accessoryView = switchControl;


// read value

UISwitch *switchControl = [cell viewWithTag:kSwitchTag];


+ Editing mode

setEditing:animated: method on the table view.


reordering for cell

cell.showsReorderControl = YES;


+ Delete mode

The delete and reorder operations do play nicely together.

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath


We can’t store raw datatypes like int in an NSDictionary.


Ch10. Application Settings and User Defaults


NSUserDefaults class

There can only be one root node in any given property  list, and all nodes must come under it.

Although you can use any kind of object as a key in an NSDictionary, keys in property list dictionary nodes have to be strings, though you are free to use any node type for the values.


Sliders allow placement of a small  21- pixel   21- pixel image at each end of the slider.


* Type *

PSGroupSpecifier

PSTextFieldSpecifier

PSTextFieldSpecifier

PSMultiValueSpecifier

PSToggleSwitchSpecifier

PSSliderSpecifier

PSChildPaneSpecifier


NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

objectForKey:, intForKey:, floatForKey: boolForKey:


Ch11. Basic Data Persistence


NSSearchPathForDirectoriesInDomain function


* Document directory *

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 

NSString *documentsDirectory = [paths objectAtIndex:0];

// each application has only one Documents directory.

NSString *filename = [documentsDirectory  stringByAppendingPathComponent:@"/theFile.txt"];


* Temporary directory *

NSString *tp = NSTemporaryDirectory();


The downside of using a single file is that you have to load all of your application’s data into memory, and you have to write all of it to the file system for even the smallest changes.


** Property list serialization

Although any object can be made serializable, only certain objects can be placed into a collection class, such as an NSDictionary or NSArray, and then stored to a property list using the collection classes’ writeToFile:atomically: method. 

- NSArray

- NSMutableArray

- NSDictionary

- NSMutableDictionary

- NSData

- NSMutableData

- NSString

- NSMutableString

- NSNumber

- NSDate


[myArray writeToFile:@"/some/file/location/output.plist" atomically:YES];


** Archiving model object

* NSCoding protocol *

You can encode and decode both objects and scalars using  key- value coding.

- (void)encodeWithCoder:(NSCoder *)encoder

- (id)initWithCoder:(NSCoder *)decoder

// if your superclass doesn't conform to NSCoding

   if (self = [super init])

// if your superclass conforms to NSCoding

   if (self = [super initWithCoder:decoder])


* NSCopying protocol *

- (id)copyWithZone:(NSZone *)zone

{

    MyClass *copy = [[[self class] allocWithZone: zone] init];

    copy.foo = [self.foo copy];

   ...

    return copy;// caller releases copy

}


* Archiving Data object *

NSMutableData *data = [[NSMutableData alloc] init];

NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];

[archiver encodeObject:myObject forKey:@"keyValueString"];

[archiver finishEncoding];

BOOL success = [data writeToFile:@"/path/to/archive" atomically:YES];

[archiver release];

[data release];

* Unarchiving Data object *

NSData *data = [[NSData alloc] initWithContentsOfFile:path];

NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];

self.object = [unarchiver decodeObjectForKey:@"keyValueString"]; // auto-released

[unarchiver finishDecoding];

[unarchiver release];

[data release];


** SQLite3

 object- relational mapping (ORM) is provided by Core Data

// open

sqlite3 *database;

int result = sqlite3_open("/path/to/database/file", &database);

// close

sqlite3_close(database);

// execution

char * errorMsg;

const char *createSQL = "CREATE TABLE IF NOT EXISTS PEOPLE

 (ID INTEGER PRIMARY KEY AUTOINCREMENT, FIELD_DATA TEXT)";

int result = sqlite3_exec (database, createSQL, NULL, NULL, &errorMsg);

// retrieval

NSString *query = @"SELECT ID, FIELD_DATA FROM FIELDS ORDER BY ROW";

sqlite3_stmt *statement;

int result = sqlite3_prepare_v2( database, [query UTF8String],-1, &statement, nil);

while (sqlite3_step(statement) == SQLITE_ROW) {

    int rowNum = sqlite3_column_int(statement, 0);

    char *rowData = (char *)sqlite3_column_text(statement, 1);

    NSString *fieldValue = [[NSString alloc] initWithUTF8String:rowData];

    // Do something with the data here

    [fieldValue release];

}

sqlite3_finalize(statement);


Ch12. Drawing with Quartz and OpenGL


* Quartz 2D: painter's model on a virtual canvas with invisible pen (context)

* OpenGL ES: state machine, virtual window into its 3D world


** Quartz 2D **

Core Graphics’s API is C based.


// retrieves the current context

CGContextRef context = UIGraphicsGetCurrentContext();


CGPoint(x, y)

CGSize(width, height)

CGRect(CGPoint origin, CGSize size)


Color: (Red, Green, Blue) * alpha

[UIColor colorWithRed:1.0f green:0.0f blue:0.0f alpha:1.0f]


Draw images directly into a context:

CGImage or UIImage (ObjC alternative)


when an object instance is loaded from a nib, neither init: or initWithFrame: ever gets called. Instead, initWithCoder: is used.


setNeedsDisplay:  vs. setNeedsDisplayInRect:


We need to redraw not just the rectangle between firstTouch and lastTouch but any part of the screen encompassed by the current drag.


** OpenGLES **

http://www.khronos.org/opengles/


OpenGL ES doesn’t have sprites or images, per se; it has textures. draw a polygon, and then map a texture onto that polygon


[1] you draw in the context.

[2] once all your drawing is done, you render the context into the buffer.

[3] you present your render buffer, which is when the pixels actually get drawn onto the screen.


Ch13. Taps, Touches, and Gestures


160 pixels per inch


gesture is any sequence of events that happens from the time you touch the screen with one or more fingers until you lift your fingers off the screen.


iPhone only keeps track of tapswhen one finger is used.


The first responder is almost always a view or control and gets the first shot at responding to an event.


responder chain: view -> view's view controller -> view's parent view -> view's parent's view controller -> ...

If an object intercepts an event that it doesn’t handle, it needs to pass it along manually, by calling the same method on the next responder.


Every object in touches is a UITouch event that represents one finger touching the screen.

Every UITouch object knows its current position in the view, as well as its previous position in the view.


Ch14. Core Location


CLLocationManager *locationManager = [[CLLocationManager alloc] init];


Our delegate must conform to the CLLocationManagerDelegate protocol.


// self conforms to CLLocationManagerDelegate protocol

locationManager.delegate = self;

locationManager.desiredAccuracy = kCLLocationAccuracyBest;

locationManager.distanceFilter = 1000.0f;

// start continuously polling the location

[locationManager startUpdatingLocation];


The accuracy value is in meters, so if you specify a desiredAccuracy of 10, you’re telling Core Location that you want it to try to determine the current location within 10 meters, if possible.

Distance filters are also set in meters.


Ch15. Accelerometer

(+x: right, +y: up, +z: front)


Accelerometers give measurements in  g- forces (“g” for gravity), so a value of 1.0 returned by the accelerometer means that 1 g is sensed in a particular direction.


 // singleton

UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];

accelerometer.delegate = self;          // UIAccelerometerDelegate protocol

accelerometer.updateInterval =  1.0f/60.0f;


accelerometer:didAccelerate:           // delegate method

UIAcceleration object                      // passed object for acceleration data


** detect shaking (1.5g ~ 2g, max: 2.3g)

- (void)accelerometer:(UIAccelerometer *)accelerometer 

    didAccelerate:(UIAcceleration *)acceleration {

    

    if (fabsf(acceleration.x) > 2.0  

        || fabsf(acceleration.y) > 2.0 

        || fabsf(acceleration.z) > 2.0) {

        // Do something here...

    }

}


If you’re doing animation based on input from the accelerometer, you have to keep track of the time that passes between delegate method calls.


When using the accelerometer as a controller, you’ll need to poll at a considerably faster rate, usually between 30 and 60 updates per second.


Ch16. Camera and Photo Library

UIImagePickerController

1. create an instance of this class

2. specify a delegate

3. specify its image source

4. launch it modally


[UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]


UIImagePickerController *picker = [[UIImagePickerController alloc] init];

picker.delegate = self;                // UIImagePickerControllerDelegate protocol

picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

[self presentModalViewController:picker animated:YES];

[picker release];


UIImagePickerController is a subclass of UINavigationController, we have to conform our class to both of these protocols.


Ch17. Application Localization

<2 or 3 language code (lower case)>_<2 letter country code (upper case)>.lproj


Full name localization project, such as French.lprj. exists to support legacy Mac OS X applications, and you should avoid it.


* resouce searching order

1. language_country matching resource

2. language matching resource

3. base language resource


* string files *

/* comments */ 

"First Name" = "First Name"; 

-----

NSString *myString = @"First Name";

NSString *myString = NSLocalizedString(@"First Name", 

    @"Used to ask the user his/her first name");


genstrings ./Classes/*.m

import (not copy) Localizable.strings as UTF-16 char. set file.



출처 : http://blog.naver.com/PostView.nhn?blogId=gonagi&logNo=150051830428
Posted by 오늘마감

댓글을 달아 주세요