태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.
- (void) handleDoubleTap : (UIGestureRecognizer*) sender
{
NSLog (@"Double tap is being handled here");
}

- (void) handleSingleTap : (UIGestureRecognizer*) sender
{
NSLog (@"Single tap is being handled here");
}

- (void) loadView
{
UITapGestureRecognizer* doubleTap = [[UITapGestureRecognizer alloc] initWithTarget : self action : @selector (handleDoubleTap:)];
UITapGestureRecognizer* singleTap = [[UITapGestureRecognizer alloc] initWithTarget : self action : @selector (handleSingleTap:)];

[singleTap requireGestureRecognizerToFail : doubleTap];

[doubleTap setDelaysTouchesBegan : YES];
[singleTap setDelaysTouchesBegan : YES];

[doubleTap setNumberOfTapsRequired : 2];
[singleTap setNumberOfTapsRequired : 1];

[self.view addGestureRecognizer : doubleTap];
[self.view addGestureRecognizer : singleTap];

[singleTap release];
[doubleTap release];
}
신고
블로그 이미지

*별빛*

UI/UX관련 개발이슈 및 방법을 나누는 곳입니다. Flex/AIR, Silverlight등 pc 기반 iPhone, Android등 smartphone 기반

http://iphonedevelopertips.com/cocoa/launching-your-own-application-via-a-custom-url-scheme.html

Launching Your Own Application via a Custom URL Scheme

신고
블로그 이미지

*별빛*

UI/UX관련 개발이슈 및 방법을 나누는 곳입니다. Flex/AIR, Silverlight등 pc 기반 iPhone, Android등 smartphone 기반

// 0. picker등에서 선택한 이미지를 jpeg data로 변환.
NSData *imageData = UIImageJPEGRepresentation(image.image, 90); 

// 1. 보낼 URL 지정
NSString *urlString = @"http://iphone.zcentric.com/test-upload.php";

// 2. Request object 초기화
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease]; [request setURL:[NSURL URLWithString:urlString]]; 
 [request setHTTPMethod:@"POST"]; 

NSString *boundary = @"---------------------------14737809831466499882746641449"; NSString *contentType = [NSString stringWithFormat:@"multipart/form-data;boundary=%@",boundary]; 

[request addValue:contentType forHTTPHeaderField: @"Content-Type"]; 
 /* now lets create the body of the post */ 
NSMutableData *body = [NSMutableData data]; 
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
 [body appendData:[[NSString stringWithString:@"Content-Disposition: form-data; name=\"userfile\"; filename=\"ipodfile.jpg\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; 
[body appendData:[[NSString stringWithString:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; 
[body appendData:[NSData dataWithData:imageData]]; 
[body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]]; 
// setting the body of the post to the reqeust 
 [request setHTTPBody:body]; // now lets make the connection to the web 
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; 
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
신고
블로그 이미지

*별빛*

UI/UX관련 개발이슈 및 방법을 나누는 곳입니다. Flex/AIR, Silverlight등 pc 기반 iPhone, Android등 smartphone 기반

[원문]

Binary Property Lists

MS ActiveUserHostility™ in Tiger? You can get around it - for now.


Buy It

Try It

Welcome to the Apple Registry: OS X 10.4 Tiger reverts to a binary format for property lists. Actually this format has been available all along. From the manpage for plutil:

NAME
  plutil - property list utility

SYNOPSIS
plutil [command_option] [other_options] file ...

DESCRIPTION
plutil can be used to check the syntax of property list files, or convert a plist file from one format to another.

-convert fmt
 
Convert the named file to the indicated format and write back to the file system.

fmt is one of: xml1, for version 1 of the XML plist format; binary1, for version 1 of the binary plist format.

-o
 
Specify an alternate path name for the result of the -convert operation.

[Note: older manpages will incorrectly give the XML format as 'xm1'. Ed.]

One can then test this operation by copying out a sample property list file - in this case the file for the WebFoundation was chosen for its brevity.

% cat com.apple.WebFoundation.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>WebAcceptCookies</key>
    <string>never</string>
</dict>
</plist>
%

All one needs at this point is a command line.

% plutil -convert binary1 -o binary.plist com.apple.WebFoundation.plist
%

And then hexdump.

% hexdump -Cv binary.plist
00000000  62 70 6c 69 73 74 30 30  d1 01 02 5f 10 10 57 65  |bplist00..._..We|
00000010  62 41 63 63 65 70 74 43  6f 6f 6b 69 65 73 55 6e  |bAcceptCookiesUn|
00000020  65 76 65 72 08 0b 1e 00  00 00 00 00 00 01 01 00  |ever............|
00000030  00 00 00 00 00 00 03 00  00 00 00 00 00 00 00 00  |................|
00000040  00 00 00 00 00 00 24                              |......$|
%

As can be seen, binary property lists contain the signature 'bplist00' (version 0.0?) and the actual text used in the key/value pair is preserved; however everything else is a mishmash, and you can't edit it directly.

Your version of OS X will automatically revert to its preferred format for property lists; on versions prior to Tiger, this was the 'xml1' format; now with Tiger we're into Bill Gates Registry territory with the 'binary1' format.

You can convert any property list files you want - and thereafter edit them as plain text files; you can even replace them in the system in the 'xml1' format; the next time the system writes to them the 'binary1' format will be used again.

So yes, it's a speed bump, and no, this is not going to be popular, but yes, you can get around it for the moment.

At least until Mister Bill again starts to flash his $800 million and demand more.

신고
블로그 이미지

*별빛*

UI/UX관련 개발이슈 및 방법을 나누는 곳입니다. Flex/AIR, Silverlight등 pc 기반 iPhone, Android등 smartphone 기반

시뮬레이터에서는 아무상관없이 잘 컴파일이 되는데, 

Device로 컴파일하면 에러가 몇백개 나는 경우가 있다.

이때, 컴파일옵션중 Header Search Paths에 다음 경로를 추가하자.

$(SDKROOT)/usr/include/c++/4.2.1/armv6-apple-darwin9
신고
블로그 이미지

*별빛*

UI/UX관련 개발이슈 및 방법을 나누는 곳입니다. Flex/AIR, Silverlight등 pc 기반 iPhone, Android등 smartphone 기반

Tag STL

cocos2d has proven to be invaluable in enabling us to get our iPhone game up and running fast. But when we started playing with animated sprites, we noticed some performance problems. If you are like us and have many sprites that have to have repeating animations, you may have noticed the same thing.

Conventional wisdom (aka the sample code) says that you would create a RepeatForever action using an Animate action to animate an AtlasSprite. When we tried this, however, we noticed that at the end of each animation cycle, the action would deallocate an AtlasSpriteFrame. This is a by-product of the Animate action being able to restore the original frame of animation once the animation has finished playing. This is also what was causing the performance issues.

To resolve this, we created a cut-down version of the Animate action called FastAnimate. It is very similar to the Animate action with the exception that it does not support restoring the original frame of animation. From what we’ve seen, this simple change greatly increases the performance of animating sprites in cocos2d.

FastAnimate.h:

#import "cocos2d.h"
 
@interface FastAnimate : IntervalAction <NSCopying>
{
	Animation *animation;
}
+(id) actionWithAnimation:(id<CocosAnimation>) a;
-(id) initWithAnimation:(id<CocosAnimation>) a;
@end

FastAnimate.m:

#import "FastAnimate.h"
 
@implementation FastAnimate
 
+(id) actionWithAnimation: (id<CocosAnimation>)anim {
	return [[[self alloc] initWithAnimation:anim] autorelease];
}
 
-(id) initWithAnimation: (id<CocosAnimation>)anim {
	NSAssert( anim!=nil, @"Animate: argument Animation must be non-nil");
 
	if( (self=[super initWithDuration: [[anim frames] count] * [anim delay]]) ) {
 
		animation = [anim retain];
	}
	return self;
}
 
-(id) copyWithZone: (NSZone*) zone {
	return [[[self class] allocWithZone: zone] initWithAnimation: animation];
}
 
-(void) dealloc {
	[animation release];
	[super dealloc];
}
 
-(void) start {
	[super start];
}
 
-(void) stop {
	[super stop];
}
 
-(void) update: (ccTime) t {
	NSUInteger idx=0;
 
	ccTime slice = 1.0f / [[animation frames] count];
 
	if(t !=0 )
		idx = t/ slice;
 
	if( idx >= [[animation frames] count] ) {
		idx = [[animation frames] count] -1;
	}
	id<CocosNodeFrames> sprite = (id<CocosNodeFrames>) target;
	if (! [sprite isFrameDisplayed: [[animation frames] objectAtIndex: idx]] ) {
		[sprite setDisplayFrame: [[animation frames] objectAtIndex:idx]];
	}
}
@end

신고
블로그 이미지

*별빛*

UI/UX관련 개발이슈 및 방법을 나누는 곳입니다. Flex/AIR, Silverlight등 pc 기반 iPhone, Android등 smartphone 기반

Wouldn’t it be handy for your iPhone app to have access to its subversion revision number at run-time? Of course it would!

Being able to access the current revision number in your app is especially useful for testing. We use it to display the current rev on our test builds so our testers can reference the build that they discover bugs in, like so:

Here’s how to do it

1. In Xcode, add an empty header file to your project’s “Other Sources” group called “revision.h”.

2. Add a “New Run Script Build Phase” to your target.

3. When defining your build phase, use “/bin/sh” for the Shell value and enter the following script:

REV=`svnversion -n`
echo "#define kRevision @\"$REV\"" > ${PROJECT_DIR}/revision.h

4. Ensure that the new build phase happens before your “Compile Sources” build phase.

5. Build your app.

That’s it! From now on you can use a string define called kRevision wherever you would like to reference your revision number at run-time.

IMPORTANT: Do NOT add your revision.h file to your subversion repository. It will be generated automatically each time you build your app.


신고
블로그 이미지

*별빛*

UI/UX관련 개발이슈 및 방법을 나누는 곳입니다. Flex/AIR, Silverlight등 pc 기반 iPhone, Android등 smartphone 기반

There is a collectively recognized method for storing application data and preferences which is NSUserDefaults.  The API for this is a bit unconventional and I thought an appropriate wrapper class would work well in this case.  While not completely understanding the full details of NSUserDefaults I developed a singleton class which we can use in our games to save/load data.  The interface is simple…

SettingsManager.h

#import <Foundation/Foundation.h>
 
@interface SettingsManager : NSObject {
	NSMutableDictionary* settings;
}
 
-(NSString *)getString:(NSString*)value;
-(int)getInt:(NSString*)value;
-(void)setValue:(NSString*)value newString:(NSString *)aValue;
-(void)setValue:(NSString*)value newInt:(int)aValue;
-(void)save;
-(void)load;
-(void)logSettings;
 
+(SettingsManager*)sharedSettingsManager;
@end

SettingsManager.m

#import "SettingsManager.h"
 
@implementation SettingsManager
 
static SettingsManager* _sharedSettingsManager = nil;
 
-(NSString *)getString:(NSString*)value
{	
	return [settings objectForKey:value];
}
 
-(int)getInt:(NSString*)value {
	return [[settings objectForKey:value] intValue];
}
 
-(void)setValue:(NSString*)value newString:(NSString *)aValue {	
	[settings setObject:aValue forKey:value];
}
 
-(void)setValue:(NSString*)value newInt:(int)aValue {
	[settings setObject:[NSString stringWithFormat:@"%i",aValue] forKey:value];
}
 
-(void)save
{
        // NOTE: You should be replace "MyAppName" with your own custom application string.
        //
	[[NSUserDefaults standardUserDefaults] setObject:settings forKey:@"MyAppName"];
	[[NSUserDefaults standardUserDefaults] synchronize];	
}
 
-(void)load
{
        // NOTE: You should be replace "MyAppName" with your own custom application string.
        //
	[settings addEntriesFromDictionary:[[NSUserDefaults standardUserDefaults] objectForKey:@"MyAppName"]];
}
 
// Logging function great for checkin out what keys/values you have at any given time
//
-(void)logSettings
{
	for(NSString* item in [settings allKeys])
	{
		NSLog(@"[SettingsManager KEY:%@ - VALUE:%@]", item, [settings valueForKey:item]);
	}
}
 
+(SettingsManager*)sharedSettingsManager
{
	@synchronized([SettingsManager class])
	{
		if (!_sharedSettingsManager)
			[[self alloc] init];
 
		return _sharedSettingsManager;
	}
 
	return nil;
}
 
+(id)alloc
{
	@synchronized([SettingsManager class])
	{
		NSAssert(_sharedSettingsManager == nil, @"Attempted to allocate a second instance of a singleton.");
		_sharedSettingsManager = [[super alloc] init];
		return _sharedSettingsManager;
	}
 
	return nil;
}
 
-(id)autorelease {
    return self;
}
 
-(id)init {	
	settings = [[NSMutableDictionary alloc] initWithCapacity:5];	
	return [super init];
}
 
@end

Values can then be saved/retrieved in code like so…

[[SettingsManager sharedSettingsManager] saveValue:@"hiscore" newValue:@"10000"];
NSString* myValue = [[SettingsManager sharedSettingsManager] getValue:@"hiscore"];
int myInt = [[SettingsManager sharedSettingsManager] getInt:@"challenges_won"];

To save our values on an incoming call or other system interruption we can put save/load calls in the appropriate callbacks of the app delegate…

- (void)applicationDidFinishLaunching:(UIApplication *)application
 
{
  // ...  (some code) ...
 
  // Load settings on initial startup
  //
  [[SettingsManager sharedSettingsManager] load];
 
  // ...  (more code) ...
}
 
- (void)applicationWillResignActive:(UIApplication *)application
{
  [[SettingsManager sharedSettingsManager] save];
  [[Director sharedDirector] pause];
}
 
- (void)applicationDidBecomeActive:(UIApplication *)application
{
  [[SettingsManager sharedSettingsManager] load];
  [[Director sharedDirector] resume];
}
 
- (void)applicationWillTerminate:(UIApplication *)application
{
  [[SettingsManager sharedSettingsManager] save];
  [[Director sharedDirector] end];
}

This basic class is great for storing arbitrary user state values that you want to preserve for the next time someone plays your game.  Hi scores, level progression, number of lives are a few of the possibilities this class could be used for.


신고
블로그 이미지

*별빛*

UI/UX관련 개발이슈 및 방법을 나누는 곳입니다. Flex/AIR, Silverlight등 pc 기반 iPhone, Android등 smartphone 기반

While working on our coming-soon first iPhone game, we have been having a lot of success with cocos2d. One area in particular that we have been impressed with is the ability to run “Actions” on sprites, string them together in sequences and wrap them in modifiers such as ease-in, ease-out etc. This has made it easy to make our UI lively and animated as well as animate our game objects.

Recently we had a need to animate an AtlasSprite’s texture rect in order to pan around an atlas sprite. We ended up creating a custom cocos2d action to do this and we figured it would be a good thing to give back to the community.

This will allow you to transform an AtlasSprite’s texture rect’s origin and size over the length of a provided duration. You can also wrap this in a modifier action such as ease-in or repeater.

Here is the code

TransformTextureRect.h:

#import "cocos2d.h"
 
@interface TransformTextureRect : IntervalAction {
	CGRect fromRect;
	CGRect toRect;
}
+(id) actionWithDuration:(ccTime)d toRect:(CGRect)rect;
-(id) initWithDuration:(ccTime)d toRect:(CGRect)rect;
 
@end

TransformTextureRect.m:

#import "TransformTextureRect.h"
 
@implementation TransformTextureRect
+(id) actionWithDuration:(ccTime)d toRect:(CGRect)rect {
	return [[[self alloc] initWithDuration:d toRect:rect] autorelease];
}
 
-(id) initWithDuration:(ccTime)d toRect:(CGRect)rect {
	if ( (self=[super initWithDuration:d] ) )
		toRect = rect;
	return self;
}
 
-(id) copyWithZone: (NSZone*) zone
{
	Action *copy = [[[self class] allocWithZone: zone] initWithDuration: [self duration] toRect: toRect];
	return copy;
}
 
-(void) start
{
	[super start];
	fromRect = [(AtlasSprite*)target textureRect];
}
 
-(void) update: (ccTime) t
{	
	[(AtlasSprite*)target setTextureRect:CGRectMake(fromRect.origin.x + (toRect.origin.x - fromRect.origin.x) * t,
													fromRect.origin.y + (toRect.origin.y - fromRect.origin.y) * t,
													fromRect.size.width + (toRect.size.width - fromRect.size.width) * t,
													fromRect.size.height + (toRect.size.height - fromRect.size.height) * t)];
}
 
@end

Example Usage

This transforms an AtlasSprite’s texture rect to the position (25,25) and with a width and height of 50 over the course of 1 second:

[sprite runAction:[TransformTextureRect actionWithDuration:1 toRect:CGRectMake(25,25,50,50)]];

This does something similar to the above example, only it eases in and out of the action as well.

[sprite runAction:[EaseExponentialInOut actionWithAction:[TransformTextureRect actionWithDuration:2 toRect:CGRectMake(480,0,480,320)]]];
신고
블로그 이미지

*별빛*

UI/UX관련 개발이슈 및 방법을 나누는 곳입니다. Flex/AIR, Silverlight등 pc 기반 iPhone, Android등 smartphone 기반

You might have noticed in our recent videos that our game features the ability to load assets from either the device or the web depending on which menu item you select from the main menu.

Early on in the development of our game, we realized how valuable it would be to be able to load image assets from the web instead of from the app bundle. This led us to creating a Resource Manager class that we use to load all of our image assets.

ResourceManager is a singleton class that can be toggled between web mode and local mode. Since it’s a singleton, it is intended to stick around in memory for the duration of the app’s runtime, so we added a cleanup method which can be called to dump everything it is responsible for allocating from time to time. We run the cleanup method after every level.

So far it supports getting images in 3 ways: as a UIImage, as a CGImageRef, or as a cocos2d Texture2D. It is by no means a finished product. We are thinking of adding support for sounds as well. And if you see anything glaringly obvious that can be added or improved, I would love to hear it.

Enough talk, let’s see the code

ResourceManager.h

#import <Foundation/Foundation.h>
#import "cocos2d.h"
 
@interface ResourceManager : NSObject {
	BOOL web;
	NSString * urlPrefix;
	NSMutableArray * images;
	NSMutableArray * textures;
}
 
@property (readwrite) BOOL web;
@property (readwrite,assign) NSString * urlPrefix;
 
+(ResourceManager*)sharedResourceManager;
 
-(void)cleanup;
 
-(CGImageRef)getCGImageRef:(NSString*)fileName;
-(UIImage*)getUIImage:(NSString*)fileName;
-(Texture2D*)getTexture2D:(NSString*)fileName;
 
-(CGImageRef)getCGImageRefFromWeb:(NSString*)url;
-(UIImage*)getUIImageFromWeb:(NSString*)url;
-(Texture2D*)getTexture2DFromWeb:(NSString*)url;
 
-(CGImageRef)getCGImageRefFromAppBundle:(NSString*)fileName;
-(UIImage*)getUIImageFromAppBundle:(NSString*)fileName;
-(Texture2D*)getTexture2DFromAppBundle:(NSString*)fileName;
@end

ResourceManager.m

#import "ResourceManager.h"
 
 
@implementation ResourceManager
 
@synthesize web;
@synthesize urlPrefix;
 
static ResourceManager* _sharedResourceManager = nil;
 
+(ResourceManager*)sharedResourceManager
{
	@synchronized([ResourceManager class])
	{
		if (!_sharedResourceManager)
			[[self alloc] init];
 
		return _sharedResourceManager;
	}
 
	return nil;
}
 
+(id)alloc
{
	@synchronized([ResourceManager class])
	{
		NSAssert(_sharedResourceManager == nil, @"Attempted to allocate a second instance of a singleton.");
		_sharedResourceManager = [super alloc];
		return _sharedResourceManager;
	}
 
	return nil;
}
 
-(id)autorelease {
    return self;
}
 
-(id)init {
	images = [[NSMutableArray alloc] init];
	textures = [[NSMutableArray alloc] init];
	web = NO;
 
	return [super init];
}
 
-(void)cleanup {
	[images removeAllObjects];	
	[textures removeAllObjects];
}
 
-(CGImageRef)getCGImageRef:(NSString*)fileName {
	UIImage * img = [self getUIImage:fileName];
	if (img)
		return [img CGImage];
 
	return nil;
}
 
-(UIImage*)getUIImage:(NSString*)fileName {
	if (web) {
		return [self getUIImageFromWeb:[NSString stringWithFormat:@"%@%@", urlPrefix, fileName]];
	}
	else {
		return [self getUIImageFromAppBundle:fileName];
	}
 
	return nil;
}
 
-(Texture2D*)getTexture2D:(NSString*)fileName {
	UIImage * img = [self getUIImage:fileName];
	if (img)
		return [[Texture2D alloc] initWithImage:img];
 
	return nil;
}
 
-(UIImage*)getUIImageFromWeb:(NSString*)url {
	UIImage * img = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:url]]];
	[images addObject:img];
	return img;
}
 
-(CGImageRef)getCGImageRefFromWeb:(NSString*)url {
	UIImage * img = [self getUIImageFromWeb:url];
	if (img)
		return [img CGImage];
 
	return nil;
}
 
-(Texture2D*)getTexture2DFromWeb:(NSString*)url {
	UIImage * img = [self getUIImageFromWeb:url];
	if (img) {
		Texture2D * tex = [[Texture2D alloc] initWithImage:img];
		[textures addObject:tex];
		return tex;
	}
 
	return nil;
}
 
-(UIImage*)getUIImageFromAppBundle:(NSString*)fileName {
	UIImage * img = [UIImage imageNamed:fileName];
	[images addObject:img];
	return img;
}
 
-(CGImageRef)getCGImageRefFromAppBundle:(NSString*)fileName {
	UIImage * img = [self getUIImageFromAppBundle:fileName];
	if (img)
		return [img CGImage];
 
	return nil;
}
 
-(Texture2D*)getTexture2DFromAppBundle:(NSString*)fileName {
	UIImage * img = [self getUIImageFromAppBundle:fileName];
	if (img) {
		Texture2D * tex = [[Texture2D alloc] initWithImage:img];
		[textures addObject:tex];
		return tex;
	}
 
	return nil;
}
 
@end

Example Usage

Since it’s a singleton, there’s no need to instantiate it. Just include the header file and call its sharedResourceManager method. By default, it is set to load assets from the application bundle.

How to load a file into a UIImage:

UIImage * img = [[ResourceManager sharedResourceManager] getUIImage:@"menu.png"];

How to load a file into a cocos2d Sprite:

Sprite * bg = [Sprite spriteWithCGImage:[[ResourceManager sharedResourceManager] getCGImageRef:@"background.jpg"]];

How to load a file into a cocos2d AtlasSpriteManager:

AtlasSpriteManager * mgr = [AtlasSpriteManager spriteManagerWithTexture:[[ResourceManager sharedResourceManager] getTexture2D:@"character.png"] capacity:1];

As I mentioned above, we like to be able to switch between loading the same assets from the device and from the web at run-time. We do this by setting the ResourceManager to be in web mode and giving it the URL of a folder where our assets are stored online:

[ResourceManager sharedResourceManager].web = YES;
[ResourceManager sharedResourceManager].urlPrefix = @"http://example.com/assets/";

If you run those 2 lines before running any of the previous examples, the ResourceManager will look online for the asset you asked for instead of on the device.

As well, there are methods included that force the class to load from the web or device, regardless of which mode it is in.

How to force it to load a UIImage from the web:

UIImage * img = [[ResourceManager sharedResourceManager] getUIImageFromWeb:@"http://example.com/assets/menu.png"];

Finally, to clean up any resources already loaded:

[[ResourceManager sharedResourceManager] cleanup];
신고
블로그 이미지

*별빛*

UI/UX관련 개발이슈 및 방법을 나누는 곳입니다. Flex/AIR, Silverlight등 pc 기반 iPhone, Android등 smartphone 기반

티스토리 툴바