<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>seiji blog &#187; Objective-C</title>
	<atom:link href="http://blog.seiji.me/tag/objective-c/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.seiji.me</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Wed, 03 Mar 2010 14:50:33 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Making a CGRect</title>
		<link>http://blog.seiji.me/421.html</link>
		<comments>http://blog.seiji.me/421.html#comments</comments>
		<pubDate>Fri, 26 Dec 2008 12:45:09 +0000</pubDate>
		<dc:creator>seiji</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[CGRect]]></category>

		<guid isPermaLink="false">http://blog.seiji.me/?p=421</guid>
		<description><![CDATA[
	

	
CGRectには様々な作成方法があります。それをまとめておきます。

下のようなCGRectを作成したいと思います。

出力
HelloWorld[52159:20b] {{0, 0}, {320, 480}}



作成方法1
CGRect rect = CGRectMake(0, 0, 320, 480);

作成方法2
CGRect rect = {{0,0}, {320, 480}};

作成方法3
CGSize size = CGSizeMake(320, 480);
CGRect rect = {{0,0}, size};

作成方法4
CGPoint point = CGPointMake(0, 0);
CGSize size = CGSizeMake(320, 480);
CGRect rect = {point, size};

作成方法5
CGSize size = CGSizeMake(320, 480);
CGRect rect = {{0}, size};

作成方法6
CGSize size = CGSizeMake(320, 480);
CGRect rect = {{}, size};

他にもいろいろあるかとは思いますが、構造で定義できるのは便利ですね。
]]></description>
			<content:encoded><![CDATA[<p>
	<br />
<img src="http://blog.seiji.me/wp-content/uploads/2008/12/making-cgrect1.png" alt="Making CGRect.png" border="0" width="210" height="181" /><br />
	</p>
<p>CGRectには様々な作成方法があります。それをまとめておきます。
</p>
<p>下のようなCGRectを作成したいと思います。
</p>
<h4>出力</h4>
<pre class="console"><code>HelloWorld[52159:20b] {{0, 0}, {320, 480}}
</code></pre>
<p></p>
<p><span id="more-421"></span><br />
<h4>作成方法1</h4>
<pre><code>CGRect rect = CGRectMake(0, 0, 320, 480);
</code></pre>
<h4>作成方法2</h4>
<pre><code>CGRect rect = {{0,0}, {320, 480}};
</code></pre>
<h4>作成方法3</h4>
<pre><code>CGSize size = CGSizeMake(320, 480);
CGRect rect = {{0,0}, size};
</code></pre>
<h4>作成方法4</h4>
<pre><code>CGPoint point = CGPointMake(0, 0);
CGSize size = CGSizeMake(320, 480);
CGRect rect = {point, size};
</code></pre>
<h4>作成方法5</h4>
<pre><code>CGSize size = CGSizeMake(320, 480);
CGRect rect = {{0}, size};
</code></pre>
<h4>作成方法6</h4>
<pre><code>CGSize size = CGSizeMake(320, 480);
CGRect rect = {{}, size};
</code></pre>
<p>他にもいろいろあるかとは思いますが、構造で定義できるのは便利ですね。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.seiji.me/421.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>^NSStringFrom.* functions</title>
		<link>http://blog.seiji.me/405.html</link>
		<comments>http://blog.seiji.me/405.html#comments</comments>
		<pubDate>Thu, 25 Dec 2008 10:54:55 +0000</pubDate>
		<dc:creator>seiji</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[NSStringFromCGRect]]></category>

		<guid isPermaLink="false">http://blog.seiji.me/?p=405</guid>
		<description><![CDATA[NSStringFromから続くFunctionは非常に便利です。特にCGRect, CGPoint, CGSizeを出力したい場合も展開して出力するのは面倒です。

	

	

 NSStringFromCGRect, NSStringFromClassを使い次のように出力してみます。
// CGRect
NSLog(@"%@", NSStringFromCGRect([self.view bounds]));
// Class
NSLog(@"%@", NSStringFromClass([[[UIApplication sharedApplication] delegate] class]));

出力
2008-12-25 19:44:29.628 HelloWorld[39711:20b] {{0, 0}, {320, 460}}
2008-12-25 19:44:29.629 HelloWorld[39711:20b] HelloWorldAppDelegate
]]></description>
			<content:encoded><![CDATA[<p>NSStringFromから続くFunctionは非常に便利です。特にCGRect, CGPoint, CGSizeを出力したい場合も展開して出力するのは面倒です。</p>
<p>
	<br />
<img src="http://blog.seiji.me/wp-content/uploads/2008/12/uikit-function-reference.jpg" alt="UIKit Function Reference — デベロッパドキュメント.jpg" border="0" width="224" height="193" /><br />
	</p>
<p><span id="more-405"></span>
<p> NSStringFromCGRect, NSStringFromClassを使い次のように出力してみます。</p>
<pre><code>// CGRect
NSLog(@"%@", NSStringFromCGRect([self.view bounds]));
// Class
NSLog(@"%@", NSStringFromClass([[[UIApplication sharedApplication] delegate] class]));
</code></pre>
<h4>出力</h4>
<pre class="console"><code>2008-12-25 19:44:29.628 HelloWorld[39711:20b] {{0, 0}, {320, 460}}
2008-12-25 19:44:29.629 HelloWorld[39711:20b] HelloWorldAppDelegate</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.seiji.me/405.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OCUnitのTestCase作成</title>
		<link>http://blog.seiji.me/389.html</link>
		<comments>http://blog.seiji.me/389.html#comments</comments>
		<pubDate>Thu, 18 Dec 2008 07:06:49 +0000</pubDate>
		<dc:creator>seiji</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[OCUnit]]></category>

		<guid isPermaLink="false">http://blog.seiji.me/?p=389</guid>
		<description><![CDATA[OCUnitとはObjective-C用のUnitTest用Frameworkです。

今回はこのOCUnitを試してみたいと思います。-setUp, -tearDownなどJUnitなどのxUnitを使用した経験がある方なら非常に親しみやすいと言えます。

以下は全てX-Code上で行います。
UnitTest対象
UnitTestの対象として例えば以下のようなクラスを作成します。
Person.h
#import 

@interface Person : NSObject {
	NSString *displayName;
}
@property (copy) NSString *displayName;

- (id)initWithName:(NSString *)displayName;

@end

Person.m
#import "Person.h"

@implementation Person

@synthesize displayName;

- (id)initWithName:(NSString *)aName {
	if ((self = [super init])!= nil) {
		self.displayName = aName;
	}
	return self;
}

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

@end
新規ターゲットの作成

ターゲットを選択し、新規ターゲットの作成を選択
Cocoa &#62;&#62; Unit Test Bundleを選択し、次へ
名前を例えばUnitTestsにして完了

ターゲットUnitTestsの情報の変更

ビルド &#62;&#62; リンク &#62;&#62;他のリンクフラグのCocoaをFoundationに変更する
ビルド &#62;&#62; ユーザー定義 で以下の項目以外を削除する。

GCC_C_LANGUAGE_STANDARD
GCC_WARN_ABOUT_RETURN_TYPE
GCC_WARN_UNUSED_VARIABLE



Person.mのターゲット修正

Person.mのターゲットの中にUnitTestsを追加する

新規TestCaseの作成

ファイル &#62;&#038;gt 新規ファイルを選択
Cocoa Touch Classes &#62;&#62; NSObject subclassを選択し、次へ
名前を例えばPersonTest、ターゲットをUnitTestsにして完了

TestCaseの実装
PersonTest.h
#import 

@class Person;
@interface PersonTest : SenTestCase [...]]]></description>
			<content:encoded><![CDATA[<p>OCUnitとはObjective-C用のUnitTest用Frameworkです。
</p>
<p>今回はこのOCUnitを試してみたいと思います。-setUp, -tearDownなどJUnitなどのxUnitを使用した経験がある方なら非常に親しみやすいと言えます。</p>
<p><span id="more-389"></span>
<p>以下は全てX-Code上で行います。</p>
<h3>UnitTest対象</h3>
<p>UnitTestの対象として例えば以下のようなクラスを作成します。</p>
<h4>Person.h</h4>
<pre><code>#import <foundation/Foundation.h>

@interface Person : NSObject {
	NSString *displayName;
}
@property (copy) NSString *displayName;

- (id)initWithName:(NSString *)displayName;

@end
</code></pre>
<h4>Person.m</h4>
<pre><code>#import "Person.h"

@implementation Person

@synthesize displayName;

- (id)initWithName:(NSString *)aName {
	if ((self = [super init])!= nil) {
		self.displayName = aName;
	}
	return self;
}

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

@end</code></pre>
<h3>新規ターゲットの作成</h3>
<ol>
<li>ターゲットを選択し、新規ターゲットの作成を選択</li>
<li>Cocoa &gt;&gt; Unit Test Bundleを選択し、次へ</li>
<li>名前を例えばUnitTestsにして完了</li>
</ol>
<h3>ターゲットUnitTestsの情報の変更</h3>
<ol>
<li>ビルド &gt;&gt; リンク &gt;&gt;他のリンクフラグのCocoaをFoundationに変更する</li>
<li>ビルド &gt;&gt; ユーザー定義 で以下の項目以外を削除する。
<ul>
<li>GCC_C_LANGUAGE_STANDARD</li>
<li>GCC_WARN_ABOUT_RETURN_TYPE</li>
<li>GCC_WARN_UNUSED_VARIABLE</li>
</ul>
</li>
</ol>
<h3>Person.mのターゲット修正</h3>
<ol>
<li>Person.mのターゲットの中にUnitTestsを追加する</li>
</ol>
<h3>新規TestCaseの作成</h3>
<ol>
<li>ファイル &gt;&#038;gt 新規ファイルを選択</li>
<li>Cocoa Touch Classes &gt;&gt; NSObject subclassを選択し、次へ</li>
<li>名前を例えばPersonTest、ターゲットをUnitTestsにして完了</li>
</ol>
<h3>TestCaseの実装</h3>
<h4>PersonTest.h</h4>
<pre><code>#import <senTestingKit/SenTestingKit.h>

@class Person;
@interface PersonTest : SenTestCase {
	Person *person;
}

@end</code></pre>
<h4>PersonTest.m</h4>
<pre><code>#import "PersonTest.h"
#import "Person.h"

@implementation PersonTest

- (void)setUp {
	person = [[Person alloc] init];
}

- (void)testCreatePerson {
	STAssertNotNil(person, @"Couldn't create Person");
}

- (void)testSetDisplayName {
    NSString *displayName = @"Seiji";
    person.displayName = displayName;
    STAssertEqualObjects(displayName, person.displayName, @"Couldn't set person.displayName");
}

- (void)tearDown {
	[person release];
}

@end</code></pre>
<h3>TestCaseの実行</h3>
<p>UnitTestsを選択し、Buildを行うことでTestCaseが実行される。想定結果が違うものであればBuildの時点でErrorが表示されることになります。</p>
<h6>References</h6>
<ul>
<li><a href="http://developer.apple.com/tools/unittest.html">Test Driving Your Code with OCUnit</a></li>
<li><a href="http://www.stanford.edu/class/cs193p/cgi-bin/index.php">Lecture 19 &#8211; Unit Testing, Objective-C Runtime Fun and Localization</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.seiji.me/389.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>NSInvocationOperation,delegatePattern-CS193P</title>
		<link>http://blog.seiji.me/387.html</link>
		<comments>http://blog.seiji.me/387.html#comments</comments>
		<pubDate>Sat, 13 Dec 2008 07:25:44 +0000</pubDate>
		<dc:creator>seiji</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[CS193P]]></category>
		<category><![CDATA[delegatePattern]]></category>
		<category><![CDATA[NSInvocationOperation]]></category>
		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://blog.seiji.me/?p=387</guid>
		<description><![CDATA[NSInvocationOperation,delegatePattern
Lecture12迄の内容を基に&#8221;Presence&#8221;アプリケーションを拡張していきます。
AssignmentPresence3になります。


	
	
		iPhone Application Programming
	



今迄、作成したソースはhttp://public.me.com/seijit/iPhone/CS193Pから

今回の目標
前回迄は全てMainThreadで通信を行っていました。その為、待ち時間が長く感じられ、ストレスを受けていたのではないかと思います。今回はそのストレスを軽減する為に別Threadで通信を行い、最後にMainThreadの処理を返すように実装を行います。アプリケーションとしては下の図のように自分のStatusをUpdateする画面を用意し、そこからSendできるようにします。



今回は全てを記述するのは大変なので、要点を絞って記載します。

NSInvocationOperationの作成
ViewがLoadされる際にSelector(synchronousLoadsTwitterUsers)を指定してNSInvocationOperationを作成し、それをNSInvocationOperationQueueにAddします。その中で通信部分の処理を行っています。
また、作成時に指定したSelector内部ではSelector(didFinishLoadingTwitterUsersWithResults)を指定してMainThreadに返しています。

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
	if ([myData count] == 0) {
		[self showLoadingIndicators];
		[self beginLoadingTwitterUsers];
	}
}
- (void)beginLoadingTwitterUsers {
	[myData removeAllObjects];

	NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(synchronousLoadsTwitterUsers) object:nil];
	[operationQueue addOperation:operation];
	[operation release];
}
- (void)synchronousLoadsTwitterUsers {
	NSBundle *bundle = [NSBundle mainBundle];
	NSArray *twitterUsers = [NSArray arrayWithContentsOfFile:[bundle pathForResource:@"TwitterUsers" ofType:@"plist"]];

	for (NSString *userName in twitterUsers){
		Person *person = [[Person alloc] initWithPersonName:userName];
		if (person)
			[myData addObject:person];
		[person release];
	}
	[self performSelectorOnMainThread:@selector(didFinishLoadingTwitterUsersWithResults) withObject:nil [...]]]></description>
			<content:encoded><![CDATA[<h3>NSInvocationOperation,delegatePattern</h3>
<p>Lecture12迄の内容を基に&#8221;Presence&#8221;アプリケーションを拡張していきます。<br />
AssignmentPresence3になります。<br />
<br />
<img src="http://blog.seiji.me/wp-content/uploads/2008/11/cs193p-cocoa-programming-announcements.jpg" alt="CS193P - Cocoa Programming | Announcements.jpg" border="0" width="430" height="89" /><br />
	<br />
	<q><br />
		<cite><a href="http://www.stanford.edu/class/cs193p/cgi-bin/index.php">iPhone Application Programming</a></cite><br />
	</q>
</p>
<p><span id="more-387"></span>
<p>
今迄、作成したソースは<a href="http://public.me.com/seijit/iPhone/CS193P">http://public.me.com/seijit/iPhone/CS193P</a>から
</p>
<h3>今回の目標</h3>
<p>前回迄は全てMainThreadで通信を行っていました。その為、待ち時間が長く感じられ、ストレスを受けていたのではないかと思います。今回はそのストレスを軽減する為に別Threadで通信を行い、最後にMainThreadの処理を返すように実装を行います。アプリケーションとしては下の図のように自分のStatusをUpdateする画面を用意し、そこからSendできるようにします。</p>
<p><img src="http://blog.seiji.me/wp-content/uploads/2008/12/presence-part3-1-1.jpg" alt="Presence-Part3-1-1.jpg" border="0" width="400" />
</p>
<p>
今回は全てを記述するのは大変なので、要点を絞って記載します。
</p>
<h3><img src="http://blog.seiji.me/wp-content/uploads/2008/11/xcode.png" alt="picture.png" border="0" width="30" height="30" />NSInvocationOperationの作成</h3>
<p>ViewがLoadされる際にSelector(synchronousLoadsTwitterUsers)を指定してNSInvocationOperationを作成し、それをNSInvocationOperationQueueにAddします。その中で通信部分の処理を行っています。</p>
<p>また、作成時に指定したSelector内部ではSelector(didFinishLoadingTwitterUsersWithResults)を指定してMainThreadに返しています。
</p>
<pre><code>- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
	if ([myData count] == 0) {
		[self showLoadingIndicators];
		[self beginLoadingTwitterUsers];
	}
}
- (void)beginLoadingTwitterUsers {
	[myData removeAllObjects];

	NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(synchronousLoadsTwitterUsers) object:nil];
	[operationQueue addOperation:operation];
	[operation release];
}
- (void)synchronousLoadsTwitterUsers {
	NSBundle *bundle = [NSBundle mainBundle];
	NSArray *twitterUsers = [NSArray arrayWithContentsOfFile:[bundle pathForResource:@"TwitterUsers" ofType:@"plist"]];

	for (NSString *userName in twitterUsers){
		Person *person = [[Person alloc] initWithPersonName:userName];
		if (person)
			[myData addObject:person];
		[person release];
	}
	[self performSelectorOnMainThread:@selector(didFinishLoadingTwitterUsersWithResults) withObject:nil waitUntilDone:NO];
}
- (void)didFinishLoadingTwitterUsersWithResults {
	[self hideLoadingIndicators];
	[self.tableView reloadData];
    [self.tableView flashScrollIndicators];
}</code></pre>
<h3><img src="http://blog.seiji.me/wp-content/uploads/2008/11/xcode.png" alt="picture.png" border="0" width="30" height="30" />delegete Patternの使用</h3>
<p>NavigationItemのRightBarButtonItemをクリックするとStatusComposeする画面をModallyに出すようにしています。</p>
<pre><code>
- (void)viewDidLoad {
    [super viewDidLoad];
	UIBarButtonItem *addButton = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemCompose target:self action:@selector(presentModally) ];
	self.navigationItem.rightBarButtonItem = addButton;
	[addButton release];
}
- (void)presentModally {
	StatusComposeViewController *statusController = [[StatusComposeViewController alloc]initWithNibName:@"StatusCompose" bundle:nil];
	statusController.delegate = self;
	[self presentModalViewController:statusController animated:YES];
	[statusController release];
}
</code></pre>
<p>この場合、このActionは今回で言うとPersonListViewControllerに実装するわけです。ではこの画面を消すActionはどこに書けばいいのでしょうか？</p>
<p>単純にStatusComposeViewControllerに下のように実装しても消すことはできます。</p>
<pre><code>
[self.navigationController dismissModalViewControllerAnimated:YES];
</code></pre>
<p>しかし、PresentとDismissするのは同じContorollerからするのが望ましいと言われています。別の操作を行うのにもこの方が操作をしやすいでしょう。</p>
<p>ここでdelegatePatternを使用します。</p>
<h4>Protocolの作成</h4>
<pre><code>@class StatusComposeViewController;

@protocol StatusComposeViewDelegate <nsobject>
@optional
- (void)statusComposeViewControllerDidFinish:(StatusComposeViewController *)controller;
- (void)statusComposeViewControllerDidCancel:(StatusComposeViewController *)controller;
@end</code></pre>
<p>今回のdelegateの為のProtocolを作成します。</p>
<h4>Propertyの追加</h4>
<pre><code>
@interface StatusComposeViewController : UIViewController <uitextFieldDelegate> {
	// 略
	id <statusComposeViewDelegate> delegate;
}
	// 略
@property (nonatomic, assign) id <statusComposeViewDelegate> delegate;
	// 略
@end
</code></pre>
<p>StatusComposeViewControllerにStatusComposeViewDelegateを満たしたid型の属性を追加します。</p>
<h4>StatusComposeViewDelegateの実装</h4>
<p> StatusComposeViewDelegateのメソッド(statusComposeViewControllerDidFinish:, statusComposeViewControllerDidCancel: )を実装します。</p>
<p>これでStatusComposeViewController側でStatusComposeViewDelegateで実装されたPersonListViewControllerのメソッド(i.e [self.delegate statusComposeViewControllerDidFinish:])を呼べばよいわけです。</p>
<p>これでAssignmentPresence3を終了としたいと思います。</p>
<p>今回作成したソースは<a href="http://public.me.com/seijit/iPhone/CS193P/Lecture12">http://public.me.com/seijit/iPhone/CS193P/Lecture12</a>のPresence5.tar.gzです</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.seiji.me/387.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>UITableViewDelegate, UITableViewDataSource-CS193P</title>
		<link>http://blog.seiji.me/384.html</link>
		<comments>http://blog.seiji.me/384.html#comments</comments>
		<pubDate>Thu, 11 Dec 2008 04:43:39 +0000</pubDate>
		<dc:creator>seiji</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[CS193P]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[UITableViewDataSource]]></category>
		<category><![CDATA[UITableViewDelegate]]></category>

		<guid isPermaLink="false">http://blog.seiji.me/?p=384</guid>
		<description><![CDATA[UITableViewDelegate, UITableViewDataSource
前回plistの読込み、UITableViewCellAccessory-CS193Pの続きになります。
AssignmentPresence2の後半にあたります。


	
	
		iPhone Application Programming
	



今迄、作成したソースはhttp://public.me.com/seijit/iPhone/CS193Pから

今回の目標
PersonDetailViewControllerを修正し、下のアプリケーションを完成させるのが目的です。List,Detail共にTableViewを使用しています。ListがUITableViewStylePlain, Detailの方がUITableViewStyleGroupedとStyleを変えて表示をしています。


PersonDetail.xibの変更
PersonDetail.xibをWクリックし、InterfaceBuilderを起動します。ここではViewを大幅に変更します。
View上にUITableViewのみを配置し、AttributesInspectorでTableViewのStyleを&#8221;Grouped&#8221;にします。


ConnectionsInspectorでPersonDetailViewControllerのviewをTableViewに、TableViewのdataSource,delegateをPersonDetailViewControllerに接続します。



PersonList.xibでは同じTableViewを使っているのにdataSource,delegateの接続は行いませんでした。この違いはPersonLisrViewControllerはTableViewControllerのSubClassに対して、PersonDetailViewControllerはUIViewControllerのSubClassだからです。
PersonDetailViewControllerの修正

PersonDetailViewControllerはPersonListViewControllerとは違った形でTableViewを表示させます。ProtocolであるUITableViewDelegate, UITableViewDataSourceの実装を行います。
PersonDetailViewController
PersonDetailViewController.h
#import &#60;UIKit/UIKit.h&#62;

@class Person;
@interface PersonDetailViewController : UIViewController &#60;UITableViewDelegate, UITableViewDataSource&#62;  {
	Person* person;
}
@property (nonatomic, assign) Person* person;

@end


ProtocolであるUITableViewDelegate, UITableViewDataSourceの宣言をしています。
PersonDetailViewController.m
#import "PersonDetailViewController.h"
#import "Person.h"
#import "PersonText.h"

@implementation PersonDetailViewController
@synthesize person;

// 略
@end


UITableViewDelegate, UITableViewDataSourceのメソッドを実装します。

- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
	return [person.textArray count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
	static NSString *CellIdentifier = @"MyIdentifer";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    [...]]]></description>
			<content:encoded><![CDATA[<h3>UITableViewDelegate, UITableViewDataSource</h3>
<p>前回<a href="http://blog.seiji.me/374.html">plistの読込み、UITableViewCellAccessory-CS193P</a>の続きになります。<br />
AssignmentPresence2の後半にあたります。<br />
<br />
<img src="http://blog.seiji.me/wp-content/uploads/2008/11/cs193p-cocoa-programming-announcements.jpg" alt="CS193P - Cocoa Programming | Announcements.jpg" border="0" width="430" height="89" /><br />
	<br />
	<q><br />
		<cite><a href="http://www.stanford.edu/class/cs193p/cgi-bin/index.php">iPhone Application Programming</a></cite><br />
	</q>
</p>
<p><span id="more-384"></span>
<p>
今迄、作成したソースは<a href="http://public.me.com/seijit/iPhone/CS193P">http://public.me.com/seijit/iPhone/CS193P</a>から
</p>
<h3>今回の目標</h3>
<p>PersonDetailViewControllerを修正し、下のアプリケーションを完成させるのが目的です。List,Detail共にTableViewを使用しています。ListがUITableViewStylePlain, Detailの方がUITableViewStyleGroupedとStyleを変えて表示をしています。</p>
<p><img src="http://blog.seiji.me/wp-content/uploads/2008/12/app-11.png" alt="app-1.png" border="0" width="400" height="391" />
</p>
<h3><img src="http://blog.seiji.me/wp-content/uploads/2008/11/picture.png" alt="picture.png" border="0" width="30" height="30" />PersonDetail.xibの変更</h3>
<p>PersonDetail.xibをWクリックし、InterfaceBuilderを起動します。ここではViewを大幅に変更します。</p>
<p>View上にUITableViewのみを配置し、AttributesInspectorでTableViewのStyleを&#8221;Grouped&#8221;にします。</p>
<p><a href="http://blog.seiji.me/wp-content/uploads/2008/12/1-2.png"><img src="http://blog.seiji.me/wp-content/uploads/2008/12/1-2.png" alt="ピクチャ 1-2.png" border="0" width="400" /></a>
</p>
<p>ConnectionsInspectorでPersonDetailViewControllerのviewをTableViewに、TableViewのdataSource,delegateをPersonDetailViewControllerに接続します。</p>
<p><img src="http://blog.seiji.me/wp-content/uploads/2008/12/table-view-connections-1.png" alt="Table View Connections-1.png" border="0" width="316" height="186" />
</p>
<p>
PersonList.xibでは同じTableViewを使っているのにdataSource,delegateの接続は行いませんでした。この違いはPersonLisrViewControllerはTableViewControllerのSubClassに対して、PersonDetailViewControllerはUIViewControllerのSubClassだからです。</p>
<h3><img src="http://blog.seiji.me/wp-content/uploads/2008/11/xcode.png" alt="xcode.png" border="0" width="30" height="30" />PersonDetailViewControllerの修正</h3>
<p>
PersonDetailViewControllerはPersonListViewControllerとは違った形でTableViewを表示させます。ProtocolであるUITableViewDelegate, UITableViewDataSourceの実装を行います。</p>
<h4>PersonDetailViewController</h4>
<h5>PersonDetailViewController.h</h5>
<pre><code>#import &lt;UIKit/UIKit.h&gt;

@class Person;
@interface PersonDetailViewController : UIViewController &lt;UITableViewDelegate, UITableViewDataSource&gt;  {
	Person* person;
}
@property (nonatomic, assign) Person* person;

@end
</code></pre>
<p>
ProtocolであるUITableViewDelegate, UITableViewDataSourceの宣言をしています。</p>
<h5>PersonDetailViewController.m</h5>
<pre><code>#import "PersonDetailViewController.h"
#import "Person.h"
#import "PersonText.h"

@implementation PersonDetailViewController
@synthesize person;

// 略
@end
</code></pre>
<p>
UITableViewDelegate, UITableViewDataSourceのメソッドを実装します。
</p>
<pre><code>- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
	return [person.textArray count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
	static NSString *CellIdentifier = @"MyIdentifer";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    }
    // Set up the cell...
	PersonText *personText = [person.textArray objectAtIndex:indexPath.row];
	UILabel *textField = [[UILabel alloc] initWithFrame:CGRectMake(20, 6, personText.size.width, personText.size.height)];
	[textField setText:[NSString stringWithCString:[personText.textString UTF8String] encoding:NSUTF8StringEncoding]];
	[textField setBackgroundColor:[UIColor clearColor]];
	[textField setLineBreakMode:UILineBreakModeWordWrap];
	[textField setFont:personText.font];
	[textField setHighlightedTextColor:[UIColor whiteColor]];
	[textField setNumberOfLines:0];
	[cell addSubview:textField];
	[textField release];

    return cell;
}</code></pre>
<p>行の数とUITableViewCellの中身の表示を行うメソッドです。UILabelを作成し、UITableViewCellのSubViewとして追加しています。</p>
<pre><code>
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    // Return the displayed title for the specified section.
    return @"Statuses";
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
	PersonText *personText = [person.textArray objectAtIndex:indexPath.row];
	int padding = 10;
	return personText.size.height + padding;
}
</code></pre>
<p>Sectionのヘッダ名を返すメソッドと、各UITableViewCellの高さを返すメソッドです。ここで動的にUITabelViewCellの高さを変化させています。</p>
<h4>PersonListViewController</h4>
<p>最後にPersonListのUITableViewCellをクリックした際のメソッドを変更しておきます。ここでPersonDetailViewControllerを作成し、UINavigationContollerのStackに追加しています。</p>
<h5>PersonListViewController.m</h5>
<pre><code>- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // Navigation logic may go here. Create and push another view controller.
	PersonDetailViewController *detailViewController = [[PersonDetailViewController alloc] initWithNibName:@"PersonDetail" bundle:nil];
	int personIndex = [indexPath indexAtPosition: [indexPath length] - 1];
	detailViewController.person = [myData objectAtIndex:personIndex];
	[self.navigationController pushViewController:detailViewController animated:YES];
	[detailViewController release];
}</code></pre>
<p>これでAssignmentPresence2ができました。</p>
<p>今回作成したソースは<a href="http://public.me.com/seijit/iPhone/CS193P/Lecture9">http://public.me.com/seijit/iPhone/CS193P/Lecture9</a>のPresence4.tar.gzです。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.seiji.me/384.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>plistの読込み、UITableViewCellAccessory-CS193P</title>
		<link>http://blog.seiji.me/374.html</link>
		<comments>http://blog.seiji.me/374.html#comments</comments>
		<pubDate>Wed, 10 Dec 2008 18:47:25 +0000</pubDate>
		<dc:creator>seiji</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[CS193P]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[plist]]></category>
		<category><![CDATA[UITableViewCellAccessory]]></category>

		<guid isPermaLink="false">http://blog.seiji.me/?p=374</guid>
		<description><![CDATA[plistの読込み、UITableViewCellAccessory
Lecture9迄の内容を基に&#8221;Presence&#8221;アプリケーションを拡張していきます。
AssignmentPresence2の前半になります。


	
	
		iPhone Application Programming
	



今迄、作成したソースはhttp://public.me.com/seijit/iPhone/CS193Pから

今回の目標
前回のPersonListViewControllerを修正し、下のアプリケーションの内、左側を表示できるようになるのが目的です。

Performanceは今は考えてなくてよいとのことなので、Performanceは一切考慮していません。
 前準備
プロジェクトへの追加
Presence2Files.zipに含まれていますTwitterAPI部分のソース、TwitterUsers.plistを追加します。TwitterUsers.plistは好きなUserに変更します。


TwitterHelperの修正

TwitterAPIはデフォルトで20件を返します。そんなに必要ないので5件にします。また、encodingが指定されてないので、指定します。その結果、下のようになります。

TwitterHelper.m
+ (NSArray *)fetchTimelineForUsername:(NSString *)username
{
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://twitter.com/statuses/user_timeline/%@.json?count=5", username]];
    NSString *string = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
    return [string JSONValue];
}

 Modelの作成

起動時にTwiiterにアクセスし、必要な情報をメモリ上に格納します。その為のModelを作成します。例えば、Userの情報を格納するPersonクラス、Userのつぶやきを格納するPersonTextクラスを作成します。

Personクラス
Person.h
import &#60;Foundation/Foundation.h&#62;

@interface Person : NSObject {
	NSString *name;
	NSString *screenName;
	NSString *profileImageURL;
	NSMutableArray *textArray;
}
@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSString *screenName;
@property (nonatomic, retain) NSString *profileImageURL;
@property [...]]]></description>
			<content:encoded><![CDATA[<h3>plistの読込み、UITableViewCellAccessory</h3>
<p>Lecture9迄の内容を基に&#8221;Presence&#8221;アプリケーションを拡張していきます。<br />
AssignmentPresence2の前半になります。<br />
<br />
<img src="http://blog.seiji.me/wp-content/uploads/2008/11/cs193p-cocoa-programming-announcements.jpg" alt="CS193P - Cocoa Programming | Announcements.jpg" border="0" width="430" height="89" /><br />
	<br />
	<q><br />
		<cite><a href="http://www.stanford.edu/class/cs193p/cgi-bin/index.php">iPhone Application Programming</a></cite><br />
	</q>
</p>
<p><span id="more-374"></span>
<p>
今迄、作成したソースは<a href="http://public.me.com/seijit/iPhone/CS193P">http://public.me.com/seijit/iPhone/CS193P</a>から
</p>
<h3>今回の目標</h3>
<p>前回のPersonListViewControllerを修正し、下のアプリケーションの内、左側を表示できるようになるのが目的です。</p>
<p><img src="http://blog.seiji.me/wp-content/uploads/2008/12/app-1.png" alt="app-1.png" border="0" width="400" height="331" /></p>
<p>Performanceは今は考えてなくてよいとのことなので、Performanceは一切考慮していません。</p>
<h3><img src="http://blog.seiji.me/wp-content/uploads/2008/11/xcode.png" alt="xcode.png" border="0" width="30" height="30" /> 前準備</h3>
<h4>プロジェクトへの追加</h4>
<p>Presence2Files.zipに含まれていますTwitterAPI部分のソース、TwitterUsers.plistを追加します。TwitterUsers.plistは好きなUserに変更します。</p>
<p><img src="http://blog.seiji.me/wp-content/uploads/2008/12/init-presence.png" alt="init — Presence.png" border="0" width="268" height="528" />
</p>
<h4>TwitterHelperの修正</h4>
<p>
TwitterAPIはデフォルトで20件を返します。そんなに必要ないので5件にします。また、encodingが指定されてないので、指定します。その結果、下のようになります。
</p>
<h5>TwitterHelper.m</h5>
<pre><code>+ (NSArray *)fetchTimelineForUsername:(NSString *)username
{
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://twitter.com/statuses/user_timeline/%@.json?count=5", username]];
    NSString *string = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
    return [string JSONValue];
}
</code></pre>
<h3><img src="http://blog.seiji.me/wp-content/uploads/2008/11/xcode.png" alt="xcode.png" border="0" width="30" height="30" /> Modelの作成</h3>
<p>
起動時にTwiiterにアクセスし、必要な情報をメモリ上に格納します。その為のModelを作成します。例えば、Userの情報を格納するPersonクラス、Userのつぶやきを格納するPersonTextクラスを作成します。
</p>
<h4>Personクラス</h4>
<h5>Person.h</h5>
<pre><code>import &lt;Foundation/Foundation.h&gt;

@interface Person : NSObject {
	NSString *name;
	NSString *screenName;
	NSString *profileImageURL;
	NSMutableArray *textArray;
}
@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSString *screenName;
@property (nonatomic, retain) NSString *profileImageURL;
@property (nonatomic, retain) NSMutableArray *textArray;

- (id)initWithPersonName:(NSString *)name;
- (id)createPerson:(NSString *)personName;
- (NSString *)description;
- (void)dealloc;

@end
</code></pre>
<h5>Person.m</h5>
<pre><code>#import "Person.h"
#import "PersonText.h"
#import "TwitterHelper.h"

@implementation Person
@synthesize name, screenName, profileImageURL, textArray;

- (id)initWithPersonName:(NSString *)personName {
	if ( (self =[super init])!= nil ) {
		self = [self createPerson:personName];
	}
	return self;
}

- (id)createPerson:(NSString *)personName {
	// name
	self.screenName = personName;
	// Twitter API
	NSArray *array = [TwitterHelper fetchTimelineForUsername:personName];
	if([array count]==0) {
		return nil;
	}
	NSDictionary *user = [[array objectAtIndex:0] objectForKey:@"user"];
	self.profileImageURL = [user objectForKey:@"profile_image_url"];
	self.name = [user objectForKey:@"name"];

	self.textArray = [NSMutableArray array];
	NSDictionary *dic;
	for (dic in array) {
		NSString *text = [dic objectForKey:@"text"];
		if (text) {
			PersonText *personText = [[PersonText alloc] initWithText:text font:[UIFont systemFontOfSize:[UIFont systemFontSize]]];
			[self.textArray addObject:personText];
			[personText release];
		}
	}

	return self;
}
// 略
@end
</code></pre>
<h4>PersonTextクラス</h4>
<h5>PersonText.h</h5>
<pre><code>#import &lt;Foundation/Foundation.h&gt;

@interface PersonText : NSObject
{
	NSString *textString;
	UIFont *font;
	CGSize size;
}
@property (nonatomic, retain)NSString *textString;
@property (nonatomic, retain)UIFont *font;
@property (nonatomic)CGSize size;

- (id)initWithText:(NSString *)text font:(UIFont *)fontObj;
- (void)dealloc;

@end
</code></pre>
<h5>PersonText.m</h5>
<pre><code>#import "PersonText.h"

@implementation PersonText

@synthesize textString;
@synthesize font;
@synthesize size;

- (id)initWithText:(NSString *)txt font:(UIFont *)fontObj;{
	if ((self = [super init])!= nil) {
		self.textString = txt;
		self.font = fontObj;
		CGSize withinSize = CGSizeMake(280, 1000);
		self.size = [textString sizeWithFont:font constrainedToSize:withinSize lineBreakMode:UILineBreakModeWordWrap];
	}
	return self;
}

// 略
@end
</code></pre>
<p>PersonTextの方は初期化の際にwidth280pxをした際に高さを計算する為にサイズを求めています。
</p>
<h3><img src="http://blog.seiji.me/wp-content/uploads/2008/11/xcode.png" alt="xcode.png" border="0" width="30" height="30" /> PersonListViewControllerの修正</h3>
<p>PersonListViewController.mを修正していきます。
</p>
<h4>plistの読込み</h4>
<pre><code>- (void)viewDidLoad {
    [super viewDidLoad];
	// load data
	self.myData = [NSMutableArray array];
	NSBundle *bundle = [NSBundle mainBundle];

	// Load plist
	NSArray *twitterUsers = [NSArray arrayWithContentsOfFile:[bundle pathForResource:@"TwitterUsers" ofType:@"plist"]];
	NSString *userName;

	for (userName in twitterUsers){
		Person *person = [[Person alloc] initWithPersonName:userName];
		if (person)
			[myData addObject:person];
		[person release];
	}
}</code></pre>
<p>viewDidLoadの際にTwitterへアクセスし、Personインスタンスが要素のNSMutableArrayを作成しています。</p>
<h4>List表示</h4>
<pre><code>- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    }

    // Set up the cell...
	int personIndex = [indexPath indexAtPosition: [indexPath length] - 1];
	Person *person = [myData objectAtIndex:personIndex];
	NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:person.profileImageURL]];
	UIImage *image= [UIImage imageWithData:imageData];

	[cell setImage:image];
	[cell setText:person.name];
    return cell;
}</code></pre>
<p>各Personインスタンスを展開しています。ここでも画像へのアクセスを行っています。</p>
<h4>UITableViewCellAccessory</h4>
<pre><code>- (UITableViewCellAccessoryType)tableView:(UITableView *)table accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath {
	return UITableViewCellAccessoryDisclosureIndicator;
	//return UITableViewCellAccessoryDetailDisclosureButton;
	//return UITableViewCellAccessoryCheckmark;
}</code></pre>
<p>最後にCellの右側に表示されるUITableViewCellAccessoryを表示させる為にメソッドを実装しています。</p>
<p>これでplistから読み込んだPersonListが表示されるはずです。</p>
<p>今回作成したソースは<a href="http://public.me.com/seijit/iPhone/CS193P/Lecture9">http://public.me.com/seijit/iPhone/CS193P/Lecture9</a>のPresence3.tar.gzです。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.seiji.me/374.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>navigation stackへの追加-CS193P</title>
		<link>http://blog.seiji.me/363.html</link>
		<comments>http://blog.seiji.me/363.html#comments</comments>
		<pubDate>Sat, 06 Dec 2008 13:44:10 +0000</pubDate>
		<dc:creator>seiji</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[CS193P]]></category>
		<category><![CDATA[navigation stack]]></category>
		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://blog.seiji.me/?p=363</guid>
		<description><![CDATA[navigation stackへの追加
前回UINavigationController, TableViewControllerの作成-CS193Pの続きになります。ViewControllerインスタンスをnavigation stackへと追加するところが中心となります。


	
	
		iPhone Application Programming
	



今迄、作成したソースはhttp://public.me.com/seijit/iPhone/CS193Pから

今回の目標
下の図のようなアプリケーションの内、PersonListを選択し、DetailViewを表示できるようになるのが目標です。（右側の図）

ViewControler,xibの作成
今迄と同じようなことなので、図は省略します。

TemplateからViewControllerのSubClassを選択し、名前を&#8221;PersonDetailViewController&#8221;とします。
TemplateからView XIBを選択し、名前を&#8221;PersonDetail.xib&#8221;とします。

PersonDetailViewControllerの実装
新しく作成したPersonDetailViewControllerを実装します。
PersonDetailViewController.h
#import &#60;UIKit/UIKit.h&#62;

@interface PersonDetailViewController : UIViewController {
	NSDictionary* dict;
	IBOutlet UILabel *name;
	IBOutlet UIImageView *imageView;
}

@property (nonatomic, assign) NSDictionary* dict;
@property (nonatomic, retain) UILabel *name;
@property (nonatomic, retain) UIImageView *imageView;
@end
PersonDetailViewController.m
viewがLoadされた後にNSDictionaryのデータをOutletに展開しています。
#import "PersonDetailViewController.h"

@implementation PersonDetailViewController
@synthesize dict;
@synthesize name;
@synthesize imageView;

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
	[super viewDidLoad];
	[self.navigationItem setTitle:@"Detail"];
	[name setText:[self.dict objectForKey:@"name"]];
	[imageView setImage:[UIImage [...]]]></description>
			<content:encoded><![CDATA[<h3>navigation stackへの追加</h3>
<p>前回<a href="http://blog.seiji.me/354.html">UINavigationController, TableViewControllerの作成-CS193P</a>の続きになります。ViewControllerインスタンスをnavigation stackへと追加するところが中心となります。<br />
<br />
<img src="http://blog.seiji.me/wp-content/uploads/2008/11/cs193p-cocoa-programming-announcements.jpg" alt="CS193P - Cocoa Programming | Announcements.jpg" border="0" width="430" height="89" /><br />
	<br />
	<q><br />
		<cite><a href="http://www.stanford.edu/class/cs193p/cgi-bin/index.php">iPhone Application Programming</a></cite><br />
	</q>
</p>
<p><span id="more-363"></span>
<p>
今迄、作成したソースは<a href="http://public.me.com/seijit/iPhone/CS193P">http://public.me.com/seijit/iPhone/CS193P</a>から
</p>
<h3>今回の目標</h3>
<p>下の図のようなアプリケーションの内、PersonListを選択し、DetailViewを表示できるようになるのが目標です。（右側の図）<br />
<br /><img src="http://blog.seiji.me/wp-content/uploads/2008/12/target-1.png" alt="target-1.png" border="0" width="400" height="337" /></p>
<h3><img src="http://blog.seiji.me/wp-content/uploads/2008/11/xcode.png" alt="xcode.png" border="0" width="30" height="30" />ViewControler,xibの作成</h3>
<p>今迄と同じようなことなので、図は省略します。</p>
<ol>
<li>TemplateからViewControllerのSubClassを選択し、名前を&#8221;PersonDetailViewController&#8221;とします。</li>
<li>TemplateからView XIBを選択し、名前を&#8221;PersonDetail.xib&#8221;とします。</li>
</ol>
<h4>PersonDetailViewControllerの実装</h4>
<p>新しく作成したPersonDetailViewControllerを実装します。</p>
<h5>PersonDetailViewController.h</h5>
<pre><code>#import &lt;UIKit/UIKit.h&gt;

@interface PersonDetailViewController : UIViewController {
	NSDictionary* dict;
	IBOutlet UILabel *name;
	IBOutlet UIImageView *imageView;
}

@property (nonatomic, assign) NSDictionary* dict;
@property (nonatomic, retain) UILabel *name;
@property (nonatomic, retain) UIImageView *imageView;
@end</code></pre>
<h5>PersonDetailViewController.m</h5>
<p>viewがLoadされた後にNSDictionaryのデータをOutletに展開しています。</p>
<pre><code>#import "PersonDetailViewController.h"

@implementation PersonDetailViewController
@synthesize dict;
@synthesize name;
@synthesize imageView;

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
	[super viewDidLoad];
	[self.navigationItem setTitle:@"Detail"];
	[name setText:[self.dict objectForKey:@"name"]];
	[imageView setImage:[UIImage imageWithContentsOfFile:[self.dict objectForKey:@"path"]]];
}

// 間省略
- (void)dealloc {
	[name release];
	[imageView release];
	[super dealloc];
}

@end</code></pre>
<h3><img src="http://blog.seiji.me/wp-content/uploads/2008/11/picture.png" alt="picture.png" border="0" width="30" height="30" />PersonDetailViewControllerとViewとの接続</h3>
<h4>PersonDetail.xib</h4>
<p> PersonDetail.xibをWクリックしInterfaceBuilderを起動します。Viewを例えば下の図のようにします。</p>
<p><img src="http://blog.seiji.me/wp-content/uploads/2008/12/view.png" alt="View.png" border="0" width="200" height="313" /></p>
<p>その後、下の作業を行います。
</p>
<ol>
<li>File&#8217;s Ownerのクラス名をPersonDetailViewControllerとする。</li>
<li>PersonDetailViewControllerの&#8221;view&#8221;をUIViewに接続する。</li>
<li>PersonDetailViewControllerの&#8221;name&#8221;, &#8220;imageView&#8221;をそれぞれUILabel, UIImageViewに接続する。</li>
</ol>
<h3><img src="http://blog.seiji.me/wp-content/uploads/2008/11/xcode.png" alt="xcode.png" border="0" width="30" height="30" />PersonListViewControllerの修正</h3>
<p>今回作成した、PersonDetailViewControllerはこのままではLoadされません。このPresenceアプリケーションに組み込む必要があります。</p>
<h4> PersonListViewController.m </h4>
<pre><code>- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
	// Navigation logic may go here. Create and push another view controller.
	PersonDetailViewController *detailViewController = [[PersonDetailViewController alloc] initWithNibName:@"PersonDetail" bundle:nil];
	int personIndex = [indexPath indexAtPosition: [indexPath length] - 1];
	detailViewController.dict = [myData objectAtIndex:personIndex];
	[self.navigationController pushViewController:detailViewController animated:NO];
	[detailViewController release];
}</code></pre>
<p>これはTableViewのCellを選択した場合にCallされるメソッドです。PersonDetailViewController.hをImportすることも必要です。</p>
<p>これで下のように動作するかと思います。</p>
<p><img src="http://blog.seiji.me/wp-content/uploads/2008/12/target-1.png" alt="target-1.png" border="0" width="400" height="337" /></p>
<p>今回作成したソース<br />
<a href="http://public.me.com/seijit/iPhone/CS193P/Lecture7">http://public.me.com/seijit/iPhone/CS193P/Lecture7</a> <img src='http://blog.seiji.me/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> resence2.tar.gz</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.seiji.me/363.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>UINavigationController, TableViewControllerの作成-CS193P</title>
		<link>http://blog.seiji.me/354.html</link>
		<comments>http://blog.seiji.me/354.html#comments</comments>
		<pubDate>Sat, 06 Dec 2008 12:26:08 +0000</pubDate>
		<dc:creator>seiji</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[CS193P]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[UINavigationController]]></category>

		<guid isPermaLink="false">http://blog.seiji.me/?p=354</guid>
		<description><![CDATA[UINavigationControllerの作成
Lecture7を基に、新しい課題&#8221;Presence&#8221;アプリケーションを作成していきます。実際の内容と脱線するところもありますが、ご了承下さい。


	
	
		iPhone Application Programming
	



今迄、作成したソースはhttp://public.me.com/seijit/iPhone/CS193Pから

今回の目標
下の図のようなアプリケーションの内、PersonListをTableViewで表示できるようになるのが目標です。（左側の図）

新規プロジェクト、ViewControlerの作成
新規プロジェクト作成
Navigation-Based Applicationを選択すれば簡単なのですが、今回はあえてWindow-Based Application	を選択して作成していきます。プロジェクト名は&#8221;Presence&#8221;とします。


TableViewController, xibファイルの作成
ViewControllerとして今回はTableViewControllerを作成します。また、それに対応するxibファイルを作成します。TableViewControllerのサブクラスのファイル名を&#8221;PersonListViewController&#8221;,xibファイル名を&#8221;PersonList.xib&#8221;とします。


PresenceAppDelegateの修正
以前、ViewControllerを追加した同様のやり方で、UINavigationControllerをDelegateクラスに追加します。
PresenceAppDelegate.h
#import 
@interface PresenceAppDelegate : NSObject  {
	UIWindow *window;
	UINavigationController *navController;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UINavigationController *navController;
@end

PresenceAppDelegate.m
#import "PresenceAppDelegate.h"
@implementation PresenceAppDelegate
@synthesize window;
@synthesize navController;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
	// Override point for customization after application launch
	[window addSubview:[navController view]];
	[window makeKeyAndVisible];
}

- (void)dealloc {
	[window release];
	[navController release];
	[super dealloc];
}
@end

UINavigationControllerの配置・接続
MainWindow.xib
MainWindow.xibをWクリックしInterfaceBuilderを起動します。ここで、UINavigationControllerを配置します。

LibraryからNavigation ControllerオブジェクトをDrag&#038;DropでDocumentWindow上に作成します。そのオブジェクトに対して、PresenceAppDelegateクラスのOutlet,navControllerを接続します。 


Navigation Controllerオブジェクトの下にはView Controllerオブジェクトがあります。このクラス名を&#8221;PersonListViewController&#8221;, NIB Nameを&#8221;PersonList&#8221;とします。 


最後にNavigation ControllerオブジェクトをWクリックしView画面を出します。タイトルを&#8221;PersonList&#8221;とします。 


これでMainWindow.xibを閉じ、今度はPersonList.xibを開きます。
 [...]]]></description>
			<content:encoded><![CDATA[<h3>UINavigationControllerの作成</h3>
<p>Lecture7を基に、新しい課題&#8221;Presence&#8221;アプリケーションを作成していきます。実際の内容と脱線するところもありますが、ご了承下さい。<br />
<br />
<img src="http://blog.seiji.me/wp-content/uploads/2008/11/cs193p-cocoa-programming-announcements.jpg" alt="CS193P - Cocoa Programming | Announcements.jpg" border="0" width="430" height="89" /><br />
	<br />
	<q><br />
		<cite><a href="http://www.stanford.edu/class/cs193p/cgi-bin/index.php">iPhone Application Programming</a></cite><br />
	</q>
</p>
<p><span id="more-354"></span>
<p>
今迄、作成したソースは<a href="http://public.me.com/seijit/iPhone/CS193P">http://public.me.com/seijit/iPhone/CS193P</a>から
</p>
<h3>今回の目標</h3>
<p>下の図のようなアプリケーションの内、PersonListをTableViewで表示できるようになるのが目標です。（左側の図）<br />
<br /><img src="http://blog.seiji.me/wp-content/uploads/2008/12/target-1.png" alt="target-1.png" border="0" width="400" height="337" /></p>
<h3><img src="http://blog.seiji.me/wp-content/uploads/2008/11/xcode.png" alt="xcode.png" border="0" width="30" height="30" />新規プロジェクト、ViewControlerの作成</h3>
<h4>新規プロジェクト作成</h4>
<p>Navigation-Based Applicationを選択すれば簡単なのですが、今回はあえてWindow-Based Application	を選択して作成していきます。プロジェクト名は&#8221;Presence&#8221;とします。</p>
<p><img src="http://blog.seiji.me/wp-content/uploads/2008/12/200812052345.jpg" alt="200812052345.jpg" border="0" width="400" height="301" />
</p>
<h4>TableViewController, xibファイルの作成</h4>
<p>ViewControllerとして今回はTableViewControllerを作成します。また、それに対応するxibファイルを作成します。TableViewControllerのサブクラスのファイル名を&#8221;PersonListViewController&#8221;,xibファイル名を&#8221;PersonList.xib&#8221;とします。</p>
<p><img src="http://blog.seiji.me/wp-content/uploads/2008/12/2-1.jpg" alt="2-1.jpg" border="0" width="400" height="303" /></p>
<p><img src="http://blog.seiji.me/wp-content/uploads/2008/12/.jpg" alt="新規ファイル.jpg" border="0" width="400" height="303" /></p>
<h4>PresenceAppDelegateの修正</h4>
<p>以前、ViewControllerを追加した同様のやり方で、UINavigationControllerをDelegateクラスに追加します。</p>
<h5>PresenceAppDelegate.h</h5>
<pre><code>#import <uikit/UIKit.h>
@interface PresenceAppDelegate : NSObject <uiapplicationDelegate> {
	UIWindow *window;
	UINavigationController *navController;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UINavigationController *navController;
@end
</code></pre>
<h5>PresenceAppDelegate.m</h5>
<pre><code>#import "PresenceAppDelegate.h"
@implementation PresenceAppDelegate
@synthesize window;
@synthesize navController;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
	// Override point for customization after application launch
	[window addSubview:[navController view]];
	[window makeKeyAndVisible];
}

- (void)dealloc {
	[window release];
	[navController release];
	[super dealloc];
}
@end
</code></pre>
<h3><img src="http://blog.seiji.me/wp-content/uploads/2008/11/picture.png" alt="picture.png" border="0" width="30" height="30" />UINavigationControllerの配置・接続</h3>
<h4>MainWindow.xib</h4>
<p>MainWindow.xibをWクリックしInterfaceBuilderを起動します。ここで、UINavigationControllerを配置します。
</p>
<p>LibraryからNavigation ControllerオブジェクトをDrag&#038;DropでDocumentWindow上に作成します。そのオブジェクトに対して、PresenceAppDelegateクラスのOutlet,navControllerを接続します。 </p>
<p><img src="http://blog.seiji.me/wp-content/uploads/2008/12/1.jpg" alt="ピクチャ 1.jpg" border="0" width="400" height="250" />
</p>
<p>Navigation Controllerオブジェクトの下にはView Controllerオブジェクトがあります。このクラス名を&#8221;PersonListViewController&#8221;, NIB Nameを&#8221;PersonList&#8221;とします。 </p>
<p><img src="http://blog.seiji.me/wp-content/uploads/2008/12/21.jpg" alt="ピクチャ 2.jpg" border="0" width="400" height="250" />
</p>
<p>最後にNavigation ControllerオブジェクトをWクリックしView画面を出します。タイトルを&#8221;PersonList&#8221;とします。 </p>
<p><img src="http://blog.seiji.me/wp-content/uploads/2008/12/3.jpg" alt="ピクチャ 3.jpg" border="0" width="400" height="250" />
</p>
<p>これでMainWindow.xibを閉じ、今度はPersonList.xibを開きます。</p>
<h4> PersonList.xib</h4>
<p>初めにLibraryからTableViewを選択しview上にDrag&#038;Dropで配置し、各Cellの高さをSize Inspectorでheightを60.00にします。次にFile&#8217;s OwnerのClass名を&#8221;PersonListViewController&#8221;とし、最後にPersonListViewControllerのviewをTableViewに接続して終了です。</p>
<p><img src="http://blog.seiji.me/wp-content/uploads/2008/12/4.jpg" alt="ピクチャ 4.jpg" border="0" width="400" height="250" />
</p>
<p>これで、Navigation-Based Applicationを選択した場合に近いものができました。
</p>
<h3><img src="http://blog.seiji.me/wp-content/uploads/2008/11/xcode.png" alt="xcode.png" border="0" width="30" height="30" />TableViewControllerの実装</h3>
<p>先ほど、作成したTableViewControllerのSubClassのPersonListViewControllerの実装を行います。
</p>
<h4>読み込むデータ</h4>
<p>今回、読み込むデータは静的なものにします。Project内(Bundle内)に画像(i.g. Bors.jpg)をDrag&#038;Dropで配置します。今回使用した画像は<a href="http://www.southparkstudios.com/">South Park Studios</a>で作成したものを使わせていただいています。</p>
<p><img src="http://blog.seiji.me/wp-content/uploads/2008/12/personlistviewcontrollerm-presence-1.png" alt="PersonListViewController.m — Presence-1.png" border="0" width="200" height="339" /></p>
<p>ファイルパスを取得し、ファイル名を名前とするわけです。
</p>
<h4>UIImageの拡張</h4>
<p>UIImageはImageを扱うクラスです。今回、用意している画像は120px × 120pxで、このまま表示するとCellからはみだします。画像を縮小して表示したいのですが、UIImageには簡単に行えるのがない為、UIImageのカテゴリを実装し、リサイズの機能を付加します。</p>
<h5>UIImageResize.h</h5>
<pre><code>#import &lt;Foundation/Foundation.h&gt;
@interface UIImage (Resize)
- (UIImage*)resize:(CGRect)rect;
@end</code></pre>
<h5>UIImageResize.m</h5>
<pre><code>#import "UIImageResize.h"

@implementation UIImage (Resize)
- (UIImage*)resize:(CGRect)rect {
	UIGraphicsBeginImageContext(rect.size);
	[self drawInRect:rect];
	UIImage *imageCopy =　UIGraphicsGetImageFromCurrentImageContext();
	UIGraphicsEndImageContext();
	return imageCopy;
}
@end</code></pre>
<p>これでResizeのメソッドを持つUIImazeを扱えるようになりました。</p>
<h4>PersonListViewController.h</h4>
<pre><code>#import &lt;UIKit/UIKit.h&gt;

@interface PersonListViewController : UITableViewController {
	NSMutableArray *myData;
}

@property (nonatomic, retain) NSArray *myData;
@end</code></pre>
<h4>PersonListViewController.m</h4>
<pre><code>#import "PersonListViewController.h"
#import "UIImageResize.h"

@implementation PersonListViewController
@synthesize myData;

// 間省略

- (void)dealloc {
	[myData release];
	[super dealloc];
}
</code></pre>
<p>Bundleからファイルを読込みNSMutableArrayに格納します。</p>
<pre><code>- (void)viewDidLoad {
    [super viewDidLoad];
	// load data
	self.myData = [NSMutableArray array];
	NSBundle *bundle = [NSBundle mainBundle];
	NSArray *imgPaths = [bundle pathsForResourcesOfType:@"jpg" inDirectory:@""];
	NSString *path;
	for (path in imgPaths) {
		NSString *name =[[path lastPathComponent] substringToIndex:[[path lastPathComponent] length]- [@".jpg" length]];
		NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:name, @"name", path, @"path", nil];
		[myData addObject:dic];
	}
}
</code></pre>
<p>TableViewを表示する為のメソッドを実装します。</p>
<pre><code>// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [myData count];
}

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

	static NSString *CellIdentifier = @"Cell";
	UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
	if (cell == nil) {
		cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
	}

	// Set up the cell...
	int personIndex = [indexPath indexAtPosition: [indexPath length] - 1];
	UIImage *image= [UIImage imageWithContentsOfFile:[[myData objectAtIndex:personIndex] objectForKey:@"path"]];

	[cell setImage:[image resize:CGRectMake(0, 0, 60, 60)]];
	[cell setText:[[myData objectAtIndex:personIndex] objectForKey:@"name"]];
	return cell;
}
</code></pre>
<p>これで下のように動くはずです。</p>
<p><img src="http://blog.seiji.me/wp-content/uploads/2008/12/iphone.png" alt="iPhone シミュレータ.png" border="0" width="200" height="381" /></p>
<p>今回作成したソースは<a href="http://public.me.com/seijit/iPhone/CS193P/Lecture7">http://public.me.com/seijit/iPhone/CS193P/Lecture7</a>のPresence.tar.gzです。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.seiji.me/354.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>NSUserDefaultsでのデータ保存-CS193P</title>
		<link>http://blog.seiji.me/320.html</link>
		<comments>http://blog.seiji.me/320.html#comments</comments>
		<pubDate>Sat, 29 Nov 2008 12:55:33 +0000</pubDate>
		<dc:creator>seiji</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[CS193P]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[UIView]]></category>

		<guid isPermaLink="false">http://blog.seiji.me/?p=320</guid>
		<description><![CDATA[NSUserDefaultsでのデータ保存
Lecture6の内容にあたります。前回のHelloPolyプロジェクトを拡張します。今回はアプリケーションの終了・起動時にデータを保存・読込みを行います。具体的にはPolygonの辺の数を保存します。データが存在した場合はその数を使い描画を行います。
	

	
	
		iPhone Application Programming
	



今迄、作成したソースはhttp://public.me.com/seijit/iPhone/CS193Pから

データの保存
今回は値が変化したタイミングではなく、アプリケーションが終了した時のみ、データの保存を行います。
MyUIViewController
ViewControllerの中でアプリケーション終了時に呼び出されるメソッドを作成します。
MyUIViewController.h
- (void)willTerminate:(UIApplication *)application;
MyUIViewController.m
-(void)willTerminate:(UIApplication *)application {
	NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
	[defaults setInteger:polygon.numberOfSides forKey:NUMBER_OF_SIDES];
}

HelloPolyAppDelegate
HelloPolyAppDelegateでapplicationWillTerminate:を実装し、その中でMyUIViewController::willTerminate:をCallします。
HelloPolyAppDelegate.m
- (void)applicationWillTerminate:(UIApplication *)application {
	[myUIViewController willTerminate:application];
}

データの読込み
アプリケーション起動時に読込むコードを追加します。
MyUIViewController 
MyUIViewControllerでviewDidLoad:のメソッド中にコードを追加します。
MyUIViewController.m
- (void)viewDidLoad {
	[polygon setMinimumNumberOfSides:3];
	[polygon setMaximumNumberOfSides:12];
	// NSUserDefaults Loading
	NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
	int num = [defaults integerForKey:NUMBER_OF_SIDES];
	if(num == 0) {
		[polygon setNumberOfSides:numberOfSidesLabel.text.integerValue];
	} else {
		[polygon setNumberOfSides:num];
	}
	myUIView.polygon = polygon;
	[self updateInterface];
    [super viewDidLoad];
}


値を変えて終了した後、再度起動するとその値が保存されて、描画されるのがわかります。

今回作成したソースは
http://public.me.com/seijit/iPhone/CS193P/Lecture6のHelloPoly4.tar.gzです。
]]></description>
			<content:encoded><![CDATA[<h3>NSUserDefaultsでのデータ保存</h3>
<p>Lecture6の内容にあたります。前回のHelloPolyプロジェクトを拡張します。今回はアプリケーションの終了・起動時にデータを保存・読込みを行います。具体的にはPolygonの辺の数を保存します。データが存在した場合はその数を使い描画を行います。<br />
	<br />
<img src="http://blog.seiji.me/wp-content/uploads/2008/11/cs193p-cocoa-programming-announcements.jpg" alt="CS193P - Cocoa Programming | Announcements.jpg" border="0" width="430" height="89" /><br />
	<br />
	<q><br />
		<cite><a href="http://www.stanford.edu/class/cs193p/cgi-bin/index.php">iPhone Application Programming</a></cite><br />
	</q>
</p>
<p><span id="more-320"></span>
<p>
今迄、作成したソースは<a href="http://public.me.com/seijit/iPhone/CS193P">http://public.me.com/seijit/iPhone/CS193P</a>から
</p>
<h3><img src="http://blog.seiji.me/wp-content/uploads/2008/11/xcode.png" alt="xcode.png" border="0" width="30" height="30" />データの保存</h3>
<p>今回は値が変化したタイミングではなく、アプリケーションが終了した時のみ、データの保存を行います。</p>
<h4>MyUIViewController</h4>
<p>ViewControllerの中でアプリケーション終了時に呼び出されるメソッドを作成します。</p>
<h5>MyUIViewController.h</h5>
<pre><code>- (void)willTerminate:(UIApplication *)application;</code></pre>
<h5>MyUIViewController.m</h5>
<pre><code>-(void)willTerminate:(UIApplication *)application {
	NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
	[defaults setInteger:polygon.numberOfSides forKey:NUMBER_OF_SIDES];
}
</code></pre>
<h4>HelloPolyAppDelegate</h4>
<p>HelloPolyAppDelegateでapplicationWillTerminate:を実装し、その中でMyUIViewController::willTerminate:をCallします。</p>
<h5>HelloPolyAppDelegate.m</h5>
<pre><code>- (void)applicationWillTerminate:(UIApplication *)application {
	[myUIViewController willTerminate:application];
}
</code></pre>
<h3><img src="http://blog.seiji.me/wp-content/uploads/2008/11/picture.png" alt="picture.png" border="0" width="30" height="30" />データの読込み</h3>
<p>アプリケーション起動時に読込むコードを追加します。</p>
<h4>MyUIViewController </h4>
<p>MyUIViewControllerでviewDidLoad:のメソッド中にコードを追加します。</p>
<h5>MyUIViewController.m</h5>
<pre><code>- (void)viewDidLoad {
	[polygon setMinimumNumberOfSides:3];
	[polygon setMaximumNumberOfSides:12];
	// NSUserDefaults Loading
	NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
	int num = [defaults integerForKey:NUMBER_OF_SIDES];
	if(num == 0) {
		[polygon setNumberOfSides:numberOfSidesLabel.text.integerValue];
	} else {
		[polygon setNumberOfSides:num];
	}
	myUIView.polygon = polygon;
	[self updateInterface];
    [super viewDidLoad];
}
</code></pre>
<p>
値を変えて終了した後、再度起動するとその値が保存されて、描画されるのがわかります。<br />
<img src="http://blog.seiji.me/wp-content/uploads/2008/11/iphone-1.jpg" alt="iPhone シミュレータ-1.jpg" border="0" width="290" height="550" /></p>
<p>今回作成したソースは<a href="http://public.me.com/seijit/iPhone/CS193P/Lecture6"><br />
http://public.me.com/seijit/iPhone/CS193P/Lecture6</a>のHelloPoly4.tar.gzです。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.seiji.me/320.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>UIViewの作成-CS193P</title>
		<link>http://blog.seiji.me/310.html</link>
		<comments>http://blog.seiji.me/310.html#comments</comments>
		<pubDate>Fri, 28 Nov 2008 18:15:58 +0000</pubDate>
		<dc:creator>seiji</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[CS193P]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[UIView]]></category>

		<guid isPermaLink="false">http://blog.seiji.me/?p=310</guid>
		<description><![CDATA[UIViewの作成と図形の描画
前回のHelloPolyプロジェクトを拡張します。今回はUIVIewのSubClassを作成し、図形を描画します。
	

	
	
		iPhone Application Programming
	



今迄、作成したソースはhttp://public.me.com/seijit/iPhone/CS193Pから

 UIViewのSubClass作成 
UIView SubClassテンプレート作成
UIViewのSubClassを作成します。名前はMyUIViewとします。


MyUIViewController.hの変更
MyUIViewをPropertyに追加します。
IBOutlet MyUIView *myUIVIew;

 UIViewとUIViewControllerの接続 
MyUIViewController.hの変更
LibraryからUIViewを配置し、Identity InspectorでClassNameをMyViewとします。またMyUIViewControllerのOutletとの接続も行います。


 UIViewなどの実装 
PolygonShape
資料にあったpointsForPolygonInRect:numberOfSides:を追加します。
PolygonShape.h
+ (NSArray *)pointsForPolygonInRect:(CGRect)rect numberOfSides:(int)numberOfSides;

PolygonShape.m
+ (NSArray *)pointsForPolygonInRect:(CGRect)rect numberOfSides:(int)numberOfSides {
	CGPoint center = CGPointMake(rect.size.width / 2.0, rect.size.height / 2.0);
	float radius = 0.9 * center.x;
	NSMutableArray *result = [NSMutableArray array];
	float angle = (2.0 * M_PI) / numberOfSides;
	float exteriorAngle = M_PI - angle;
	float rotationDelta = angle - (0.5 * [...]]]></description>
			<content:encoded><![CDATA[<h3>UIViewの作成と図形の描画</h3>
<p>前回のHelloPolyプロジェクトを拡張します。今回はUIVIewのSubClassを作成し、図形を描画します。<br />
	<br />
<img src="http://blog.seiji.me/wp-content/uploads/2008/11/cs193p-cocoa-programming-announcements.jpg" alt="CS193P - Cocoa Programming | Announcements.jpg" border="0" width="430" height="89" /><br />
	<br />
	<q><br />
		<cite><a href="http://www.stanford.edu/class/cs193p/cgi-bin/index.php">iPhone Application Programming</a></cite><br />
	</q>
</p>
<p><span id="more-310"></span>
<p>
今迄、作成したソースは<a href="http://public.me.com/seijit/iPhone/CS193P">http://public.me.com/seijit/iPhone/CS193P</a>から
</p>
<h3><img src="http://blog.seiji.me/wp-content/uploads/2008/11/xcode.png" alt="xcode.png" border="0" width="30" height="30" /> UIViewのSubClass作成 </h3>
<h4>UIView SubClassテンプレート作成</h4>
<p>UIViewのSubClassを作成します。名前はMyUIViewとします。<br />
<img src="http://blog.seiji.me/wp-content/uploads/2008/11/2-1-1.jpg" alt="2-1-1.jpg" border="0" width="400" height="296" /></p>
<p><img src="http://blog.seiji.me/wp-content/uploads/2008/11/2-2.jpg" alt="2-2.jpg" border="0" width="400" height="293" /></p>
<h4>MyUIViewController.hの変更</h4>
<p>MyUIViewをPropertyに追加します。</p>
<pre><code>IBOutlet MyUIView *myUIVIew;
</code></pre>
<h3><img src="http://blog.seiji.me/wp-content/uploads/2008/11/picture.png" alt="picture.png" border="0" width="30" height="30" /> UIViewとUIViewControllerの接続 </h3>
<h4>MyUIViewController.hの変更</h4>
<p>LibraryからUIViewを配置し、Identity InspectorでClassNameをMyViewとします。またMyUIViewControllerのOutletとの接続も行います。<br />
<img src="http://blog.seiji.me/wp-content/uploads/2008/11/2-3-1.jpg" alt="2-3-1.jpg" border="0" width="400" height="250" />
</p>
<h3><img src="http://blog.seiji.me/wp-content/uploads/2008/11/xcode.png" alt="xcode.png" border="0" width="30" height="30" /> UIViewなどの実装 </h3>
<h4>PolygonShape</h4>
<p>資料にあったpointsForPolygonInRect:numberOfSides:を追加します。</p>
<h5>PolygonShape.h</h5>
<pre><code>+ (NSArray *)pointsForPolygonInRect:(CGRect)rect numberOfSides:(int)numberOfSides;
</code></pre>
<h5>PolygonShape.m</h5>
<pre><code>+ (NSArray *)pointsForPolygonInRect:(CGRect)rect numberOfSides:(int)numberOfSides {
	CGPoint center = CGPointMake(rect.size.width / 2.0, rect.size.height / 2.0);
	float radius = 0.9 * center.x;
	NSMutableArray *result = [NSMutableArray array];
	float angle = (2.0 * M_PI) / numberOfSides;
	float exteriorAngle = M_PI - angle;
	float rotationDelta = angle - (0.5 * exteriorAngle);
	for (int currentAngle = 0; currentAngle < numberOfSides; currentAngle++) {
		float newAngle = (angle * currentAngle) - rotationDelta;
		float curX = cos(newAngle) * radius;
		float curY = sin(newAngle) * radius;
		[result addObject:[NSValue valueWithCGPoint:CGPointMake(center.x + curX,
																center.y + curY)]];
	}
	return result;
}
</code></pre>
<h4>MyUIView</h4>
<p>PolygonShape *をPropertyに追加します。retain,copyはしません。</p>
<h5>MyUIView.h</h5>
<pre><code>#import &lt;UIKit/UIKit.h&gt;

@class PolygonShape;
@interface MyUIView : UIView {
	PolygonShape *polygon;
}
@property (nonatomic, assign) PolygonShape *polygon;

@end
</code></pre>
<h5>MyUIView.m</h5>
<pre><code>#import "MyUIView.h"
#import "PolygonShape.h"

@implementation MyUIView
@synthesize polygon;

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

- (void)drawRect:(CGRect)rect {
    // Drawing code
	CGContextRef context = UIGraphicsGetCurrentContext();
	CGRect bounds = [self bounds];

	CGContextBeginPath(context);
	NSArray *pointsArray = [PolygonShape pointsForPolygonInRect:bounds numberOfSides:[polygon numberOfSides]];
	NSEnumerator *pointsEnu = [pointsArray objectEnumerator];
	// firstPoint
	CGPoint firstPoint = [[pointsEnu nextObject] CGPointValue];
	CGContextMoveToPoint (context, firstPoint.x, firstPoint.y);
	// otherPoint
	for (NSValue *points in pointsEnu ) {
		CGPoint thePoint = [points CGPointValue];
		CGContextAddLineToPoint (context, thePoint.x, thePoint.y);
	}
	CGContextClosePath (context);
	CGContextSetRGBFillColor(context, 0xff/255.0, 0xd7/255.0,0x00/255.0, 1);
	CGContextDrawPath (context, kCGPathFillStroke);
}

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

@end

</code></pre>
<h4>MyUIViewController</h4>
<p>MyUIViewのPolygon*のセット、そしてPolygonの状態が変更された場合の再描画の支持のコードを追加します。</p>
<h5>MyUIViewController.m</h5>
<pre><code>- (void)updateInterface {
	if ( [polygon numberOfSides] == [polygon minimumNumberOfSides]) {
		decreaseButton.enabled = NO;
	} else {
		decreaseButton.enabled = YES;
	}
	if ( [polygon numberOfSides] == [polygon maximumNumberOfSides]) {
		increaseButton.enabled = NO;
	} else {
		increaseButton.enabled = YES;
	}
	nameOfPolygon.text = [NSString stringWithFormat:@"aka a %@", [polygon name]];
	numberOfSidesLabel.text = [NSString stringWithFormat:@"%d", [polygon numberOfSides]];
	numberSlider.value = [polygon numberOfSides];
	[myUIView setNeedsDisplay];
}

- (void)viewDidLoad {
	[polygon setMinimumNumberOfSides:3];
	[polygon setMaximumNumberOfSides:12];
	[polygon setNumberOfSides:numberOfSidesLabel.text.integerValue];
	myUIView.polygon = polygon;
	[self updateInterface];
	NSLog (@"My polygon from viewDidLoad: %@", polygon);
    [super viewDidLoad];
}
</code></pre>
<p>これで図形の描画ができるようになりました。状態が変更された場合もその都度、再描画されます。<br />
<br />
<img src="http://blog.seiji.me/wp-content/uploads/2008/11/iphone.jpg" alt="iPhone シミュレータ.jpg" border="0" width="294" height="553" /><br />
<br />
今回作成したソースは<a href="http://public.me.com/seijit/iPhone/CS193P/Lecture3">http://public.me.com/seijit/iPhone/CS193P/Lecture3</a>のHelloPoly3.tar.gzを。状態保存はまた別の機会に行います。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.seiji.me/310.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
