<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7926047175171636650</id><updated>2024-10-25T02:13:12.659+08:00</updated><category term="iOS"/><category term="Facebook"/><category term="JavaScript"/><category term="Quartz 2D"/><category term="ActionScript3"/><category term="Flash"/><category term="GoogleMap"/><category term="Graphic API"/><category term="Open Graph protocol"/><category term="心得"/><category term="Block"/><category term="JSON"/><category term="Mobile Web"/><category term="iPhone"/><category term="專案"/><title type='text'>Green</title><subtitle type='html'>主要的內容是技術性文章，會不定期的分享技術性文章；除了技術性文章外，還會有一些遊記、攝影還有一般日常生活分享的文章。</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://greenchiou.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://greenchiou.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>綠</name><uri>http://www.blogger.com/profile/10866243185938517560</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiROppWVtpB4GpYxBDY_T-AZzPrlMgq71-UD2AMaBewAxJAFPEBE5ccXU3vzceeteWEfSPnvBxBPhFejD55iKs_gygYzs1LCW70HmCi4vUQjwnrisgqhAqI7d06MQ6epw/s220/IMG_6544.JPG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>17</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7926047175171636650.post-3028728002471487692</id><published>2012-11-10T14:29:00.000+08:00</published><updated>2012-11-10T14:29:39.376+08:00</updated><title type='text'>關於這個blog~</title><content type='html'>這個Blog已經不再維護了, 新的Blog &lt;a href=&quot;http://greenchiu.github.com&quot;&gt;greenchiu.github.com&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
大家有需要可以到那邊去看&lt;br /&gt;
&lt;br /&gt;
感謝大家～ &lt;(_ _)&gt;&lt;br /&gt;
&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://greenchiou.blogspot.com/feeds/3028728002471487692/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://greenchiou.blogspot.com/2012/11/blog.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/3028728002471487692'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/3028728002471487692'/><link rel='alternate' type='text/html' href='http://greenchiou.blogspot.com/2012/11/blog.html' title='關於這個blog~'/><author><name>綠</name><uri>http://www.blogger.com/profile/10866243185938517560</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiROppWVtpB4GpYxBDY_T-AZzPrlMgq71-UD2AMaBewAxJAFPEBE5ccXU3vzceeteWEfSPnvBxBPhFejD55iKs_gygYzs1LCW70HmCi4vUQjwnrisgqhAqI7d06MQ6epw/s220/IMG_6544.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7926047175171636650.post-6359476250616748160</id><published>2012-06-28T11:18:00.001+08:00</published><updated>2012-06-28T11:20:18.280+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Block"/><category scheme="http://www.blogger.com/atom/ns#" term="iOS"/><title type='text'>[memo]iOS with Block</title><content type='html'>雖然現在已經要出iOS6了，不過還是要memo一個在iOS4就推出的功能Block,Block是C Language撰寫的extension for Objective-C, 不過在其他語言類似的功能可能稱作Closure(因為我也不懂所以就不贅述啦 飄~)&lt;br /&gt;
白話一點Block就是一個區間(封閉的), 在程式中可以把他當作是一個function(method)既然是function的話為什麼還要特別介紹, 因為&lt;strike&gt;&lt;span style=&quot;color: red;&quot;&gt;要報告&lt;/span&gt;&lt;/strike&gt;它可以不用宣告就使用, 而且有好多API都直接支援了~&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
接下來就直接看看程式碼&lt;br /&gt;
&lt;pre class=&quot;brush:objc;highlight:[4,5,6,7,8,16,14,15]&quot;&gt;//sample1
[UIView animateWithDuration:2.0
&amp;nbsp;&amp;nbsp; animations:
    ^ {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  self.view.alpha = 1.0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.view.frame = CGRectMake(176.0, 258.0, 72.0, 96.0);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.view.transform = CGAffineTransformMakeRotation(M_PI);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
];
//sample2
NSArray *cards = [NSArray arrayWithObjects:@&quot;Jack&quot;, @&quot;Queen&quot;, @&quot;King&quot;, @&quot;Ace&quot;, nil];
&amp;nbsp;
[cards enumerateObjectsUsingBlock:
    ^(id object, NSUInteger index, BOOL *stop) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;    NSLog(@&quot;%@ card at index %d&quot;, object, index);
    }
];
//end
&lt;/pre&gt;上面兩個範例highlight的部分, 就是Block, 如果有注意到的話, 應該會知道這兩個Block不同的地方在於一個有待參數, 一個沒有參數(下方highlight部分)&lt;br /&gt;
&lt;pre class=&quot;brush:objc;highlight:[2, 6]&quot;&gt;//block1
^ {
    //statement ...
}
//block2
^(id object, NSUInteger index, BOOL *stop) {
    //statement ...
}
&lt;/pre&gt;從上面, 可以知道block是可以有待參數跟沒有參數, 接著我們更進一步的介紹Block的&lt;strike&gt;成分&lt;/strike&gt;構成&lt;br /&gt;
&lt;pre class=&quot;brush:objc&quot;&gt;void   (^BlockName)   (void)
傳回型別 Block的名稱    參數

BlockName();
使用
&lt;/pre&gt;上面的code, 我們可以把block分成三個部分,分別是 傳回型別(return type)、BlockName跟帶入的參數(parameters), 其中參數如果是void, 在宣告block的時候可以直接把引入的參數省略, 下面就來宣告幾個Block並使用&lt;br /&gt;
&lt;pre class=&quot;brush:objc;highlight:[0]&quot;&gt;//sample1
void (^myName)(void) = ^ {
    NSLog(@&quot;Green&quot;);
};
myName();

//sample2
int (^getAge)(void) = ^ {
    return 26;
};
int myAge = getAge();

//sample3
NSString* (^getBirthday)(int) = ^(int mode) {
    NSString* birthday;
    switch(mode) {
        case 0:
            birthday = @&quot;75.1.15&quot;;
        break;
        default:
            birthday = @&quot;1986.1.15&quot;;
    }
    return birthday;
};
NSString* myBirthday = getBirthday(1);
&lt;/pre&gt;看完前面有一些了解過後，我們再拿UIView有使用Block的Method來相互對照一下&lt;br /&gt;
&lt;pre class=&quot;brush:objc;highlight:[2,5,6,7,8,9]&quot;&gt;+ (void)animateWithDuration:(NSTimeInterval)duration
              animations:(void (^)(void))animations
&lt;/pre&gt;在第二行的地方, 並沒有像前面說的有一個Block&#39;s Name, 照邊我個人理解是因為他的Block是直接使用, 所以就直接用^(cross)符號來代表匿名的block; &lt;strike&gt;接著我們繼續看下去&lt;/strike&gt;&lt;br /&gt;
&lt;pre class=&quot;brush:objc;highlight:[0]&quot;&gt;//sample1
void (^animation)(void) = ^{
    self.view.alpha = 1.0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.view.frame = CGRectMake(176.0, 258.0, 72.0, 96.0);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.view.transform = CGAffineTransformMakeRotation(M_PI);
}
[UIView animateWithDuration:2.0
&amp;nbsp;&amp;nbsp;               animations:animation
];
//sample2
[UIView animateWithDuration:2.0
&amp;nbsp;&amp;nbsp; animations:
    ^ {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  self.view.alpha = 1.0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.view.frame = CGRectMake(176.0, 258.0, 72.0, 96.0);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.view.transform = CGAffineTransformMakeRotation(M_PI);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
];
&lt;/pre&gt;sample1是用先宣告一個跟UIView ClassMethod 需要的Block Method 一樣的Block animation, 然後在呼叫UIView ClassMethod 並將 block animation 指定過去; 更快直接的話可以像sample2一樣直接打一段匿名的block, 也是可以順利執行的.&lt;br /&gt;
&lt;br /&gt;
接著再來介紹 &lt;b&gt;__block&lt;/b&gt; 這個關鍵字, 這個關鍵字是讓在block method外宣告的變數在block method可以當成變數來使用, 前面有提到說Block本身是一個封閉區間, 所以在宣告Block method本身的時候, 他會將block外部的變數當作常數來使用, 所以需要在Block變更Block外部的變數, 只要在宣告的變數前面加上&lt;b&gt;__block&lt;/b&gt;就可以了&lt;br /&gt;
&lt;pre class=&quot;brush:objc&quot;&gt;__block int count = 0;
void(^increase)(void)=^ {
    count++;
    NSLog(@&quot;count:%d&quot;, count);
};

increase();// 1
increase();// 2 ...
&lt;/pre&gt;當我們在coding的時候, 如果有一個mehtod像上面的UIView的ClassMethod用到了Block, 但是如果要帶入的參數很多, 那在閱讀的時候會因為太長就會比較不方便, 我們可用typedef來解決這個問題&lt;br /&gt;
&lt;br /&gt;
下面我建立了一個sampleMethod並要帶入一個block, 接著我們使用typedef來定義type SampleBlock, 接著把method改寫成第6行的樣子; 最下面就是一些簡單的use sample code &lt;br /&gt;
&lt;pre class=&quot;brush:objc&quot;&gt;//before
-(void)sampleMehtod:(void(^)(void))aBlock;

//after
typedef void(^SampleBlock)(void);
-(void)sampleMethod:(SampleBlock)aBlock;

//use
SampleBlock testBlock = ^ {
    //statement ...
};

[self sampleMethod:testBlock];
&lt;/pre&gt;&lt;br /&gt;
到這邊就告一段落啦, 因為打著Memo的口號, 我是用我自己理解的方式來寫可能只有我自己看得比較懂啦&lt;br /&gt;
如果有錯誤也請提出, 感謝</content><link rel='replies' type='application/atom+xml' href='http://greenchiou.blogspot.com/feeds/6359476250616748160/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://greenchiou.blogspot.com/2012/06/memoios-with-block.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/6359476250616748160'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/6359476250616748160'/><link rel='alternate' type='text/html' href='http://greenchiou.blogspot.com/2012/06/memoios-with-block.html' title='[memo]iOS with Block'/><author><name>綠</name><uri>http://www.blogger.com/profile/10866243185938517560</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiROppWVtpB4GpYxBDY_T-AZzPrlMgq71-UD2AMaBewAxJAFPEBE5ccXU3vzceeteWEfSPnvBxBPhFejD55iKs_gygYzs1LCW70HmCi4vUQjwnrisgqhAqI7d06MQ6epw/s220/IMG_6544.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7926047175171636650.post-6933350764285817092</id><published>2011-07-23T11:00:00.002+08:00</published><updated>2011-07-23T11:02:19.818+08:00</updated><title type='text'>新開始，新挑戰</title><content type='html'>&lt;div&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPPklgOl_-UBrEygHnb3fak3UsxERpLyd0BqKFAv1pUy-Fr6RuU0jJO_m8LR16aKRR7lLKBUpZTT0xQq7cGWgJRYh3YHvMG4zAtYBPrZhtqpSoTTe1cWZ5oK7sCjxTngp-3H4Bsl0QweO1/s1600/IMG_0633.JPG&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;476&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPPklgOl_-UBrEygHnb3fak3UsxERpLyd0BqKFAv1pUy-Fr6RuU0jJO_m8LR16aKRR7lLKBUpZTT0xQq7cGWgJRYh3YHvMG4zAtYBPrZhtqpSoTTe1cWZ5oK7sCjxTngp-3H4Bsl0QweO1/s640/IMG_0633.JPG&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;放了一段暑假之後，開始進入了新的工作；雖然因為放假的關係，在頭一、二天非常的不習慣，整個就是躺在床上想賴床這樣，不過還是很努力的投入新工作；新的工作主要是在做Mobile Device Application的開發，而我是之後會開發 iOS 這塊的東西。&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;在這個領域我算是一隻菜鳥吧，渾身菜味那種，所以....不用多說，當然是從看code這件事情開始做起；不得不說，差異性頗大的，當然也偷偷學到好幾招了，不過還是有待嘗試嘗試。&lt;br /&gt;
不過有好多東西都是頭一遭，只能扒著人到處問，不過還是有很多不了解的地方，而且工作的co-work方式也不大一樣，還得要在慢慢熟悉，摸索摸索~&lt;br /&gt;
&lt;br /&gt;
至於，第一個禮拜過去了，老實說我還是有些緊張，不知道當初勇往直前的衝勁是哪邊來的；不過還是想要挑戰自己，做自己想要做的東西，可能過程會辛苦一些，不過總是要努力過才不會覺得後悔。當然，自己還是有一些計畫，想要做一個可以存放自己作品的網站，目前有初步計畫了，不過在開始之前可能要先複習一下PHP，可以在不久的將來把這個計畫放上我的時程表上。&lt;br /&gt;
&lt;br /&gt;
至於Flash的部分嘛，其實還是會繼續玩吧，只要有時間，我想在AS的聚會上我還是會不定時出現的，就像老林跟SEGA的&lt;a href=&quot;http://blog.igdshare.org/&quot; target=&quot;_blank&quot;&gt;獨立遊戲開發者分享會&lt;/a&gt;一樣，只不過主力不會是這方面而已。&lt;br /&gt;
&lt;br /&gt;
最後希望我可以在這邊順利的闖出一片自己的天空啦，也祝大家工作、生活都順利囉。</content><link rel='replies' type='application/atom+xml' href='http://greenchiou.blogspot.com/feeds/6933350764285817092/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://greenchiou.blogspot.com/2011/07/blog-post.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/6933350764285817092'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/6933350764285817092'/><link rel='alternate' type='text/html' href='http://greenchiou.blogspot.com/2011/07/blog-post.html' title='新開始，新挑戰'/><author><name>綠</name><uri>http://www.blogger.com/profile/10866243185938517560</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiROppWVtpB4GpYxBDY_T-AZzPrlMgq71-UD2AMaBewAxJAFPEBE5ccXU3vzceeteWEfSPnvBxBPhFejD55iKs_gygYzs1LCW70HmCi4vUQjwnrisgqhAqI7d06MQ6epw/s220/IMG_6544.JPG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPPklgOl_-UBrEygHnb3fak3UsxERpLyd0BqKFAv1pUy-Fr6RuU0jJO_m8LR16aKRR7lLKBUpZTT0xQq7cGWgJRYh3YHvMG4zAtYBPrZhtqpSoTTe1cWZ5oK7sCjxTngp-3H4Bsl0QweO1/s72-c/IMG_0633.JPG" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7926047175171636650.post-652889894000165932</id><published>2011-05-09T11:15:00.001+08:00</published><updated>2011-12-03T10:16:05.213+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="GoogleMap"/><category scheme="http://www.blogger.com/atom/ns#" term="iOS"/><title type='text'>iOS SDK with MapKit (Google Map) 練習 (2)</title><content type='html'>接續上篇，接著繼續分享MKAnnotationView以及MKMapViewDelegate兩個內容；上一篇有提到說顯示在地圖上的資訊註解(Annotations)是由一個&lt;b&gt;資訊模組&lt;/b&gt;(MKAnnotation)跟一個&lt;b&gt;可視物件/模組&lt;/b&gt;(MKAnnotationView)所組成的，這個可視模組除了將資訊模組裡的資料呈現出來之外，我們還可以將其運用加入圖片跟按鈕，讓我們顯示出來的資訊更加全面。&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;b&gt;我會將閱讀文章的人視作對 c / obj-c 以及 iOS有一定的認識，因此在obj-c/c的一些使用內容將不會有太多的解釋。&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
在這邊我們會先使用MKPinAnnotationView 來介紹 MKAnnotationView 以及 MKMapViewDelegate在顯示MKAnnotationView用的method&lt;br /&gt;
&lt;pre class=&quot;brush:objc;highlight:[5,13]&quot;&gt;//MapKit_PracticeController.h
#import &amp;lt;MapKit/MapKit.h&amp;gt;
#import &quot;Annotation.h&quot;

@interface MapKit_PracticeViewController : UIViewController &amp;lt;MKMapViewDelegate&amp;gt; {
    MKMapView *mapView;
}
//MapKit_PracticeViewController.m
-(void)loadView
{
    [super loadView];
    mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
    mapView.delegate = self;
    MKCoordinateRegion region;
    region.center.latitude = 25.044;
    region.center.longitude = 121.526;
    MKCoordinateSpan span;
    span.latitudeDelta  = .002;
    span.longitudeDelta = .002;
    region.span = span;
    [mapView setRegion:region animated:YES];

    /**
     * 以下照舊 ... 
     */
    [self.view addSubview:mapView];
}
&lt;/pre&gt;第5,8行的地方我們先將controller採用了MKMapViewDelegate協定，再將mapView的委派指向controller，這樣一來當我們在mapView上的動作就可以反應到我們實作的method上；這邊我們先實作 method&lt;br /&gt;
&lt;pre class=&quot;brush:objc&quot;&gt;#pragma mark methods for MKMapViewDelegate
- (MKAnnotationView *)mapView:(MKMapView *)map 
            viewForAnnotation:(id &amp;lt;MKAnnotation&amp;gt;)annotation 
{
    static NSString *AnnotationViewID = @&quot;annotationViewID&quot;;
    MKPinAnnotationView* pinView = 
    (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];
    if (!pinView)
    {
 // if an existing pin view was not available, create one
        MKPinAnnotationView* customPinView = 
        [[[MKPinAnnotationView alloc] initWithAnnotation:annotation 
                                         reuseIdentifier:AnnotationViewID] 
         autorelease];                              
        customPinView.pinColor = MKPinAnnotationColorPurple;
        customPinView.animatesDrop = YES;
        customPinView.canShowCallout =YES;
        return customPinView;
    }
    else
    {
        pinView.annotation = annotation;
    }
    return pinView;
}
&lt;/pre&gt;這個method是當你要呈現的我們在地圖上的資訊註解時所呈現的可視模組(MKAnnotationView)，一開始會先判斷這個資訊是否建立過了沒有的話就建立一個新的，有的話就直接使用只是修改資訊內容。&lt;br /&gt;
執行結果:&lt;br /&gt;
&lt;div&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLUPYGYtyQhLUyWoQn1Hvw7an0GQOsN_9IT-H7Lds3ez26_YzXVt6o9NECPUtxfPnNvW4O3OPWDEsOZ30KCXTmq2RFzetSQ6ADJr4tKBEp-ZhggfcdIFI76WciyWd-iS5G6Of57dxLd65I/s1600/%25E8%259E%25A2%25E5%25B9%2595%25E5%25BF%25AB%25E7%2585%25A7+2011-05-08+%25E4%25B8%258B%25E5%258D%258810.00.36.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; width=&quot;206&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLUPYGYtyQhLUyWoQn1Hvw7an0GQOsN_9IT-H7Lds3ez26_YzXVt6o9NECPUtxfPnNvW4O3OPWDEsOZ30KCXTmq2RFzetSQ6ADJr4tKBEp-ZhggfcdIFI76WciyWd-iS5G6Of57dxLd65I/s400/%25E8%259E%25A2%25E5%25B9%2595%25E5%25BF%25AB%25E7%2585%25A7+2011-05-08+%25E4%25B8%258B%25E5%258D%258810.00.36.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;接著我希望我資訊註解可以有相關的照片以及可以點擊顯示更詳細的內容，所以我們要新增修改下列兩個 method&lt;br /&gt;
&lt;pre class=&quot;brush:objc;highlight:[16,17]&quot;&gt;- (MKAnnotationView *)mapView:(MKMapView *)map 
            viewForAnnotation:(id &amp;lt;MKAnnotation&amp;gt;)annotation 
{
    static NSString *AnnotationViewID = @&quot;annotationViewID&quot;;
    MKPinAnnotationView* pinView = 
    (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];
    if (!pinView)
    {
        MKPinAnnotationView* customPinView = 
        [[[MKPinAnnotationView alloc] initWithAnnotation:annotation 
                                         reuseIdentifier:AnnotationViewID] 
         autorelease];                              
        customPinView.pinColor = MKPinAnnotationColorPurple;
        customPinView.animatesDrop = YES;
        customPinView.canShowCallout =YES;
        customPinView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
        customPinView.leftCalloutAccessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@&quot;Pic_image.png&quot;]];
        return customPinView;
    }
    else
    {
        pinView.annotation = annotation;
    }
    return pinView;
}
//AnnotationView&#39;s UIControl 被點擊後的動作反應
-(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
    [[[[UIAlertView alloc] initWithTitle:view.annotation.title 
                                 message:view.annotation.subtitle 
                                delegate:nil 
                       cancelButtonTitle:@&quot;OK&quot; 
                       otherButtonTitles:nil, nil] 
      autorelease] 
     show];
}
&lt;/pre&gt;執行畫面&lt;br /&gt;
&lt;div&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGhkAGh7jdKqoMm2yImpS4eDU1jVHZpcPhMEdfJ2M9pCnCZPO5miCYFmro5nQea0jIzr3ys0QvAi3tCrsertZm7K-k3jKeR1tAUfeNYPFThcJ0PqtirYukjZo-bu_I4ArMX-FGPHKweuJj/s1600/%25E8%259E%25A2%25E5%25B9%2595%25E5%25BF%25AB%25E7%2585%25A7+2011-05-08+%25E4%25B8%258B%25E5%258D%258810.11.03.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; width=&quot;204&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGhkAGh7jdKqoMm2yImpS4eDU1jVHZpcPhMEdfJ2M9pCnCZPO5miCYFmro5nQea0jIzr3ys0QvAi3tCrsertZm7K-k3jKeR1tAUfeNYPFThcJ0PqtirYukjZo-bu_I4ArMX-FGPHKweuJj/s400/%25E8%259E%25A2%25E5%25B9%2595%25E5%25BF%25AB%25E7%2585%25A7+2011-05-08+%25E4%25B8%258B%25E5%258D%258810.11.03.png&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/td&gt;&lt;td&gt;&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0CZ5PKGVB08xbXg43ErDL1365j7Z8FhT6Ky5dTmXWX99w3rl4c7m0TE1bLUMSngFOjOg3jmqyaQNBe4xDhMP7kfYQeb5JNnTiojKAG1L99bvOBbknA0iyVkgDHKZeCyVONlDTNI38_NEm/s1600/%25E8%259E%25A2%25E5%25B9%2595%25E5%25BF%25AB%25E7%2585%25A7+2011-05-08+%25E4%25B8%258B%25E5%258D%258810.11.16.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; width=&quot;206&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0CZ5PKGVB08xbXg43ErDL1365j7Z8FhT6Ky5dTmXWX99w3rl4c7m0TE1bLUMSngFOjOg3jmqyaQNBe4xDhMP7kfYQeb5JNnTiojKAG1L99bvOBbknA0iyVkgDHKZeCyVONlDTNI38_NEm/s400/%25E8%259E%25A2%25E5%25B9%2595%25E5%25BF%25AB%25E7%2585%25A7+2011-05-08+%25E4%25B8%258B%25E5%258D%258810.11.16.png&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/td&gt; &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;除了用大頭針外，也是可以自定資訊註解的圖形，只要使用MKAnnotationView來取代MKPinAnnotationView就可以了，並且將MKAnnotationView的image指定成要使用的圖形就可以了，不過要注意的是載入圖形後要使用centerOffset去調整圖形的位置，不然定點會出現一些誤差。&lt;br /&gt;
最後在介紹&lt;br /&gt;
&lt;pre class=&quot;brush:objc&quot;&gt;- (void)mapView:(MKMapView *)map regionDidChangeAnimated:(BOOL)animated
&lt;/pre&gt;這個method是當你移動你地圖完畢的時候反應的動作，可以在這邊判斷現在在地圖裡面的資訊哪些已經離開畫面需要被移除的或者是需要被新增加到地圖上。在請大家自己試看看該怎麼做囉。&lt;br /&gt;
&lt;br /&gt;
這次的分享內容是補足上一篇沒打完的部份，所以內容比較少了些，有一些地方也是用敘述來帶過，可能要麻煩大家自己嘗試一下會比較清楚；最後就是內容有錯誤或者是有什麼指教的地方，也請大家跟我反應，希望這篇分享也可以幫助倒有需要的人，謝謝。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
參考連結:&lt;br /&gt;
Introduction to MapKit on iOS Tutorial &lt;a href=&quot;http://www.raywenderlich.com/2847/introduction-to-mapkit-on-ios-tutorial&quot; target=&quot;_blank&quot;&gt;Link&lt;/a&gt;&lt;br /&gt;
Map Kit Framework Reference &lt;a href=&quot;http://developer.apple.com/library/ios/#documentation/MapKit/Reference/MapKit_Framework_Reference/_index.html&quot; target=&quot;_blank&quot;&gt;Link&lt;/a&gt;&lt;br /&gt;
MKMapViewDelegate Protocol Reference &lt;a href=&quot;http://developer.apple.com/library/ios/#documentation/MapKit/Reference/MKMapViewDelegate_Protocol/MKMapViewDelegate/MKMapViewDelegate.html#//apple_ref/doc/uid/TP40008204&quot; target=&quot;_blank&quot;&gt;Link&lt;/a&gt;&lt;br /&gt;
MKAnnotationView Class Reference &lt;a href=&quot;http://developer.apple.com/library/ios/#documentation/MapKit/Reference/MKAnnotationView_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40008207&quot; target=&quot;_blank&quot;&gt;Link&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://greenchiou.blogspot.com/feeds/652889894000165932/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://greenchiou.blogspot.com/2011/05/ios-sdk-with-mapkit-google-map-2.html#comment-form' title='3 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/652889894000165932'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/652889894000165932'/><link rel='alternate' type='text/html' href='http://greenchiou.blogspot.com/2011/05/ios-sdk-with-mapkit-google-map-2.html' title='iOS SDK with MapKit (Google Map) 練習 (2)'/><author><name>綠</name><uri>http://www.blogger.com/profile/10866243185938517560</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiROppWVtpB4GpYxBDY_T-AZzPrlMgq71-UD2AMaBewAxJAFPEBE5ccXU3vzceeteWEfSPnvBxBPhFejD55iKs_gygYzs1LCW70HmCi4vUQjwnrisgqhAqI7d06MQ6epw/s220/IMG_6544.JPG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLUPYGYtyQhLUyWoQn1Hvw7an0GQOsN_9IT-H7Lds3ez26_YzXVt6o9NECPUtxfPnNvW4O3OPWDEsOZ30KCXTmq2RFzetSQ6ADJr4tKBEp-ZhggfcdIFI76WciyWd-iS5G6Of57dxLd65I/s72-c/%25E8%259E%25A2%25E5%25B9%2595%25E5%25BF%25AB%25E7%2585%25A7+2011-05-08+%25E4%25B8%258B%25E5%258D%258810.00.36.png" height="72" width="72"/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7926047175171636650.post-8468222062843731465</id><published>2011-05-05T15:10:00.002+08:00</published><updated>2011-12-03T10:15:41.244+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="GoogleMap"/><category scheme="http://www.blogger.com/atom/ns#" term="iOS"/><title type='text'>iOS SDK with MapKit (Google Map) 練習 (1)</title><content type='html'>Hi all，最近練習了在iOS終始用Google Map，有一些成果後筆記一下順便分享給大家，這次要來分享如何使用 iOS SDK 的 MapKit framework來建立地圖，並且在地圖上建立幾個點，還有一些相關的運用；至於查詢地指方面的功能，就等我試出來後再跟大家介紹吧。&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;b&gt;我會將閱讀文章的人視作對 c / obj-c 以及 iOS有一定的認識，因此在obj-c/c的一些使用內容將不會有太多的解釋。&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
首先，先在專案(我專案命為MapKit_Practice)內加入MapKit framework，你可以參考下圖來增加需要的framework&lt;br /&gt;
&lt;div&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZJNiWx7H4ZmHYm0Mh9ecP6xykKfqpf4iI4N4n59sTXs9l7RmUkKEgvLi9IpRDosbygI884St3eWWxhnECuism8wDLfdL94orjrYjDAzj5pfI1B6L5sawE62ylwX1yEin1lM5DpFjVdFNr/s1600/%25E8%259E%25A2%25E5%25B9%2595%25E5%25BF%25AB%25E7%2585%25A7+2011-05-04+%25E4%25B8%258B%25E5%258D%25885.08.25.png&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;115&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZJNiWx7H4ZmHYm0Mh9ecP6xykKfqpf4iI4N4n59sTXs9l7RmUkKEgvLi9IpRDosbygI884St3eWWxhnECuism8wDLfdL94orjrYjDAzj5pfI1B6L5sawE62ylwX1yEin1lM5DpFjVdFNr/s400/%25E8%259E%25A2%25E5%25B9%2595%25E5%25BF%25AB%25E7%2585%25A7+2011-05-04+%25E4%25B8%258B%25E5%258D%25885.08.25.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
增加完成後，接著我們開始建立Google Map到我們的畫面上&lt;br /&gt;
MapKit_PracticeViewController.h&lt;br /&gt;
&lt;pre class=&quot;brush:objc;highlight:[1]&quot;&gt;#import &amp;lt;MapKit/MapKit.h&amp;gt;
@interface MapKit_PracticeViewController : UIViewController {
    MKMapView *mapView;
}
@end
&lt;/pre&gt;接的修改MapKit_PracticeViewController.m&lt;br /&gt;
&lt;pre class=&quot;brush:objc&quot;&gt;#import &quot;MapKit_PracticeViewController.h&quot;
@implementation MapKit_PracticeViewController
- (void)dealloc
{
    [mapView release];
    [super dealloc];
}
-(void)loadView
{
    [super loadView];
    mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
    [self.view addSubview:mapView];
}
&lt;/pre&gt;執行結果&lt;br /&gt;
&lt;div&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhByreZypEH795V8egk4P0AWp_hb_46vnma6oE078OMasio8J_AfqXRy1I1r0ilvD7gr8h2HdDAA-vnk3b-Vmoha9-k2jygLHNfGzVSaRvbdcIq9hsSWXQ8kdi1YYyQ5iF0Q48FWwfqNHEO/s1600/%25E8%259E%25A2%25E5%25B9%2595%25E5%25BF%25AB%25E7%2585%25A7+2011-05-04+%25E4%25B8%258B%25E5%258D%25885.30.13.png&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhByreZypEH795V8egk4P0AWp_hb_46vnma6oE078OMasio8J_AfqXRy1I1r0ilvD7gr8h2HdDAA-vnk3b-Vmoha9-k2jygLHNfGzVSaRvbdcIq9hsSWXQ8kdi1YYyQ5iF0Q48FWwfqNHEO/s400/%25E8%259E%25A2%25E5%25B9%2595%25E5%25BF%25AB%25E7%2585%25A7+2011-05-04+%25E4%25B8%258B%25E5%258D%25885.30.13.png&quot; width=&quot;204&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
到這邊就完成基本的建立了，但是我們並不想要把地圖一開始顯示的地點設在美國，我想把他設定在台北火車站的附近，所以我們接著修改map.region參數：&lt;br /&gt;
MapKit_PracticeViewController.m&lt;br /&gt;
&lt;pre class=&quot;brush:objc;highlight:[5,8]&quot;&gt;-(void)loadView
{
    [super loadView];
    mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
    MKCoordinateRegion region;
    region.center.latitude = 25.044;
    region.center.longitude = 121.526;
    MKCoordinateSpan span;
    span.latitudeDelta  = .002;
    span.longitudeDelta = .002;
    region.span = span;
    [mapView setRegion:region animated:YES];
    [self.view addSubview:mapView];
}
&lt;/pre&gt;上面的程式碼中我們先宣告了一個 MKCoordinateRegion 結構的變數 region，並將中心點設定在(北緯,東經):&lt;br /&gt;
(25.044,121.526)的地方，接著在設定地圖縮放的等級(zoom-level) MKCoordinateSpan span，數值越小呈現的地圖範圍越小。&lt;br /&gt;
執行的結果如下圖&lt;br /&gt;
&lt;div&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj58lYJCe6cgAGZYHUecHKKercAZ56MloNlu3jueu3OIWrq66-wUQ6kMGvDEASAtsmNHtpLUSGakj3SggfGyCAtbkKABQZcGe0pk6MkHoP3xwhNRdp6OtYm9LED1bJO5TkHs336g903V9AP/s1600/%25E8%259E%25A2%25E5%25B9%2595%25E5%25BF%25AB%25E7%2585%25A7+2011-05-04+%25E4%25B8%258B%25E5%258D%25885.48.14.png&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj58lYJCe6cgAGZYHUecHKKercAZ56MloNlu3jueu3OIWrq66-wUQ6kMGvDEASAtsmNHtpLUSGakj3SggfGyCAtbkKABQZcGe0pk6MkHoP3xwhNRdp6OtYm9LED1bJO5TkHs336g903V9AP/s400/%25E8%259E%25A2%25E5%25B9%2595%25E5%25BF%25AB%25E7%2585%25A7+2011-05-04+%25E4%25B8%258B%25E5%258D%25885.48.14.png&quot; width=&quot;204&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
到這邊，我們已經建立了基本的地圖內容，被並且將起始位置跟縮放等級設定在我們所想要的位置，接下來我們將要在地圖增加一個地點網路基因，這要用到MKAnnotation Protocal，這個協定被宣告如下：&lt;br /&gt;
&lt;pre class=&quot;brush:objc&quot;&gt;@protocol MKAnnotation &amp;lt;NSObject&amp;gt;

// Center latitude and longitude of the annotion view.
// The implementation of this property must be KVO compliant.
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;

@optional

// Title and subtitle for use by selection UI.
- (NSString *)title;
- (NSString *)subtitle;

// Called as a result of dragging an annotation view.
- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_0);

@end
&lt;/pre&gt;上面的程式碼，你應該有注意到並沒有我們在宣告Class時候都會出現一個@interface ClassName {}的內容，因此我們需要去宣告一個 Class 來採用並實現這個資料模型(data medol)。&lt;br /&gt;
&lt;b&gt;註解在地圖上的資訊(Annotations)是由MKAnnontation 跟 MKAnnontationView組成&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
宣告一個新的Class Annotation&lt;br /&gt;
&lt;pre class=&quot;brush:objc&quot;&gt;//Annotation.h:
#import &amp;lt;MapKit/MapKit.h&amp;gt;
@interface Annotation : NSObject &amp;lt;MKAnnotation&amp;gt; {
}
@end
//Annotation.m:
-(NSString*)title
{
    return @&quot;網路基因&quot;;
}
-(NSString*)subtitle
{
    return @&quot;電話：02-2395-5378&quot;;
}
-(CLLocationCoordinate2D) coordinate
{
    CLLocationCoordinate2D _coordinate = {25.044423,121.52673};
    return _coordinate;
}
&lt;/pre&gt;接著我們直接使用Annotation這個類別並增加到我們的地圖上&lt;br /&gt;
&lt;pre class=&quot;brush:objc&quot;&gt;//MapKit_PracticeViewController.h
#import Annotation.h
//MapKit_PracticeViewController.m
-(void)loadView
{
    [super loadView];
    mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
    MKCoordinateRegion region;
    region.center.latitude = 25.044;
    region.center.longitude = 121.526;
    MKCoordinateSpan span;
    span.latitudeDelta  = .0015;
    span.longitudeDelta = .0015;
    region.span = span;
    [mapView setRegion:region animated:YES];

    Annotation *myAnnotation = [[Annotation alloc] init];
    [mapView addAnnotation:myAnnotation];

    [self.view addSubview:mapView];
}
&lt;/pre&gt;執行後的畫面(我有先點擊大頭針)如下&lt;br /&gt;
&lt;div&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjB9XqW8gAuHvS5KESqUJ6sbLmaYcmk76w5snEPs3-ZZhiQ_s2YgSJ5uXHkIyMMDdOwjBhZtmMM4XlplEzR0-n4TqMXtTgxOEaV6sjR4LwgaAZ2YbsFw1JRAkz2tfXVHQNZYo0ojYNhlSmu/s1600/%25E8%259E%25A2%25E5%25B9%2595%25E5%25BF%25AB%25E7%2585%25A7+2011-05-05+%25E4%25B8%258B%25E5%258D%258812.28.41.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; width=&quot;204&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjB9XqW8gAuHvS5KESqUJ6sbLmaYcmk76w5snEPs3-ZZhiQ_s2YgSJ5uXHkIyMMDdOwjBhZtmMM4XlplEzR0-n4TqMXtTgxOEaV6sjR4LwgaAZ2YbsFw1JRAkz2tfXVHQNZYo0ojYNhlSmu/s400/%25E8%259E%25A2%25E5%25B9%2595%25E5%25BF%25AB%25E7%2585%25A7+2011-05-05+%25E4%25B8%258B%25E5%258D%258812.28.41.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
這樣我們就成功的在地圖上增加了一個地點&quot;網路基因&quot;，但是現在的Annotation class在使用上非常的不方便，所以我在針對Annotation做一些修改以便在使用尚可以更符合我們的需求&lt;br /&gt;
&lt;pre class=&quot;brush:objc;highlight:20&quot;&gt;//Annotation.h:
#import &amp;lt;MapKit/MapKit.h&amp;gt;

@interface Annotation : NSObject &amp;lt;MKAnnotation&amp;gt; {
    NSString *_title;
    NSString *_subTitle;
    CLLocationCoordinate2D _coordiante2D;
}

@property (nonatomic , readonly) NSString *title;
@property (nonatomic , readonly) NSString *subtitle;
@property (nonatomic , readonly) CLLocationCoordinate2D coordinate;

-(id) initWhithTitle:(NSString *) theTitle subTitle:(NSString *)theSubTitle andCoordiante:(CLLocationCoordinate2D) theCoordinate;
@end

//Annotation.m:
@implementation Annotation
//設定getter
@synthesize title=_title,subtitle=_subTitle,coordinate=_coordiante2D;

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

-(id) initWhithTitle:(NSString *) theTitle subTitle:(NSString *)theSubTitle andCoordiante:(CLLocationCoordinate2D) theCoordinate
{
    self = [super init];
    if (self) {
        _title = [theTitle copy];
        _subTitle = [theSubTitle copy];
        _coordiante2D = theCoordinate;
    }
    return self;
}
&lt;/pre&gt;然後，除了原來的網路基因外，我希望在另外增加兩個資訊在地圖上，接著修改&lt;br /&gt;
&lt;pre class=&quot;brush:objc&quot;&gt;//MapKit_PracticeViewController.m
-(void)loadView
{
    [super loadView];
    mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
    MKCoordinateRegion region;
    region.center.latitude = 25.044;
    region.center.longitude = 121.526;
    MKCoordinateSpan span;
    span.latitudeDelta  = .0015;
    span.longitudeDelta = .0015;
    region.span = span;
    [mapView setRegion:region animated:YES];

    CLLocationCoordinate2D location0 = {25.044423,121.52673};
    Annotation *myAnnotation0 = [[Annotation alloc] initWhithTitle:@&quot;網路基因資訊股份有限公司&quot;
                                                          subTitle:@&quot;電話：02-23955378&quot; 
                                                     andCoordiante:location0];
    CLLocationCoordinate2D location1 = {25.04411,121.52534};
    Annotation *myAnnotation1 = [[Annotation alloc] initWhithTitle:@&quot;遠東國際商業銀行&quot; 
                                                          subTitle:@&quot;電話：02-2327-8898&quot; 
                                                     andCoordiante:location1];
    CLLocationCoordinate2D location2 = {25.04443,121.52579};
    Annotation *myAnnotation2 = [[Annotation alloc] initWhithTitle:@&quot;文化大學推廣教育部&quot; 
                                                          subTitle:@&quot;電話：02-2356-7356&quot; 
                                                     andCoordiante:location2];
    
    [mapView addAnnotations:[NSArray arrayWithObjects:myAnnotation0, myAnnotation1, myAnnotation2, nil]];
    [myAnnotation0 release];
    [myAnnotation1 release];
    [myAnnotation2 release];

    [self.view addSubview:mapView];
}
&lt;/pre&gt;執行後的結果如下&lt;br /&gt;
&lt;div&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfpqJaxYjKKxY3ErRVRLZkZYlRDJH2j4OPJVXtRkNr4r9qfK3g9fYiJnVJhj62gcIsHBGD-X50Y0PB7PVzLsVwVhiKvdoqjNt81CP_A9O3ggX5DQlVrczLfGb8-9ZNSO4ih_Rh2Q2BSv-_/s1600/%25E8%259E%25A2%25E5%25B9%2595%25E5%25BF%25AB%25E7%2585%25A7+2011-05-05+%25E4%25B8%258A%25E5%258D%25882.44.46.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; width=&quot;205&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfpqJaxYjKKxY3ErRVRLZkZYlRDJH2j4OPJVXtRkNr4r9qfK3g9fYiJnVJhj62gcIsHBGD-X50Y0PB7PVzLsVwVhiKvdoqjNt81CP_A9O3ggX5DQlVrczLfGb8-9ZNSO4ih_Rh2Q2BSv-_/s400/%25E8%259E%25A2%25E5%25B9%2595%25E5%25BF%25AB%25E7%2585%25A7+2011-05-05+%25E4%25B8%258A%25E5%258D%25882.44.46.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
將Annotation Class修改後，使用起來會更方便，在增加新的資訊的時候也不用一個Class宣告一個資訊造成之後的管理不方便；關於MKAnnotionView以及MKMapDelegate的部份因為內容好像有點太長了，所以就不在這篇繼續下去了，會在下一篇的練習中在分享給大家。&lt;br /&gt;
&lt;br /&gt;
最後希望這篇內容可以對大家有幫助，對於文章內容有錯誤或者建議的地方，也請大家多多指教，謝謝。&lt;br /&gt;
&lt;br /&gt;
參考內容：&lt;br /&gt;
Introduction to MapKit on iOS Tutorial &lt;a href=&quot;http://www.raywenderlich.com/2847/introduction-to-mapkit-on-ios-tutorial&quot; target=&quot;_blank&quot;&gt;Link&lt;/a&gt;&lt;br /&gt;
Map Kit Framework Reference &lt;a href=&quot;http://developer.apple.com/library/ios/#documentation/MapKit/Reference/MapKit_Framework_Reference/_index.html&quot; target=&quot;_blank&quot;&gt;Link&lt;/a&gt;&lt;br /&gt;
MKMapView Class Reference &lt;a href=&quot;http://developer.apple.com/library/ios/#documentation/MapKit/Reference/MKMapView_Class/MKMapView/MKMapView.html#//apple_ref/doc/uid/TP40008205&quot; target=&quot;_blank&quot;&gt;Link&lt;/a&gt;&lt;br /&gt;
MKAnnotation Protocol Reference &lt;a href=&quot;http://developer.apple.com/library/ios/#documentation/MapKit/Reference/MKAnnotation_Protocol/Reference/Reference.html#//apple_ref/doc/uid/TP40008208&quot; target=&quot;_blank&quot;&gt;Link&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://greenchiou.blogspot.com/feeds/8468222062843731465/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://greenchiou.blogspot.com/2011/05/ios-sdk-with-mapkit-google-map-1.html#comment-form' title='6 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/8468222062843731465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/8468222062843731465'/><link rel='alternate' type='text/html' href='http://greenchiou.blogspot.com/2011/05/ios-sdk-with-mapkit-google-map-1.html' title='iOS SDK with MapKit (Google Map) 練習 (1)'/><author><name>綠</name><uri>http://www.blogger.com/profile/10866243185938517560</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiROppWVtpB4GpYxBDY_T-AZzPrlMgq71-UD2AMaBewAxJAFPEBE5ccXU3vzceeteWEfSPnvBxBPhFejD55iKs_gygYzs1LCW70HmCi4vUQjwnrisgqhAqI7d06MQ6epw/s220/IMG_6544.JPG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZJNiWx7H4ZmHYm0Mh9ecP6xykKfqpf4iI4N4n59sTXs9l7RmUkKEgvLi9IpRDosbygI884St3eWWxhnECuism8wDLfdL94orjrYjDAzj5pfI1B6L5sawE62ylwX1yEin1lM5DpFjVdFNr/s72-c/%25E8%259E%25A2%25E5%25B9%2595%25E5%25BF%25AB%25E7%2585%25A7+2011-05-04+%25E4%25B8%258B%25E5%258D%25885.08.25.png" height="72" width="72"/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7926047175171636650.post-222301219649908677</id><published>2011-04-26T12:33:00.001+08:00</published><updated>2011-04-26T13:59:48.895+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iOS"/><category scheme="http://www.blogger.com/atom/ns#" term="Quartz 2D"/><title type='text'>iOS SDK 認識 Quartz 2D (2)</title><content type='html'>Hi everyone，在上一篇 &lt;a href=&quot;http://greenchiou.blogspot.com/2011/04/ios-sdk-quartz-2d-1.html&quot; target=&quot;_blank&quot;&gt;iOS SDK 認識 Quartz 2D (1)&lt;/a&gt;，我們成功的將冗長的程式碼包裝成一個class，並賦予這個class讓其可以有旋轉以及縮放的功能；接著這次要介紹的功能是如果播放動態，介紹其相關的原理。&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;我會將閱讀文章的人視作對 c / obj-c 以及 iOS有一定的認識，因此在obj-c/c的一些使用內容將不會有太多的解釋。另外會以AS3為對照的語言，作一些相關的引用跟對照。&lt;br /&gt;
&lt;br /&gt;
此篇將延續上兩篇使用的專案&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
動態製作的原理，是依照連環圖動畫來製作(&lt;a href=&quot;http://www.youtube.com/watch?v=-TSi9oQrsN4&quot; target=&quot;target&quot;&gt;filpnook animation&lt;/a&gt;)，使用一張一張圖讓他去播放(可以參考前面連結的影片)，在瞭解動態如何製作之後，我們假設現在要製作一個數字跳動的動態，我希望能已30fps重複播放六張圖片，但如果這樣製作六張分開的圖片讓程式載入，不只在檔案上會增加很多圖檔，程式也必需要一直載入圖片來播放，這樣管理起又變得麻煩。 所以我們將會把一個物件(人物、角色...)的動態坐在一張檔案裡，圖片製作的方式如下：&lt;br /&gt;
&lt;div&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXCaJ9cD0QCoBqy4dXHY6jZCderadEQaRuNLlX_q77YOe8KT9ZogfVOsdmXAflT3oYelHnOc8uHlLNRWnyEnqrFljOdcSje83wUjNVbsM0DJmH9tebMzB5vpspTxDuql_BLIeJB7KKP59d/s1600/sample.png&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;280&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXCaJ9cD0QCoBqy4dXHY6jZCderadEQaRuNLlX_q77YOe8KT9ZogfVOsdmXAflT3oYelHnOc8uHlLNRWnyEnqrFljOdcSje83wUjNVbsM0DJmH9tebMzB5vpspTxDuql_BLIeJB7KKP59d/s400/sample.png&quot; width=&quot;280&quot; /&gt;&lt;/a&gt;&lt;/div&gt;一個Row, 可以做一方向(狀態)的動態, 將物件所有的動態做成一張圖(atlas 地圖集)，用來載入程式來動作。&lt;br /&gt;
&lt;br /&gt;
接著我們建立一個新的Class，繼承 Sprite 命名為 AtlasSprite&lt;br /&gt;
AltasSprite.h:&lt;br /&gt;
&lt;pre class=&quot;brush:objc&quot;&gt;#import &quot;Sprite.h&quot;
@interface AtlasSprite : Sprite {
    UIImage *atlas;//地圖集
    CGImageRef image;//Quartz 圖片格式
    CGFloat atlasWidth;//寬
    CGFloat atlasHeight;//高度
    CGRect clipRect;//紀錄圖片位置
    int rows;//地圖集有幾行
    int columns;//幾欄
    int frame;//用來紀錄播放動態的影格
}
@property (retain, nonatomic) UIImage *atlas;
@property (assign) CGFloat atlasWidth,atlasHeight;
@property (assign) CGRect clipRect;
@property (assign) CGImageRef image;
@property (assign) int rows,columns,frame;
- (id) initWithFile:(NSString*) fileName withRows:(int)atlasRows withColumns:(int) atlasColumns;
&lt;/pre&gt;在AltasSprite中，我們宣告了八個新參數以及一個Method，接著我們進行Class的實作，這邊我會將method分開解釋，程式碼方面會比較零散，請大家自己注意一下&lt;br /&gt;
AltasSprite.m&lt;br /&gt;
&lt;pre class=&quot;brush:objc; highlight:[23]&quot;&gt;- (id) initWithFile:(NSString*) fileName withRows:(int)atlasRows withColumns:(int) atlasColumns;
{
    self = [super init];
    if(self)
    {
        atlas = [[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle]
                                                           pathForResource:fileName ofType:nil]
                   ];
        CGImageRef img = [atlas CGImage];
        image = img;
        int width0 = CGImageGetWidth(image);
        int height0 = CGImageGetHeight(image);
        if(atlasRows &amp;lt; 1) atlasRows = 1;
        if(atlasColumns &amp;lt; 1) atlasColumns = 1;
        atlasWidth = width0;
        atlasHeight = height0;
        rows = atlasRows;
        columns = atlasColumns;
        width = round(width0/columns);
        height = round(height0/rows);
        CGFloat w2 = width*0.5;
        CGFloat h2 = height*0.5;
        clipRect = CGRectMake(-width*0.5, -height*0.5, width, height);
        frame = 0;
    }
    return self;
}
&lt;/pre&gt;21行highlight的部份，將我們原點轉移到中心點, 這就是之後我們呈現圖案的範圍大小 &lt;br /&gt;
&lt;div&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_e7uOr5Usadqty_rVENAzz1qnRczAl8bLCIVPSaMZtsPYuPEsv-ztoem4MKPgcc5H4XUJR_AkQpYvk09oEwfOSvUiHviTX81QeUCVWTVVLmeLLWJeZul3j30SEVnxUWyLxVPqCBzcUvTO/s320/sprite_location2.jpg&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;163&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_e7uOr5Usadqty_rVENAzz1qnRczAl8bLCIVPSaMZtsPYuPEsv-ztoem4MKPgcc5H4XUJR_AkQpYvk09oEwfOSvUiHviTX81QeUCVWTVVLmeLLWJeZul3j30SEVnxUWyLxVPqCBzcUvTO/s320/sprite_location2.jpg&quot; width=&quot;188&quot; /&gt;&lt;/a&gt;&lt;/div&gt;接著我們覆寫drawBody Method &lt;br /&gt;
&lt;pre class=&quot;brush:objc;highlight:[3,4,11,13]&quot;&gt;-(void) drawBody:(CGContextRef)context
{
    int r0 = floor(frame/columns);
    int c0 = frame-columns*r0;
    CGFloat w2 = width*0.5;
    CGFloat h2 = height*0.5;
    CGFloat u = c0*width+w2;
    CGFloat v = atlasHeight - (r0*height+h2);
    
    CGContextBeginPath(context);
    CGContextAddRect(context, clipRect);
    CGContextClip(context);
    CGContextDrawImage(context, CGRectMake(-u, -v, atlasWidth, atlasHeight), image);
}
&lt;/pre&gt;在3-4行程式碼的地方我們先求出我們要對應的row &amp;amp; column 接著運算出對應的在地圖集上的坐標，接著我們增加即將製作圖形的大小方塊，接著使用 CGContextDrawImage 的方式，在地圖集上將我們想呈現的出區塊畫出來(參考下圖)。&lt;br /&gt;
&lt;div&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6bR-vFpFdjfFQ8kkrlDAkh8KuxifUTuiLrq4Sm80SImoWSE6Pprkc6ZmDKt2o_TPo7VhBxvnyvfnIQ2JD-ve6BqPsw3Ox60Gz5pxFnuM85dOh4jYQGWC6NIJVqaMViOFY28ScPD4pA9tt/s1600/atlas1.jpg&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;362&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6bR-vFpFdjfFQ8kkrlDAkh8KuxifUTuiLrq4Sm80SImoWSE6Pprkc6ZmDKt2o_TPo7VhBxvnyvfnIQ2JD-ve6BqPsw3Ox60Gz5pxFnuM85dOh4jYQGWC6NIJVqaMViOFY28ScPD4pA9tt/s400/atlas1.jpg&quot; width=&quot;342&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaAOBq0rfdbBze9xQoAw0KWQl_IOpECLVuFny9XBr5K9J68FowrVuEOXFi1le2_Ys2HxvEKrYjjcZeHEtLmBp1AJz7X2I0cxN0lE2-yoreFry4sHGQ9YGF_XWh5q5FqpMQ1q7sFMmI_VUA/s1600/atlas2.jpg&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;362&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaAOBq0rfdbBze9xQoAw0KWQl_IOpECLVuFny9XBr5K9J68FowrVuEOXFi1le2_Ys2HxvEKrYjjcZeHEtLmBp1AJz7X2I0cxN0lE2-yoreFry4sHGQ9YGF_XWh5q5FqpMQ1q7sFMmI_VUA/s400/atlas2.jpg&quot; width=&quot;362&quot; /&gt;&lt;/a&gt;&lt;/div&gt;最後別忘了要釋放我們使用的圖片資源 AtlasSprite.m &lt;br /&gt;
&lt;pre class=&quot;brush:objc&quot;&gt;-(void)dealloc
{
    [atlas release];
    CGImageRelease(image);
    [super dealloc];
}
&lt;/pre&gt;接著回到Quartz2DView進行修改： &lt;br /&gt;
&lt;pre class=&quot;brush:objc&quot;&gt;//Quartz2Dview.h
#import &quot;Sprite.h&quot;
#import &quot;AtlasSprite.h&quot;
@interface Quartz2DView : UIView {
    
    //Sprite *mySprite;
    AtlasSprite *atlasSprite;
    NSTimer *timer;
    int aframe;
}
-(void) dt:(NSTimer *) theTimer;
@end

//Quartz2DView.m
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        self.backgroundColor = [UIColor clearColor];
        aframe = 0;
        atlasSprite = [[AtlasSprite alloc] initWithFile:@&quot;sample.png&quot; 
                                               withRows:7 
                                               withColumns:7
                      ];
        atlasSprite.x = 100;
        atlasSprite.y = 100;
        atlasSprite.frame = 1;//使呈現的圖案＝01
    }
    return self;
}
-(void) drawRect:(CGRect)rect
{
    
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    CGContextSaveGState(context);
    
    CGAffineTransform t0 = CGContextGetCTM(context);
    t0 = CGAffineTransformInvert(t0);
    CGContextConcatCTM(context, t0);
    
    [atlasSprite updateBox];
    [atlasSprite draw:context];
    
    CGContextRestoreGState(context); 
}
&lt;/pre&gt;執行後的結果如下圖：&lt;br /&gt;
&lt;div&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5nXcfJSDY_-mBO_Yce_O7d5dx02I3QiPRprzkGO7fBUNcYO53CyZwTS8lwfxLK4HZNjy0jCJ6ey6_QRcb80cM1YsnZ3dHbOm6DAM_xCG535rQMlTJcVZcTX3ugl5fmZswQ_Zui7SV3axR/s1600/%25E8%259E%25A2%25E5%25B9%2595%25E5%25BF%25AB%25E7%2585%25A7+2011-04-26+%25E4%25B8%258A%25E5%258D%258811.53.07.png&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5nXcfJSDY_-mBO_Yce_O7d5dx02I3QiPRprzkGO7fBUNcYO53CyZwTS8lwfxLK4HZNjy0jCJ6ey6_QRcb80cM1YsnZ3dHbOm6DAM_xCG535rQMlTJcVZcTX3ugl5fmZswQ_Zui7SV3axR/s400/%25E8%259E%25A2%25E5%25B9%2595%25E5%25BF%25AB%25E7%2585%25A7+2011-04-26+%25E4%25B8%258A%25E5%258D%258811.53.07.png&quot; width=&quot;205&quot; /&gt;&lt;/a&gt;&lt;/div&gt;到這邊整個Class已經完成了，接下來要做的就是讓動態可以跑起來，我們建立一個 NSTimer 來處理動態的動作  &lt;br /&gt;
&lt;pre class=&quot;brush:objc&quot;&gt;- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        self.backgroundColor = [UIColor clearColor];
        aframe = 0;
        atlasSprite = [[AtlasSprite alloc] initWithFile:@&quot;sample.png&quot; 
                                               withRows:7 
                                               withColumns:7
                      ];
        atlasSprite.x = 100;
        atlasSprite.y = 100;
        //atlasSprite.frame = 1;//使呈現的圖案＝01
        timer = [NSTimer scheduledTimerWithTimeInterval:1/30.0
                                               target:self
                                             selector:@selector(dt:)
                                             userInfo:nil
                ];
    }
    return self;
}
-(void) dt:(NSTimer *) theTimer
{
    aframe+1 &amp;lt; atlasSprite.columns ? ++aframe : (aframe=0);
    atlasSprite.frame = aframe;
    [self setNeedsDisplay];
}
&lt;/pre&gt;執行出現的話面就不在提供了，畫面的紅色區塊將會00 ~ 06之間重複播放。&lt;br /&gt;
&lt;br /&gt;
那麼，這篇文章到這邊也就結束了，可能大家對於AltasSprite.m 的 drawBody會有較多的疑問， 這邊牽扯到了一些數學計算，讀起來可能會比較不容易瞭解，所以附上了兩個圖片來讓大家理解。&lt;br /&gt;
總算是打完這篇了，這篇的文字敘述越來越少了，大多數的內容也都是使用程式碼和圖片來帶過 囧rz ..(變懶了)；自己最近做練習，其實也是跌跌撞撞，debug花了2hrs才發現是使用到了method不是當前需要的，其實程式碼根本沒有錯誤，只能希望自己盡量小心不要再犯一樣的錯誤；最後在這邊希望這篇也能幫助到大家，如果內容有任何錯誤或者是指教，也請不要吝嗇，謝謝。&lt;br /&gt;
&lt;br /&gt;
參考資料:&lt;br /&gt;
iOS Developer Library &lt;a href=&quot;http://developer.apple.com/library/ios/#documentation/GraphicsImaging/Reference/CGContext/Reference/reference.html&quot; target=&quot;_blank&quot;&gt;CGContext Reference&lt;/a&gt;&lt;br /&gt;
iOS Developer Library &lt;a href=&quot;http://developer.apple.com/library/ios/#documentation/GraphicsImaging/Reference/CGImage/Reference/reference.html&quot; target=&quot;_blank&quot;&gt;CGImage Reference&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://furnacedigital.blogspot.com/2010/12/%E4%BD%BF%E7%94%A8%E5%96%AE%E5%BC%B5%E5%BD%B1%E5%83%8F%E4%BE%86%E8%A3%BD%E4%BD%9Cflipbook%E5%8B%95%E7%95%AB%E6%95%88%E6%9E%9C.html&quot; target=&quot;_blank&quot;&gt;使用單張影像來製作flipbook動畫效果&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.myiphoneadventure.com/xcode_witha_the_iphone_sdk/ios-sdk-tutorial-flip-book-style-animation-part-1-of-2&quot; target=&quot;_blank&quot;&gt;iOS SDK Tutorial: Flip Book Style Animation, part 1 of 2&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.myiphoneadventure.com/xcode_witha_the_iphone_sdk/ios-sdk-tutorial-flip-book-style-animation-part-2-of-2&quot; target=&quot;_blank&quot;&gt;iOS SDK Tutorial: Flip Book Style Animation, part 2 of 2&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
範例下載: &lt;a href=&quot;http://1001.webgene.tw/green/mobile/resource/Sample3.zip&quot; target=&quot;_blank&quot;&gt;Sample3.zip&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
相關文章：&lt;br /&gt;
&lt;a href=&quot;http://greenchiou.blogspot.com/2011/04/ios-sdk-quartz-2d-0.html&quot; target=&quot;_blank&quot;&gt;iOS SDK 認識 Quartz 2D(0)&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://greenchiou.blogspot.com/2011/04/ios-sdk-quartz-2d-1.html&quot; target=&quot;_blank&quot;&gt;iOS SDK 認識 Quartz 2D(1)&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://greenchiou.blogspot.com/feeds/222301219649908677/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://greenchiou.blogspot.com/2011/04/ios-sdk-quartz-2d-2.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/222301219649908677'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/222301219649908677'/><link rel='alternate' type='text/html' href='http://greenchiou.blogspot.com/2011/04/ios-sdk-quartz-2d-2.html' title='iOS SDK 認識 Quartz 2D (2)'/><author><name>綠</name><uri>http://www.blogger.com/profile/10866243185938517560</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiROppWVtpB4GpYxBDY_T-AZzPrlMgq71-UD2AMaBewAxJAFPEBE5ccXU3vzceeteWEfSPnvBxBPhFejD55iKs_gygYzs1LCW70HmCi4vUQjwnrisgqhAqI7d06MQ6epw/s220/IMG_6544.JPG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXCaJ9cD0QCoBqy4dXHY6jZCderadEQaRuNLlX_q77YOe8KT9ZogfVOsdmXAflT3oYelHnOc8uHlLNRWnyEnqrFljOdcSje83wUjNVbsM0DJmH9tebMzB5vpspTxDuql_BLIeJB7KKP59d/s72-c/sample.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7926047175171636650.post-7763126830178183989</id><published>2011-04-21T18:20:00.006+08:00</published><updated>2011-04-22T15:17:38.379+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Facebook"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript"/><category scheme="http://www.blogger.com/atom/ns#" term="Open Graph protocol"/><title type='text'>使用Facebook JavaScript SDK 來處理點 &quot;讚&quot; 的動作</title><content type='html'>Hi all，今天臨時被問了Facebook&#39;s Social Plugins一個需求，就是當User點擊網頁上面的Like Button的時候，可不可以順便發文到自己的塗鴉牆上，圖文的內容我們可以自己依照我們想造呈現方式去設定(使用SDK來發佈)；這篇文章將會結合到一些 Open Graph protocal的內容，如果對於如何使用 Facebook JavaScript SDK的人，可以先參考我之前寫的&lt;a href=&quot;http://greenchiou.blogspot.com/2010/12/javascript-facebook-sdk-width-graphic.html&quot; target=&quot;_blank&quot;&gt;使用 Javascript Facebook SDK with Graphic API&lt;/a&gt;。&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;對不起，昨天發布這篇文章，最後發現內容有一些地方必須要被更正，其中以點讚後再去登入的動作會被瀏覽器擋住的問題最大，原因是因為，登入的動作不是使用者自己去動作的，因此我會在文章的內容上做一些修改。目前已修正內容&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
一開始我們先介紹不會使用到API部分的地方，也就是不需要建立取得一個APP_ID(這邊這樣的說法可能會讓人有點混淆，之後我們會配合程式碼來加以解釋)，那麼首先我們先建立一個&lt;a href=&quot;http://developers.facebook.com/docs/reference/plugins/like/&quot; target=&quot;_blank&quot;&gt;Like Button&lt;/a&gt;，設定好相關的內容&lt;br /&gt;
&lt;div&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiU_AhpEkF5LaxA_3h64KthfsydUTZRg-sAy05UHPYaAJMpV8j-15p00-sGlV-GBr0OwDvu_PJo5n-NmcmbMCyMMPBMQ1yLqgPI3_dRQuh5Zwzmt8SBv64vHmmCeVjwrFSy41X0ceVQhXNI/s1600/p1.jpg&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiU_AhpEkF5LaxA_3h64KthfsydUTZRg-sAy05UHPYaAJMpV8j-15p00-sGlV-GBr0OwDvu_PJo5n-NmcmbMCyMMPBMQ1yLqgPI3_dRQuh5Zwzmt8SBv64vHmmCeVjwrFSy41X0ceVQhXNI/s320/p1.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;點下Get Code複製XFBML部分的程式碼貼到頁面上&lt;br /&gt;
&lt;div&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZ_BemFKDLlgjRdfFnbtxzOkpLJZ_ky2MX4Innx9HNRp5UUKSRtYPFjdzyjq9vIj77PI5CNEAEFadbY2fizic66tKvgCOV_m6tAD6gHR8mGoylHNX2-whd4HWIP9fDUUXTQEkjUKitXTsr/s1600/p2.jpg&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZ_BemFKDLlgjRdfFnbtxzOkpLJZ_ky2MX4Innx9HNRp5UUKSRtYPFjdzyjq9vIj77PI5CNEAEFadbY2fizic66tKvgCOV_m6tAD6gHR8mGoylHNX2-whd4HWIP9fDUUXTQEkjUKitXTsr/s400/p2.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;接著到同一個頁面下方的 Step 2 Get Open Graph Tags 地方同樣填入相關的資訊並複製下來貼到html上。&lt;br /&gt;
&lt;div&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0kaDOJFi2tb_3vkcunSDn59Qks0qZTy5s6LhVofG-emvhUyQ_Aym6-sTFa2TJTZs1FBKB_tLFrnsIVfc46MN1WbLuzPcVQiGMukQ9Mo02sa0ZJHeKPbTxqejV_0ns5oTSFcTAgYW_ardx/s1600/p3.jpg&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0kaDOJFi2tb_3vkcunSDn59Qks0qZTy5s6LhVofG-emvhUyQ_Aym6-sTFa2TJTZs1FBKB_tLFrnsIVfc46MN1WbLuzPcVQiGMukQ9Mo02sa0ZJHeKPbTxqejV_0ns5oTSFcTAgYW_ardx/s400/p3.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
上面兩個動作完成後，您的程式碼應該會類似下面&lt;br /&gt;
&lt;pre class=&quot;brush:js; html-script: true; highlight:11&quot;&gt;&amp;lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xmlns:fb=&quot;http://www.facebook.com/2008/fbml&quot;&amp;gt;
&amp;lt;head&amp;gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;meta property=&quot;og:title&quot; content=&quot;Facebook Event Test&quot;/&amp;gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;meta property=&quot;og:type&quot; content=&quot;author&quot; /&amp;gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;meta property=&quot;og:url&quot; content=&quot;http://1001.webgene.tw/green/facebook/event/&quot;/&amp;gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;meta property=&quot;og:image&quot; content=&quot;http://1001.webgene.tw/green/facebook/event/fb_event.png&quot;/&amp;gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;meta property=&quot;og:site_name&quot; content=&quot;http://greenchiou.blogspot.com/&quot; /&amp;gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;meta property=&quot;fb:admins&quot; content=&quot;[YOU_FACEBOOK_ID]&quot; /&amp;gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;meta property=&quot;og:description&quot; content=&quot;Test Share Video to Facebook&quot;/&amp;gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;title&amp;gt;Facebook Event Html Title&amp;lt;/title&amp;gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;script src=&quot;http://connect.facebook.net/zh_TW/all.js#xfbml=1&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;div id=&quot;fb-root&quot;&amp;gt;&amp;lt;/div&amp;gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;fb:like href=&quot;http://1001.webgene.tw/green/facebook/event/&quot; show_faces=&quot;true&quot; width=&quot;450&quot; font=&quot;&quot;&amp;gt;&amp;lt;/fb:like&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;上面highlight的部分你會注意到載入的js後面帶了&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: red;&quot;&gt;#xfbml=1&lt;/span&gt;的參數，如果沒有帶入這個參數，你的Link Button將無法正確成現在你的html上，要特別的注意；接著，我們加入Like Button被點擊like跟unlike的事件Listener，html修改如下：&lt;br /&gt;
&lt;pre class=&quot;brush:js;html-script: true&quot;&gt;&amp;lt;body&amp;gt;
    &lt;div id=&quot;result&quot;&gt;&lt;/div&gt;&lt;div id=&quot;fb-root&quot;&gt;&lt;/div&gt;&lt;script type=&quot;text/javascript&quot;&gt;
 window.fbAsyncInit = function() {
     //建立Like Button 點擊呈現 link 的eventhandle
     FB.Event.subscribe(&#39;edge.create&#39;, function(response) {
         //將傳回來的資訊顯示在 div id=&quot;result&quot;內
                document.getElementById(&#39;result&#39;).innerHTML = response;
                alert(&quot;like&quot;);
     });
     //建立Like Button 點擊呈現 unlike 的eventhandle
     FB.Event.subscribe(&#39;edge.remove&#39;, function(response) {
                document.getElementById(&#39;result&#39;).innerHTML = response;
  alert(&quot;unlike&quot;);
     });
 };
    
&lt;/script&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;fb:like href=&quot;http://1001.webgene.tw/green/facebook/event/&quot; show_faces=&quot;true&quot; width=&quot;450&quot; font=&quot;&quot;&amp;gt;&amp;lt;/fb:like&amp;gt;
&amp;lt;/body&amp;gt;
&lt;/pre&gt;然後測試點擊Like Button，讓Like Button處在Like跟unLike的情況會分別跳出alert &quot;like&quot;/&quot;unlike&quot;。&lt;br /&gt;
&lt;br /&gt;
接下來我們使用API的方式來修改讓他符合我們所想要達到的需求：&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: red;&quot;&gt;&lt;s&gt;先修html改載入js的部分，將後面的#xfbml=1拿掉&lt;/s&gt;&lt;/span&gt; &lt;b&gt;這邊多次測試後，會有一個怪異的問題，所以請大家在這邊注意一下還是維持原樣js後面帶有#xfbml=1&lt;/b&gt;&lt;br /&gt;
&lt;pre class=&quot;brush:html&quot;&gt;&lt;script src=&quot;http://connect.facebook.net/zh_TW/all.js#xfbml=1&quot;&gt;
&lt;/script&gt;
&lt;/pre&gt;接著修改js的部分&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:js; highlight:2&quot;&gt;window.fbAsyncInit = function() {
    FB.init({appId: &quot;162485500442847&quot;, status: true, cookie: true, xfbml: true});
    FB.Event.subscribe(&#39;edge.create&#39;, function(response) {
        document.getElementById(&#39;result&#39;).innerHTML = response;
        alert(&quot;like&quot;);
    });
    FB.Event.subscribe(&#39;edge.remove&#39;, function(response) {
         document.getElementById(&#39;result&#39;).innerHTML = response;
        alert(&quot;unlike&quot;);
    });
};
&lt;/pre&gt;因為我們使用了FB.init來初始化我們的Facebook App，裡面有一個xfbml: true的參數，將這參數設為true，我們就可以將js載入的部分修改成上面的樣子，也不會影響到我們使用xfbml的social plugins的Like Button。接著我們加入一個發佈訊息的function，並且在點擊Like Button的並呈現Like時候，&lt;s&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: red;&quot;&gt;判斷是否以登入跟是否取得premission，如果以登入並且已取得權限，則&lt;/span&gt;&lt;/s&gt;彈出對話框來發佈訊息。&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;因為登入的動作未經使用者自行點擊，最造成被瀏覽器阻擋的問題，為了避免病解決這樣的問題，我們將修改、增加我們的原始碼。&lt;/b&gt;&lt;br /&gt;
首先，在html的部分除了原本的Like Button 外，我們也加上一個Login Button，並且個字包在一個div底下，並預設成看不見的狀況。&lt;br /&gt;
&lt;pre class=&quot;brush:html&quot;&gt;&lt;div id=&quot;login&quot; style=&quot;display:none;&quot;&gt;&lt;fb:login-button show-faces=&quot;false&quot; width=&quot;200&quot; max-rows=&quot;1&quot; perms=&quot;publish_stream&quot;&gt;&lt;/fb:login-button&gt;
&lt;/div&gt;&lt;div id=&quot;like&quot; style=&quot;display:none;&quot;&gt;&lt;fb:like href=&quot;http://1001.webgene.tw/green/facebook/event/&quot; show_faces=&quot;true&quot; width=&quot;450&quot; font=&quot;&quot;&gt;&lt;/fb:like&gt;
&lt;/div&gt;&lt;/pre&gt;並且加上登入成功後的事件偵聽&lt;br /&gt;
&lt;pre class=&quot;brush:js&quot;&gt;FB.Event.subscribe(&#39;auth.login&#39;,function(response){
 document.getElementById(&#39;like&#39;).style.display=&quot;block&quot;;
 document.getElementById(&#39;login&#39;).style.display=&quot;none&quot;;
});
&lt;/pre&gt;接著在進到頁面的時候，先抓取是否有登入的狀況；並判斷有登入的話是不是有相關的permisson，如果沒有的話，就顯示登入。&lt;br /&gt;
&lt;pre class=&quot;brush:js&quot;&gt;FB.getLoginStatus(function(response) {
 if (response.session) {
  //特別注意傳回來的 perms 是 string 不是array 
  if(response.perms.indexOf(&quot;publish_stream&quot;) &gt;= 0 )
  {
   document.getElementById(&#39;like&#39;).style.display=&quot;block&quot;;
  }
  else document.getElementById(&#39;login&#39;).style.display=&quot;block&quot;;
 } else {
  document.getElementById(&#39;login&#39;).style.display=&quot;block&quot;;
 }
});
&lt;/pre&gt;接著修改 FB.Event.subscribe 的部分&lt;br /&gt;
&lt;pre class=&quot;brush:js&quot;&gt;FB.Event.subscribe(&#39;edge.create&#39;, function(response) {
    document.getElementById(&#39;result&#39;).innerHTML = response;
    post_feed();
});
&lt;/pre&gt;&lt;b&gt;4/22 14:58 修改&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
加入function post_feed()&lt;br /&gt;
&lt;pre class=&quot;brush:js&quot;&gt;function post_feed()
{
    FB.ui({
        method: &#39;feed&#39;,
        name: &#39;Facebook Event Html Title&#39;,
        link: &#39;http://1001.webgene.tw/green/facebook/event/&#39;,
        picture: &#39;http://1001.webgene.tw/green/facebook/event/fb_event.png&#39;,
        caption: &#39;Green Test Facebook Event &#39;,
        description: &#39;Greens Facebook Event Test&#39;,
        message: &#39;Facebook Event is easy!&#39;
    },
    function(response) {
        if (response &amp;amp;&amp;amp; response.post_id) {
            alert(&#39;Post was published.&#39;);
        } else {
            alert(&#39;Post was not published.&#39;);
        }}
    );
}
&lt;/pre&gt;&lt;br /&gt;
最後再進行測試，測試的結果可以參考下圖&lt;br /&gt;
&lt;div&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAFJOKEq49inKThyphenhyphencNU0mQucnStAjYN7Ae3y8AdodSuUu15Y2EOe45w9QWCxU1hgqQ8fWNVNFkb4t3J8j9YVhdNHSNAifqA-tr9zg2GqyzRAbAM2b7XTFUaTM8TIrr0GSfWmPQShHFvoS1/s1600/p4.jpg&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAFJOKEq49inKThyphenhyphencNU0mQucnStAjYN7Ae3y8AdodSuUu15Y2EOe45w9QWCxU1hgqQ8fWNVNFkb4t3J8j9YVhdNHSNAifqA-tr9zg2GqyzRAbAM2b7XTFUaTM8TIrr0GSfWmPQShHFvoS1/s400/p4.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
除了上面介紹的2個事件之外，FB還提供了9個事件可以被偵聽，這11個事件中有4個是專門給xfbml使用的，詳細的資訊可以參考 &lt;a href=&quot;http://developers.facebook.com/docs/reference/javascript/FB.Event.subscribe/&quot; target=&quot;_blank&quot;&gt;FB.Event.subscribe&lt;/a&gt; 的內容，就不一一列舉說明了。&lt;br /&gt;
&lt;br /&gt;
這篇文章就介紹到這邊了，希望對大家有幫助，如果有錯誤或者建議，也請大家不要吝嗇，謝謝大家。&lt;br /&gt;
&lt;br /&gt;
參考網址：&lt;br /&gt;
Facebook Developers &lt;a href=&quot;http://developers.facebook.com/docs/reference/javascript/FB.Event.subscribe/&quot; target=&quot;_blank&quot;&gt;FB.Event.subscribe&lt;/a&gt;&lt;br /&gt;
Facebook Developers &lt;a href=&quot;http://developers.facebook.com/docs/reference/plugins/like/&quot; target=&quot;_blank&quot;&gt;Social Plugins Like Button&lt;/a&gt;&lt;br /&gt;
範例網址：&lt;br /&gt;
&lt;a href=&quot;http://1001.webgene.tw/green/facebook/event/&quot; target=&quot;_blank&quot;&gt;Demo&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
相關文章：&lt;br /&gt;
&lt;a href=&quot;http://greenchiou.blogspot.com/2011/04/facebook-open-graph-protocal.html&quot; target=&quot;_blank&quot;&gt;Facebook 使用 Open Graph protocal 輕鬆分享影片&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://greenchiou.blogspot.com/2010/12/javascript-facebook-sdk-width-graphic.html&quot; target=&quot;_blank&quot;&gt;使用 Javascript Facebook SDK with Graphic API&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://greenchiou.blogspot.com/feeds/7763126830178183989/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://greenchiou.blogspot.com/2011/04/facebook-javascript-sdk.html#comment-form' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/7763126830178183989'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/7763126830178183989'/><link rel='alternate' type='text/html' href='http://greenchiou.blogspot.com/2011/04/facebook-javascript-sdk.html' title='使用Facebook JavaScript SDK 來處理點 &quot;讚&quot; 的動作'/><author><name>綠</name><uri>http://www.blogger.com/profile/10866243185938517560</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiROppWVtpB4GpYxBDY_T-AZzPrlMgq71-UD2AMaBewAxJAFPEBE5ccXU3vzceeteWEfSPnvBxBPhFejD55iKs_gygYzs1LCW70HmCi4vUQjwnrisgqhAqI7d06MQ6epw/s220/IMG_6544.JPG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiU_AhpEkF5LaxA_3h64KthfsydUTZRg-sAy05UHPYaAJMpV8j-15p00-sGlV-GBr0OwDvu_PJo5n-NmcmbMCyMMPBMQ1yLqgPI3_dRQuh5Zwzmt8SBv64vHmmCeVjwrFSy41X0ceVQhXNI/s72-c/p1.jpg" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7926047175171636650.post-8471995021716533537</id><published>2011-04-21T12:00:00.001+08:00</published><updated>2011-04-21T12:29:39.972+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iOS"/><category scheme="http://www.blogger.com/atom/ns#" term="Quartz 2D"/><title type='text'>iOS SDK 認識 Quartz 2D (1)</title><content type='html'>Hi all, 接續上一篇&lt;a href=&quot;http://greenchiou.blogspot.com/2011/04/ios-sdk-quartz-2d-0.html&quot; target=&quot;_blank&quot;&gt;iOS SDK 認識 Quartz 2D(0)&lt;/a&gt;的內容，我們希望將我們所畫出來的矩形包裝成一個Class，已達到可以在畫面上呈現多個矩形，並且不會造成程式碼過長的情況；這一篇的內容將可以持續使用上篇的已經編輯好的專案繼續使用，內容上，除了將矩形包裝成一個Class外，還會介紹將上一篇提到的轉至矩陣帶入Class中。&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;b&gt;我會將閱讀文章的人視作對 c / obj-c 以及 iOS有一定的認識，因此在obj-c/c的一些使用內容將不會有太多的解釋。另外會以AS3為對照的語言，作一些相關的引用跟對照。&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
首先先新增一個Class，命名為Sprite 繼承自 NSObject。&lt;br /&gt;
Sprite.h：&lt;br /&gt;
&lt;pre class=&quot;brush:objc&quot;&gt;@interface Sprite: NSObject {
    CGFloat x;
    CGFloat y;
    CGFloat width;
    CGFloat height;
    CGFloat red;
    CGFloat blue;
    CGFloat green;
    CGFloat alpha;
}

@property (assign) CGFloat x, y;
@property (assign) CGFloat width, height;
@property (assign) CGFloat red, green, blue, alpha;

-(void) draw:(CGContextRef) context;

@end
&lt;/pre&gt;在Sprite.h內，我們知道這個Class會有(x,y)座標、長、寬以及RGBA等參數，並宣告了一個實體method draw；接下來我們開始實做這Class。&lt;br /&gt;
Sprite.m：&lt;br /&gt;
&lt;pre class=&quot;brush:objc;highlight:[19,27]&quot;&gt;@implementation Sprite
@synthesize x, y;
@synthesize width, height;
@synthesize red, green, blue, alpha;

-(id)init
{
    self = [super init];
    if(self)
    {
        x = y = 0.0;
        width = height = 0.0;
        red = green = blue = 0.0;
        alpha = 0.0;
    }
}
-(void) draw:(CGContextRef) context
{
    CGContextSaveGState(context);

    CGContextBeginPath(context);
    CGContextSetRGBFillColor(context, red, green, blue, alpha);
    CGContextAddRect(context, CGRectMake(x, y, width, height) );
    CGContextClosePath(context);
    CGContextDrawPath(context, kCGPathFill);

    CGContextRestoreGState(context);
}
&lt;/pre&gt;在上面，你會注意到兩行(19跟27)分別被我highlight起來；在這邊會需要將他的狀況保存起來是因為我們之後將會對這個Class去進行擴充，所以要將這個Class(或者說被建立出來的實體)本身的CTM去獨立的保存與釋放；如果不這麼作，可能會遇到圖形變形或者是座標...等等出現問題；大家可以在後面進行縮放跟旋轉擴充後，在去測試將這個動作移除後的差異。&lt;br /&gt;
&lt;br /&gt;
然後回到Quartz2DView的部分，分別對 .h 以及 .m 作下面的修改：&lt;br /&gt;
&lt;pre class=&quot;brush:objc&quot;&gt;//-----Quartz2DView.h
#import &quot;Sprite.h&quot;
@interface Quartz2DView : UIView {
    Sprite  *mySprite0;
    NSTimer *timer;
}
-(void) dt:(NSTimer*) theTimer
@end
//Quartz2DView.m 
-(id) initWithFrame:(CGRect) frame
{
    self = [super initWithFrame:frame];
    if(self)
    {
        mySprite0 = [[Sprite alloc] init];
        mySprite0.width = 100;
        mySprite0.height = 100;
        timer = [NSTimer scheduledTimerWithTimeInterval:1/30.0
                                                 target:self
                                               selector:@selector(dt:)
                                               userInfo:nil
                                                repeats:YES];
    }
}
-(void) dt:(NSTimer*) theTimer
{
    mySprite0.y+=1;
    [self setNeedsDisplay];
}
-(void) drawRect:(CGRect) rect{
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextSaveGState(context); 
     
    CGAffineTransform t0 = CGContextGetCTM( context );
    t0 = CGAffineTransformInvert(t0);
    CGContextConcatCTM(context, t0);
     
    [mySprite0 draw:context];
     
    CGContextRestoreGState(context);
}
&lt;/pre&gt;到這邊就修改完畢了，執行的結果，應該是上一篇最後執行的結果，沿著Y軸移動。&lt;br /&gt;
&lt;br /&gt;
接下來我們將要進行Sprite的擴充，希望讓Sprite有旋轉和縮放的能力，這就要使用到上一篇提到的轉置矩陣，轉置矩陣可以參考一下&lt;a href=&quot;http://help.adobe.com/zh_TW/AS3LCR/Flash_10.0/flash/geom/Matrix.html&quot; target=&quot;_blank&quot;&gt;AS3的Matrix&lt;/a&gt;；那麼現在，我們就開始修改Sprite的內容。&lt;br /&gt;
Sprite.m&lt;br /&gt;
&lt;pre class=&quot;brush:objc&quot;&gt;@interface Sprite: NSObject {
    CGFloat x;
    CGFloat y;
    CGFloat width;
    CGFloat height;
    CGFloat red;
    CGFloat blue;
    CGFloat green;
    CGFloat alpha;
    CGFloat rotation;
    CGFloat scaleX;
    CGFloat scaleY;
    CGRect  box;
}

@property (assign) CGFloat x, y;
@property (assign) CGFloat width, height;
@property (assign) CGFloat red, green, blue, alpha;
@property (assign) CGFloat rotation;
@property (assign) CGFloat scaleX,scaleY;
@property (assign) CGRect  box;

-(void) drawOutlinePath:(CGContextRef) context;
-(void) drawBody:(CGContextRef) context;
-(void) draw:(CGContextRef) context;
-(void) updateBox;
@end
&lt;/pre&gt;上面我們對Sprite Class增加了旋轉(rotation)及縮放(scaleX,scaleY)的參數，以及drawBody、drawOutlinePath兩個instance method，box則是用來記錄Sprite在畫面上的起點跟大小，updateBox則是用來更新box的內容後面會有更詳細的解釋；這邊我們會注意當我們在旋轉的時候，會以Sprite的原點作旋轉，而現在的原點，在左下角如下圖所示。&lt;br /&gt;
&lt;div&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2Bu4FESgpZlJ3pzGjzHRMEESA0U6G-zKkz4NVTY3YoeFGlKiHe1z1t9qJuzEB4X0qjTe6A9JsTmm9mi_-movKs-IJ7zEG1xx_53yfCxhPONDUOIsrQze-_xsojAJqM0nIIapKSHrbcFqy/s1600/sprite_location.jpg&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;223&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2Bu4FESgpZlJ3pzGjzHRMEESA0U6G-zKkz4NVTY3YoeFGlKiHe1z1t9qJuzEB4X0qjTe6A9JsTmm9mi_-movKs-IJ7zEG1xx_53yfCxhPONDUOIsrQze-_xsojAJqM0nIIapKSHrbcFqy/s320/sprite_location.jpg&quot; width=&quot;247&quot; /&gt;&lt;/a&gt;&lt;/div&gt;如果依照上圖，以左下角原點做旋轉的話，在大多的時候不適用在我們的物件上，所以我們希望將員點移到物件的中心點，如下圖一所示。這樣才能達到理想中的旋轉情況，如圖二所示。&lt;br /&gt;
&lt;div&gt;圖一&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_e7uOr5Usadqty_rVENAzz1qnRczAl8bLCIVPSaMZtsPYuPEsv-ztoem4MKPgcc5H4XUJR_AkQpYvk09oEwfOSvUiHviTX81QeUCVWTVVLmeLLWJeZul3j30SEVnxUWyLxVPqCBzcUvTO/s1600/sprite_location2.jpg&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;163&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_e7uOr5Usadqty_rVENAzz1qnRczAl8bLCIVPSaMZtsPYuPEsv-ztoem4MKPgcc5H4XUJR_AkQpYvk09oEwfOSvUiHviTX81QeUCVWTVVLmeLLWJeZul3j30SEVnxUWyLxVPqCBzcUvTO/s320/sprite_location2.jpg&quot; width=&quot;188&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
圖二&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2d3MPwSrIWbrsiRhlTZSqyQ6SMOJHxPbwUVERwTB38Q7s2qJ9dlNi4YPsPLRp32UbcvuVBE1LUL4BuLrQpA3A4NePUAwMVyz4NngHS3P5gwUun56UAGZI1VPoqkpu8BBDs3lJ7onyjsqL/s1600/sprite_location4.jpg&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;170&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2d3MPwSrIWbrsiRhlTZSqyQ6SMOJHxPbwUVERwTB38Q7s2qJ9dlNi4YPsPLRp32UbcvuVBE1LUL4BuLrQpA3A4NePUAwMVyz4NngHS3P5gwUun56UAGZI1VPoqkpu8BBDs3lJ7onyjsqL/s320/sprite_location4.jpg&quot; width=&quot;177&quot; /&gt;&lt;/a&gt;&lt;/div&gt;因此我們在Sprite.m 的 drawOutlinePath 中將Sprite的原點做改變&lt;br /&gt;
Sprite.m&lt;br /&gt;
&lt;pre class=&quot;brush:objc&quot;&gt;-(void) drawOutlinePath:(CGContextRef) context
{
    CGFloat w2 = box.size.width  * 0.5;// 半寬
    CGFloat h2 = box.size.height * 0.5;// 半高

    CGContextBeginPath( context );
    CGContextMoveToPoint( context, -w2, h2);
    CGContextAddLineToPoint( context, w2, h2);
    CGContextAddLineToPoint( context, w2, -h2);
    CGContextAddLineToPoint( context, -w2, -h2);
    CGContextAddLineToPoint( context, -w2, h2);
    CGContextClosePath( context );
}
&lt;/pre&gt;上面的程式碼中，如果你熟悉AS3應該會覺得CGContextMoveToPoint、CGContextAddLineToPoint很像是AS3中的&lt;a href=&quot;http://help.adobe.com/zh_TW/AS3LCR/Flash_10.0/flash/display/Graphics.html#moveTo()&quot; target=&quot;_blank&quot;&gt;graphic.MoveTo()&lt;/a&gt; 跟 &lt;a href=&quot;http://help.adobe.com/zh_TW/AS3LCR/Flash_10.0/flash/display/Graphics.html#lineTo()&quot; target=&quot;_blank&quot;&gt;graphic.LineTo()&lt;/a&gt;，其實非常的類似；也就是先將起始點移到(-w2,h2)，然後再依照寬高將外框的線畫出來並畫回起始點；這樣，物件的原點與中心點就重合到在一起了(上圖一)。&lt;br /&gt;
(其實這邊也可以用簡單的CGContextAddRect去繪製矩形，不過在這邊介紹另一個用法給大家參考)&lt;br /&gt;
&lt;br /&gt;
接下來我們繼續將 drawBody 、 draw 兩個method完成：&lt;br /&gt;
&lt;pre class=&quot;brush:objc; highlight:[12,13,14,15,16]&quot;&gt;//Sprite.m
-(void) drawBody:(CGContextRef) context
{
    CGContextSetRGBFillColor( context , red, green, alpha);
    [self drawOutlinePath:context];
    CGContextDrawPath( context );
}
-(void) draw:(CGContextRef) context
{
    CGContextSaveGState(context);

    CGAffineTransform t0 = CGAffineTransformIsIdentity;
    t0 = CGAffineTransformTranslate( context, x, y);
    t0 = CGAffineTransformRotate( context, rotation);
    t0 = CGAffineTransformScale ( context, scaleX, scaleY);
    CGContextConcatCTM( context, t0);

    [self drawBody:context];

    CGContextRestoreGState(context);
}
&lt;/pre&gt;上面被Highlight的部分，就是對Sprite Class本身去進行旋轉、縮放以及位移的動作，CGAffineTransformTranslate、CGAffineTransformRotate跟CGAffineTransformScale &lt;span class=&quot;Apple-style-span&quot; style=&quot;color: red;&quot;&gt;使用順序&lt;/span&gt;可能要特別注意，不然出來的結果可能會跟你想的很不一樣。&lt;br /&gt;
&lt;br /&gt;
接著再來講解box以及updateBox內容，你也許在上面drawOutlinePath已經有注意到box有被使用到，但是我們並沒有去設定box相關的內容，那他的寬、高是如何得到的？我們配合下面的程式碼以及圖三來進行解釋：&lt;br /&gt;
&lt;pre class=&quot;brush:objc&quot;&gt;//Sprite.m
-(void)updateBox
{
    // 取得現在的寬高
    CGFloat w0 = width * scaleX;
    CGFloat h0 = height * scaleY;
    // 求出半高及半寬
    CGFloat w2 = w0 * 0.5;
    CGFloat h2 = h0 * 0.5;

    CGSize size = box.size;
    CGPoint origin = box.origin;
    //更新圖形的寬高以及起始點
    size.width = w0;
    size.height = h0;
    origin.x = x - w2;
    origin.y = y - h2;

    box.size = size;
    box.origin = origin;
}
&lt;/pre&gt;&lt;div&gt;圖三&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhygvxKwXBk-jPM8I9C9LCsrpYVC6B9socrt-M8wHvNyLMyb-aqwTqr1xvvHx4rep2qGMFRUUefM9rXuXtw9FqDwudA3SI6rwbbyxERuwitCbtVT2r9q9nFzudkusgzgkpmJOY318wH0tpc/s1600/sprite_location3.jpg&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;218&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhygvxKwXBk-jPM8I9C9LCsrpYVC6B9socrt-M8wHvNyLMyb-aqwTqr1xvvHx4rep2qGMFRUUefM9rXuXtw9FqDwudA3SI6rwbbyxERuwitCbtVT2r9q9nFzudkusgzgkpmJOY318wH0tpc/s320/sprite_location3.jpg&quot; width=&quot;188&quot; /&gt;&lt;/a&gt;&lt;/div&gt;上面的程式碼，主要事要隨著改變Sprite的寬、高以及對x、y方向的縮放，去調整實際上Sprite物件的大小，並將線在範圍重新定位。&lt;br /&gt;
&lt;br /&gt;
最後因為Quartz 2D的旋轉是以弧度來計算所以在 rotation 的 setter &amp;amp; getter 要再作一些修改：&lt;br /&gt;
&lt;pre class=&quot;brush:objc&quot;&gt;-(void)setRotation:(CGFloat) degree
{
    rotation = degree * 3.141592 / 180;
}
-(CGFloat) rotation
{
    return rotation * 180 / 3.141592;
}
&lt;/pre&gt;最後，我們將Quartz2DView的mySprite作一些修改&lt;br /&gt;
&lt;pre class=&quot;brush:objc&quot;&gt;-(id) initWithFrame:(CGRect) frame
{
    self = [super initWithFrame:frame];
    if(self)
    {
        mySprite0 = [[Sprite alloc] init];
        mySprite0.width = 100;
        mySprite0.height = 100;
        mySprite0.red = 1;
        mySprite0.rotation = 30;
        mySprite0.height = 100;        
        mySprite0.scaleX = 1.5;
        //timer = [NSTimer scheduledTimerWithTimeInterval:1/30.0
        //                                         target:self
        //                                       selector:@selector(dt:)
        //                                       userInfo:nil
        //                                        repeats:YES];
    }
}
&lt;/pre&gt;執行後的結果&lt;br /&gt;
&lt;div&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQqcXZTOAbqYvoauI7XqLzqbKdhhS8YhZEokAkchlIJKkowgh6IpKMj_6H4KhLSwgI64SIczxfKqoW1mwW5ubuT0hg5x7LzgfJqbUYanAkLst9MDgQHVrBUbH_uPaPD88POurjLzoso7dP/s1600/pic_02.jpg&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQqcXZTOAbqYvoauI7XqLzqbKdhhS8YhZEokAkchlIJKkowgh6IpKMj_6H4KhLSwgI64SIczxfKqoW1mwW5ubuT0hg5x7LzgfJqbUYanAkLst9MDgQHVrBUbH_uPaPD88POurjLzoso7dP/s320/pic_02.jpg&quot; width=&quot;164&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
到這篇，這一篇就告一段落了，內容比我想像中的多了很多 -.-&quot;，看來應該是我沒有掌控好，不過內容也大多是被程式碼給佔據就是；最後希望這篇對大家有幫助，也跟大家一起共勉求進步。對於內容有任何錯誤或者建議，也請大家不要吝嗇，謝謝。&lt;br /&gt;
&lt;br /&gt;
參考資料：&lt;br /&gt;
iOS Developer Library &lt;a href=&quot;http://developer.apple.com/library/ios/#documentation/GraphicsImaging/Reference/CGContext/Reference/reference.html&quot; target=&quot;_blank&quot;&gt;CGContext Reference&lt;/a&gt; &lt;br /&gt;
iOS Developer Library &lt;a href=&quot;http://developer.apple.com/library/ios/#documentation/GraphicsImaging/Reference/CGAffineTransform/Reference/reference.html&quot; target=&quot;_blank&quot;&gt;CGAffineTransform Reference&lt;/a&gt; &lt;br /&gt;
ActionScript3.0 &lt;a href=&quot;http://help.adobe.com/zh_TW/AS3LCR/Flash_10.0/flash/geom/Matrix.html&quot; target=&quot;_blank&quot;&gt;Matrix&lt;/a&gt;&lt;br /&gt;
ActionScript3.0 &lt;a href=&quot;http://help.adobe.com/zh_TW/AS3LCR/Flash_10.0/flash/display/Graphics.html&quot; target=&quot;_blank&quot;&gt;Graphics&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
範例下載：&lt;a href=&quot;http://1001.webgene.tw/green/mobile/resource/Sample2.zip&quot; &quot;_blank&quot;&gt;Sample2.zip&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
上一篇相關文章：&lt;a href=&quot;http://greenchiou.blogspot.com/2011/04/ios-sdk-quartz-2d-0.html&quot; target=&quot;_blank&quot;&gt;iOS SDK 認識 Quartz 2D(0)&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://greenchiou.blogspot.com/feeds/8471995021716533537/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://greenchiou.blogspot.com/2011/04/ios-sdk-quartz-2d-1.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/8471995021716533537'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/8471995021716533537'/><link rel='alternate' type='text/html' href='http://greenchiou.blogspot.com/2011/04/ios-sdk-quartz-2d-1.html' title='iOS SDK 認識 Quartz 2D (1)'/><author><name>綠</name><uri>http://www.blogger.com/profile/10866243185938517560</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiROppWVtpB4GpYxBDY_T-AZzPrlMgq71-UD2AMaBewAxJAFPEBE5ccXU3vzceeteWEfSPnvBxBPhFejD55iKs_gygYzs1LCW70HmCi4vUQjwnrisgqhAqI7d06MQ6epw/s220/IMG_6544.JPG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2Bu4FESgpZlJ3pzGjzHRMEESA0U6G-zKkz4NVTY3YoeFGlKiHe1z1t9qJuzEB4X0qjTe6A9JsTmm9mi_-movKs-IJ7zEG1xx_53yfCxhPONDUOIsrQze-_xsojAJqM0nIIapKSHrbcFqy/s72-c/sprite_location.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7926047175171636650.post-7968698948565998595</id><published>2011-04-19T18:34:00.001+08:00</published><updated>2011-04-21T12:28:14.572+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iOS"/><category scheme="http://www.blogger.com/atom/ns#" term="Quartz 2D"/><title type='text'>iOS SDK 認識 Quartz 2D (0)</title><content type='html'>Hi everyone，今天要來介紹iOS SDK的Quartz 2D，Quartz 2D可以用來繪製向量圖像、播放圖片、合成圖片以及操作字型甚至試產生pdf文件，功能可以說是非常的強大，在遊戲製作上也是熱門的建構方式；關於更詳細的介紹可以參考 Apple 提供的 Quartz 2D 的 &lt;a href=&quot;http://developer.apple.com/library/ios/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/Introduction/Introduction.html&quot; target=&quot;_blank&quot;&gt;Guide&lt;/a&gt;，這篇文章會講述到如何繪製一個矩形，並且讓矩形移動。&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;b&gt;我會將閱讀文章的人視作對 c / obj-c 以及 iOS有一定的認識，因此在obj-c/c的一些使用內容將不會有太多的解釋。另外會以AS3為對照的語言，作一些相關的引用跟對照。&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Quartz 2D是關連 UIView 這個類別的內部資料結構，主要是在一個 graphics context (圖形內文)上做繪製；graphics context 我們可以將他視作為 Canvas ，只要有使用到 Quartz 2D API 都會需要使用到他；有關Quartz 2D的API呼叫都會帶有一個CG開頭的字首，使用的時候可以注意一下。&lt;br /&gt;
&lt;br /&gt;
使用 Quartz 2D 需要遵循下面的演算程序：&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Step 1：取得得目前的圖像內文，並將其保存起來&lt;/li&gt;
&lt;li&gt;Step 2：取得目前轉換矩陣，將矩陣倒置後存到圖像內文中&lt;/li&gt;
&lt;li&gt;Step 3：開始繪製矩形&lt;/li&gt;
&lt;li&gt;Step 4：恢復保存的內文&lt;/li&gt;
&lt;/ul&gt;接下來我們先建立一個專案Sample1，類型為 View-base Application 。接著建立一個新的Class，命名為Quartz2DView；接著將 Quartz2DView.m 的 drawRect:(CGRect) rect 改成下面的內容：&lt;br /&gt;
&lt;pre class=&quot;brush:objc&quot;&gt;-(void) drawRect:(CGRect) rect{
    //(step 1)
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextSaveGState(context); 
    //(step 2)
    CGAffineTransform t0 = CGContextGetCTM( context );
    t0 = CGAffineTransformInvert(t0);
    CGContextConcatCTM(context, t0);
    //(step 3)
    CGContextBeginPath(context);
    CGContextSetRGBFillColor(context, 1, 0, 0, 1);// CGContextSetRGBFillColor(CGContextRef ,r,g,h,alpha)
    CGContextAddRect( context , CGRectMake( 0, 0,100, 100));//CGRectMake(CGFloat x,CGFloat y,CGFloat width,CGFloat height)
    CGContextClosePath(context);
    CGContextDrawPath(context,kCGPathFill);
    //(step 4)
    CGContextRestoreGState(context);
}
&lt;/pre&gt;&lt;ul&gt;&lt;li&gt;Step1，我先取得當前UI的圖像內文，這時候我們就取得的可以用來畫圖的 Canvas (畫布)，並且將context保存下來；CGContextSaveGState 保存的狀態 &lt;a href=&quot;http://developer.apple.com/library/ios/#documentation/GraphicsImaging/Reference/CGContext/Reference/reference.html&quot; target=&quot;_blank&quot;&gt;在這&lt;/a&gt; 有詳細的參考，大家請自行觀看就不細說。&lt;/li&gt;
&lt;li&gt;Step2，取得目前的轉至矩陣，並將矩陣反轉之後，在存儲回context內(CTM=current transformation matrix)，這個動作，會讓你的Quartz 2D的物件座標系轉換，後面會搭配圖解說。&lt;/li&gt;
&lt;li&gt;Step3，進行繪製的動作，其中CGContextBeginPath是每次開始繪製前必須被呼叫的method，而結束可能會有CGContextClosePath或是CGContextClip來結束，並搭配CGContextDrawPath or CGContextDrawImage來繪製圖形。&lt;/li&gt;
&lt;li&gt;Step4，最後透過CGContextRestoreGState來恢復內文。&lt;/li&gt;
&lt;/ul&gt;接著將我們寫好的Quartz2DView加到畫面上，在專案的Sample1Controller.h加上程式碼：&lt;br /&gt;
&lt;pre class=&quot;brush:objc]&quot;&gt;#import &quot;Quartz2DView.h&quot;
@interface Sample1ViewController : UIViewController {
    Quartz2DView *quartzView;
}
&lt;/pre&gt;Controller.m的loadView加上程式碼：&lt;br /&gt;
&lt;pre class=&quot;brush:objc&quot;&gt;-(void) loadView
{
    [super loadView];
    quartzView = [[Quartz2DView alloc] initWithFrame:[self.view frame]];
    [self.view addSubview:quartzView];
}
&lt;/pre&gt;執行後的畫面呈現如下：&lt;br /&gt;
&lt;div&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmntIP4RPW9-gGIF93sTe7SNcjQdCp31vfLFa5BY871O9PKJtrCFCu4p81OxR9D7Ct_RXxXntxtW0ACGt09StPPB54tLyebRKp6C-ZaqxHNl1EERhOFFOAs8vHXcpqXajb0RfcVDAj8eJf/s1600/global_location_quartz2d.jpg&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; width=&quot;164&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmntIP4RPW9-gGIF93sTe7SNcjQdCp31vfLFa5BY871O9PKJtrCFCu4p81OxR9D7Ct_RXxXntxtW0ACGt09StPPB54tLyebRKp6C-ZaqxHNl1EERhOFFOAs8vHXcpqXajb0RfcVDAj8eJf/s320/global_location_quartz2d.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;依照上圖，你會注意到，我們繪製的方塊在畫面的左下角，以左下角為原點；這跟原本的以左上為原點的座標系不同，因為我們在Step2的地方，將原本的轉至矩陣改變了，除了改變座標外，還可以變形、選轉跟縮放；這個轉至矩陣，其實很像我們在寫AS3 DisplayObject.trasform的&lt;a href=&quot;http://help.adobe.com/zh_TW/AS3LCR/Flash_10.0/flash/geom/Matrix.html&quot; target=&quot;_blank&quot;&gt;martix&lt;/a&gt;。&lt;br /&gt;
&lt;b&gt;這邊需要注意的是，整體的座標系並沒有改變，只有在Quartz2DView中 drawRect method中 被畫出來的矩形座標系被改變&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
到這邊我們已經認識到該如何繪製一個圖形，並且呈現在我們的畫面上；接下來，我希望我畫出來的矩形可以沿著y軸往上移動，所以我需要一個建立一個類似AS3 ENTER_FRAME的計時器並且希望他以30FPS的速度來更新畫面，在這邊我先使用NSTimer這個類別(有一個更適合開發遊戲的記時器類別 CADisplayLink 以60FPS的速度更新畫面)，開始修改Quartz2DView相關的程式碼：&lt;br /&gt;
Quartz2DView.h：&lt;br /&gt;
&lt;pre class=&quot;brush:objc&quot;&gt;@interface Quartz2DView : UIView{
    CGFloat x0;
    CGFloat y0;
    NSTimer *time;
}
-(void) dt:(NSTimer*) theTimer;
&lt;/pre&gt;Quartz2DView.m 分別修改 initWithFrame、drawRect並且增加dt這個method：&lt;br /&gt;
&lt;pre class=&quot;brush:objc; highlight:[17,29]&quot;&gt;-(id) initWithFrame:(CGRect) frame
{
    self = [super initWithFrame:frame];
    if(self)
    {
        x0 = y0 = 0;
        timer = [NSTimer scheduledTimerWithTimeInterval:1/30.0
                                                 target:self
                                               selector:@selector(dt:)
                                               userInfo:nil
                                                repeats:YES];
    }
}
-(void) dt:(NSTimer*) theTimer
{
    y+=1;
    [self setNeedsDisplay];
}
-(void) drawRect:(CGRect) rect{
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextSaveGState(context); 
    
    CGAffineTransform t0 = CGContextGetCTM( context );
    t0 = CGAffineTransformInvert(t0);
    CGContextConcatCTM(context, t0);
    
    CGContextBeginPath(context);
    CGContextSetRGBFillColor(context, 1, 0, 0, 1);// CGContextSetRGBFillColor(CGContextRef ,r,g,h,alpha)
    CGContextAddRect( context , CGRectMake( x, y,100, 100) );
    CGContextClosePath(context);
    CGContextDrawPath(context,kCGPathFill);
    
    CGContextRestoreGState(context);
}
&lt;/pre&gt;在上面的程式碼中，當我們建立了Quartz2DView的實體的時候會將x,y指定為0，並且建立的一個NSTimer 讓他以30FPS來速度來呼叫dt這個method，在dt這個method中 [self setNeedsDisplay] 是告訴Quartz2DView再去執行(更新)drawRect這個method的動作；最後我們在修改drawRect中的 CGContextAddRect (highlight部分)，將代表x,y的地方帶入我們宣告的參數x0,y0，這樣一來，當y0改變的時候，就可以達到讓矩形延著Y由移動的效果。&lt;br /&gt;
&lt;br /&gt;
到此，這篇算是告一段落了；Quartz 2D算是被廣泛運用在照片處理跟遊戲製作上面(有空來研究cocos2d-iphone是不是也是用這個架成的framework)，至於大家來找碴Lite，因為那時我還沒有接觸到Quartz 2D，所以是使用一堆UIImageView+UIView來製作；除了這兩種方式可以用來製作遊戲外，還有一個大家耳熟能詳的OpenGL ES，處理的效能又好了許多，希望未來可以介紹給大家。&lt;br /&gt;
&lt;br /&gt;
下一篇希望介紹將可視物件(這次範例中的矩形)包成一個class，讓畫面上可以有多個圖像去動作。&lt;br /&gt;
&lt;br /&gt;
最後希望這篇文章有幫到大家，有任何錯誤或者建議，也請大家不要吝嗇，謝謝。&lt;br /&gt;
&lt;br /&gt;
參考網址：&lt;br /&gt;
&lt;a href=&quot;http://developer.apple.com/library/ios/navigation/&quot; target=&quot;_blank&quot;&gt;iOS Developer Library&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://developer.apple.com/library/ios/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/Introduction/Introduction.html&quot; target=&quot;_blank&quot;&gt;Quart2D Guide&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://help.adobe.com/zh_TW/AS3LCR/Flash_10.0/flash/geom/Matrix.html&quot; target=&quot;_blank&quot;&gt;AS3 Martix Class&lt;/a&gt;。&lt;br /&gt;
範例：&lt;a href=&quot;http://1001.webgene.tw/green/mobile/resource/Sample1.zip&quot;&gt;Sample1.zip&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
下一篇相關文章：&lt;a href=&quot;http://greenchiou.blogspot.com/2011/04/ios-sdk-quartz-2d-1.html&quot; target=&quot;_blank&quot;&gt;iOS SDK 認識 Quartz 2D (1)&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://greenchiou.blogspot.com/feeds/7968698948565998595/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://greenchiou.blogspot.com/2011/04/ios-sdk-quartz-2d-0.html#comment-form' title='3 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/7968698948565998595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/7968698948565998595'/><link rel='alternate' type='text/html' href='http://greenchiou.blogspot.com/2011/04/ios-sdk-quartz-2d-0.html' title='iOS SDK 認識 Quartz 2D (0)'/><author><name>綠</name><uri>http://www.blogger.com/profile/10866243185938517560</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiROppWVtpB4GpYxBDY_T-AZzPrlMgq71-UD2AMaBewAxJAFPEBE5ccXU3vzceeteWEfSPnvBxBPhFejD55iKs_gygYzs1LCW70HmCi4vUQjwnrisgqhAqI7d06MQ6epw/s220/IMG_6544.JPG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmntIP4RPW9-gGIF93sTe7SNcjQdCp31vfLFa5BY871O9PKJtrCFCu4p81OxR9D7Ct_RXxXntxtW0ACGt09StPPB54tLyebRKp6C-ZaqxHNl1EERhOFFOAs8vHXcpqXajb0RfcVDAj8eJf/s72-c/global_location_quartz2d.jpg" height="72" width="72"/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7926047175171636650.post-1996361252440766734</id><published>2011-04-11T15:08:00.007+08:00</published><updated>2011-04-11T15:38:54.706+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Facebook"/><category scheme="http://www.blogger.com/atom/ns#" term="Open Graph protocol"/><title type='text'>Facebook 使用 Open Graph protocal 輕鬆分享影片</title><content type='html'>Hi all, 今天來介紹一下 facebook 使用&amp;nbsp;Open Graph protocal&amp;nbsp;來輕鬆分享影片的方式，之前在facebook 上分享影片，我使用的方式大致上可能是使用到 FB API將影片直接發到塗鴉牆上或者是將影片上傳至Youtube後，再將網址分享到Facebook來分享影片；當然之前也有直接使用meta來分享，不過我看得亂七八糟搞不懂，所以大多沒有直接使用。&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
Open Graph protocal 其實也是使用 meta 來定義分享的內容，不過因為facebook有自行定義過他使用的meta，在測試過後，我覺得比較方便，而且除了這些之外，他也可以搭配facebook 的Like Button 來使用，後面一起介紹 。&lt;br /&gt;
&lt;br /&gt;
使用Open Graph protocal，會有四個基本的meta會需要設定&lt;br /&gt;
&lt;pre class=&quot;brush:html&quot;&gt;&amp;lt;meta property=&quot;og:title&quot; content=&quot;FB Meta Video&quot;/&amp;gt;
&amp;lt;meta property=&quot;og:type&quot; content=&quot;product&quot;/&amp;gt;
&amp;lt;meta property=&quot;og:url&quot; content=&quot;http://1001.webgene.tw/green/facebook/meta/&quot;/&amp;gt;
&amp;lt;meta property=&quot;og:image&quot; content=&quot;http://1001.webgene.tw/green/facebook/meta/Icon.png&quot;/&amp;gt;
/*end*/
&lt;/pre&gt;&lt;ol&gt;&lt;li&gt;og:title 分享到 Facebook 的標題 &lt;/li&gt;
&lt;li&gt;og:type 分享內容的種類 EX：product、movie &lt;/li&gt;
&lt;li&gt;og:url 分享內容的網址&lt;/li&gt;
&lt;li&gt;og:image 分享內容的圖片&lt;/li&gt;
&lt;/ol&gt;這邊可能會注意一般我們在分享的時候Title、內文及照片是使用下面的方式：&lt;br /&gt;
&lt;pre class=&quot;brush:html&quot; style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&amp;lt;meta name=&quot;description&quot; content=&quot;[DESCRIPTION]&quot; /&amp;gt;
&amp;lt;link rel=&quot;image_src&quot; type=&quot;image/jpeg&quot; href=&quot;[PHOTO_URL]&quot;/&amp;gt;
&amp;lt;title&amp;gt;[YOUR_TITLE]&amp;lt;title/&amp;gt;&lt;/pre&gt;&lt;br /&gt;
差別是在 一個是使用 Link button 去分享 另一個則是直接貼網址在fb上分享的差異，值得注意的使用貼網址來分享的方式，仍然需要加上&lt;br /&gt;
&lt;pre class=&quot;brush:html&quot;&gt;&amp;lt;link rel=&quot;image_src&quot; type=&quot;image/jpeg&quot; href=&quot;[PHOTO_URL]&quot;/&amp;gt;
&lt;/pre&gt;不然圖片會抓不到，title的部分則會直接被 og:title 取代，如果有使用og:description 也會直接取代 description的部分&lt;br /&gt;
&lt;br /&gt;
介紹基本的四個meta後，接下來介紹video所需要的四個meta：&lt;br /&gt;
&lt;pre class=&quot;brush:js&quot;&gt;&amp;lt;meta property=&quot;og:video&quot; content=&quot;http://1001.webgene.tw/green/facebook/meta/flvplayer.swf&quot;/&amp;gt;
&amp;lt;meta property=&quot;og:video:width&quot; content=&quot;390&quot;/&amp;gt;
&amp;lt;meta property=&quot;og:video:height&quot; content=&quot;260&quot;/&amp;gt;
&amp;lt;meta property=&quot;og:video:type&quot; content=&quot;application/x-shockwave-flash&quot;/&amp;gt;
/*end*/
&lt;/pre&gt;&lt;ol&gt;&lt;li&gt;og:video 影片所在的位置URL &lt;/li&gt;
&lt;li&gt;og:video:width 載入影片的寬度 最大398&lt;/li&gt;
&lt;li&gt;og:video:height 載入影片的高度 最大460&lt;/li&gt;
&lt;li&gt;og:video:type 影片的載入播放方式 &amp;lt;--- 不知道這樣說是否合適，請大家多包涵一下&lt;/li&gt;
&lt;/ol&gt;這邊要注意一下的事，如果是影片的話，通堂會需要一張圖片，不然的話他沒有辦法去點擊播放，&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: red;&quot;&gt;那張圖片要放在og:image Or  &amp;lt;link rel=&quot;image_src&quot; type=&quot;image/jpeg&quot; href=&quot;...&quot;/&amp;gt; 中，需要特別注意一下&lt;/span&gt;；我目前只有看到 flash player 的播放方是不確定是不是有直接播放h.264影片格式的方式，如果有的話之後再補充；將這四個meta加上html後，html的head部分大至上如下：&lt;br /&gt;
&lt;pre class=&quot;brush:html&quot;&gt;&amp;lt;head&amp;gt;
&amp;lt;link rel=&quot;image_src&quot; type=&quot;image/jpeg&quot; href=&quot;http://1001.webgene.tw/green/facebook/meta/Icon.png&quot;/&amp;gt;
&amp;lt;meta property=&quot;og:title&quot; content=&quot;FB Meta Video og title&quot;/&amp;gt;
&amp;lt;meta property=&quot;og:type&quot; content=&quot;product&quot;/&amp;gt;
&amp;lt;meta property=&quot;og:url&quot; content=&quot;http://1001.webgene.tw/green/facebook/meta/&quot;/&amp;gt;
&amp;lt;meta property=&quot;og:image&quot; content=&quot;http://1001.webgene.tw/green/facebook/meta/Icon.png&quot;/&amp;gt;
&amp;lt;meta property=&quot;og:site_name&quot; content=&quot;Green&#39;s Meta Test&quot;/&amp;gt;
&amp;lt;meta property=&quot;og:description&quot; content=&quot;Test Share Video to Facebook&quot;/&amp;gt;
&amp;lt;meta property=&quot;og:video&quot; content=&quot;http://1001.webgene.tw/green/facebook/meta/flvplayer.swf&quot; /&amp;gt;
&amp;lt;meta property=&quot;og:video:height&quot; content=&quot;260&quot; /&amp;gt;
&amp;lt;meta property=&quot;og:video:width&quot; content=&quot;390&quot; /&amp;gt;
&amp;lt;meta property=&quot;og:video:type&quot; content=&quot;application/x-shockwave-flash&quot; /&amp;gt;
&amp;lt;title&amp;gt;FB Meta Video Html Title&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;&lt;/pre&gt;&lt;br /&gt;
到這邊，就算是大功告成了，不過我們在加上一個Like button，來看看使用link button分享跟直接貼網址的分享差異是什麼；使用 &lt;a href=&quot;http://developers.facebook.com/tools/lint/&quot; target=&quot;_blank&quot;&gt;URL Linter&lt;/a&gt; 輸入 網址後，如果正確的話應該會出現下面的內容：&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxhOx1pJDIDZ6b01RDkuYG0hB_wYtRZPxiDRQvdtmJRU1oa_DN4o8TBoGXjM1pV_2Gal_UxkYh1tl7UQ6lRSKfKqp539lfurdHMb7nwsqqTDr-OhF4LhCz9cw_jvKudc1Mif34u_O_0HY1/s1600/share_ref3.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxhOx1pJDIDZ6b01RDkuYG0hB_wYtRZPxiDRQvdtmJRU1oa_DN4o8TBoGXjM1pV_2Gal_UxkYh1tl7UQ6lRSKfKqp539lfurdHMb7nwsqqTDr-OhF4LhCz9cw_jvKudc1Mif34u_O_0HY1/s1600/share_ref3.jpg&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div&gt;可以在這個頁面檢查輸入的內容有無錯誤，如果再使用Open Graph protocal有錯誤的話他也會另外標示出來，在下面有個Like button的部分，有提供iframe的soure code可以複製，將他貼到html後；分別測是分享的效果：&lt;/div&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYXkTEq0844Aoa4wCME-YZ1ogDJVVWQX1znI8BUt8zr5ZPpecx1q9l9V3_mC3iSY2-vHMheWoHdIn3B6lTMcMp9Sq8QHi3Lzl45jxdIOl0kPhAghix4Q7X9yuPtITxqWvNRqT-PLOncKjE/s1600/share_ref.jpg&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYXkTEq0844Aoa4wCME-YZ1ogDJVVWQX1znI8BUt8zr5ZPpecx1q9l9V3_mC3iSY2-vHMheWoHdIn3B6lTMcMp9Sq8QHi3Lzl45jxdIOl0kPhAghix4Q7X9yuPtITxqWvNRqT-PLOncKjE/s1600/share_ref.jpg&quot; /&gt;&lt;/a&gt; &lt;br /&gt;
&lt;div&gt;Like button 分享  &lt;/div&gt;&lt;a &quot;=&quot;&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdRGAqWWT-Lv-uRornYsEfMa2kqq8bflT5uYfQPnnMtS3bbYR6gSm6eJ8dGXDDVuBxc8I5QVDTUYFNTM3LyRv0cfRokyxZVcaA4qFau2_S3V1tRK1Tf036RRz1N8MBX_3f3QEUI46YpQnP/s1600/share_ref2.jpg&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdRGAqWWT-Lv-uRornYsEfMa2kqq8bflT5uYfQPnnMtS3bbYR6gSm6eJ8dGXDDVuBxc8I5QVDTUYFNTM3LyRv0cfRokyxZVcaA4qFau2_S3V1tRK1Tf036RRz1N8MBX_3f3QEUI46YpQnP/s1600/share_ref2.jpg&quot; /&gt;&lt;/a&gt; &lt;br /&gt;
貼網址分享&lt;br /&gt;
&lt;br /&gt;
眼尖的話會注意到左下方的icon有明顯的不同喔&lt;br /&gt;
&lt;br /&gt;
這就是這次分享的內容，當然Open Graph protocal可以使用的部分還不只這些，他還可以搭配其他的social plugins來使用，可以去統計分享的次數，誰分享的這些東西，多少人對這個東西點了讚之類的，不過怎麼用可能還要研究一下；希望這次的分享對大家有幫助囉，如果有什麼錯誤也請大家給我更至以及指教，謝謝。&lt;br /&gt;
&lt;br /&gt;
demo：&lt;a href=&quot;http://1001.webgene.tw/green/facebook/meta/&quot; target=&quot;_blank&quot;&gt;範例網址&lt;/a&gt;&lt;br /&gt;
reference：&lt;a href=&quot;http://developers.facebook.com/docs/opengraph/&quot; target=&quot;_blank&quot;&gt;Facebook Open Graph protocal&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
補充：&lt;br /&gt;
Eric艾額外問了一個那是不是可以在這邊直接將參數帶入swf中；答案是可以的，帶入的方式如下：&lt;br /&gt;
將og:video的路徑改成 http://1001.webgene.tw/green/facebook/meta/flvplayer.swf?param1=one&amp;amp;param2=two&lt;br /&gt;
&lt;pre class=&quot;brush:html&quot;&gt;&amp;lt;meta property=&quot;og:video&quot; content=&quot;http://1001.webgene.tw/green/facebook/meta/flvplayer.swf?param1=one&amp;param2=two&quot; /&amp;gt;
&lt;/pre&gt;在flash中的as3寫法&lt;br /&gt;
&lt;pre class=&quot;brush:as3&quot;&gt;trace(stage.loaderInfo.paramters[&#39;param1&#39;]); // one
//也可以使用這樣的方式去看會帶入哪些值近來
for(var $s:String in stage.loaderInfo.parameters)
{
    trace(stage.loaderInfo.parameters[$s]);
}
// 除了剛剛的param1、param2外 還會有 width 跟 height 兩個參數
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://greenchiou.blogspot.com/feeds/1996361252440766734/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://greenchiou.blogspot.com/2011/04/facebook-open-graph-protocal.html#comment-form' title='2 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/1996361252440766734'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/1996361252440766734'/><link rel='alternate' type='text/html' href='http://greenchiou.blogspot.com/2011/04/facebook-open-graph-protocal.html' title='Facebook 使用 Open Graph protocal 輕鬆分享影片'/><author><name>綠</name><uri>http://www.blogger.com/profile/10866243185938517560</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiROppWVtpB4GpYxBDY_T-AZzPrlMgq71-UD2AMaBewAxJAFPEBE5ccXU3vzceeteWEfSPnvBxBPhFejD55iKs_gygYzs1LCW70HmCi4vUQjwnrisgqhAqI7d06MQ6epw/s220/IMG_6544.JPG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxhOx1pJDIDZ6b01RDkuYG0hB_wYtRZPxiDRQvdtmJRU1oa_DN4o8TBoGXjM1pV_2Gal_UxkYh1tl7UQ6lRSKfKqp539lfurdHMb7nwsqqTDr-OhF4LhCz9cw_jvKudc1Mif34u_O_0HY1/s72-c/share_ref3.jpg" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7926047175171636650.post-2211868608912840874</id><published>2011-03-29T16:49:00.000+08:00</published><updated>2011-03-29T16:49:59.431+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Mobile Web"/><category scheme="http://www.blogger.com/atom/ns#" term="心得"/><title type='text'>關於Mobile web develope的兩、三事</title><content type='html'>在台灣mobile device越來越普及，其中Smart Phone為是主要的device，反映出來的是&lt;br /&gt;
&lt;br /&gt;
Mobile Web的詢問度也變高了；不過相對的問題也衍生出來，像是該如何做?要做什麼?&lt;br /&gt;
&lt;br /&gt;
在這我也遇到的相同的一些問題，所以整理了一些內容。&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
這邊的mobile device我以iphone當作我參考的依據。&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;&lt;b&gt;如何設計&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;避免像website一樣，作成一整張的layout再來切，設計也不適合太過於複雜，盡量偏向簡單。&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;使用css來編排你的html，以避免手機方向轉化造成的破圖、變形的情況。&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;檢視畫面，請盡量使用手機來檢視，或使用瀏覽器外掛模擬器來檢視&lt;br /&gt;
&lt;br /&gt;
(Firefox、Opera 跟Chrome都有外掛可以使用)；&lt;br /&gt;
&lt;br /&gt;
避免使用desktop的browser將大小拉成一樣，就當作是手機的瀏覽情形。&lt;br /&gt;
&lt;br /&gt;
手機browser支援圖片格式、css 跟 js 與 desktop browser 有差異，不同平台手機支援的程度也有差異。&lt;br /&gt;
&lt;br /&gt;
(我使用 htc desire hd 內建google瀏覽器跟 iphone safari 看png，差異很明顯)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;
&lt;pre class=&quot;brush:html&quot;&gt;//瀏覽前在meta上增加一個 viewport  
&amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0, maximum-scale=2.0&quot;&amp;gt;
/**
 * viewport 的 property
 * width：控制 viewport 的大小，可以指定一个值，如果 600，或者特殊的值，如 device-width 為預設的寬度
 * height： 指定高度。
 * initial-scale：初始缩放比例。
 * maximum-scale：可缩放的最大比例。
 * minimum-scale：可缩放的最小比例。
 * user-scalable：是否可以手動缩放
 *
**/
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;使用者體驗&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
這點我個人覺得非常的重要，手機不是desktop一樣有滑鼠、鍵盤讓使用者操作；&lt;br /&gt;
&lt;br /&gt;
在開始之前先將動作的流程畫成&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: red;&quot;&gt;圖示流程圖&lt;/span&gt;後再討論，可以有個簡單的demo來試著&lt;br /&gt;
&lt;br /&gt;
操作會更棒，可以避掉很多的盲點跟操作上的誤區。&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;互動設計&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
如果不考慮時程跟人力上的問題，能試著自己開發，可以學到很多的東西；不然的話，&lt;br /&gt;
&lt;br /&gt;
建議盡量使用framework來開發您的mobile web，可以幫你解決/避免不同平台瀏覽器上的&lt;br /&gt;
&lt;br /&gt;
問題與差異；而且已經幫你設計基礎的模組，減少你所需要花費的時間。&lt;br /&gt;
&lt;br /&gt;
推薦 &amp;nbsp;&lt;a href=&quot;http://jquerymobile.com/&quot; target=&quot;_blank&quot;&gt;jQuery&lt;/a&gt; 跟 &lt;a href=&quot;http://basecamphq.com/mobile&quot; target=&quot;_blank&quot;&gt;Basecamp&lt;/a&gt;&amp;nbsp;兩個 framework。&lt;br /&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
這些是我目前有遇到的一些問題，跟同事一起討論，並在同事製作出相關的成果後的一些心得，&lt;br /&gt;
&lt;br /&gt;
感謝阿駿、亞珍跟我的討論，也再次謝謝阿駿提供相關的reference。&lt;br /&gt;
&lt;br /&gt;
希望這些東西慢慢的整理出來可以幫助自己跟大家在規劃/製作上有所幫助。&lt;br /&gt;
&lt;br /&gt;
如果有錯誤或者是有建議的話，也請指證並且多多包涵 &lt;(_ _)&gt;&lt;br /&gt;
&lt;br /&gt;
ps. 感謝小P對於內容上呈現，及表達方式的建議。</content><link rel='replies' type='application/atom+xml' href='http://greenchiou.blogspot.com/feeds/2211868608912840874/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://greenchiou.blogspot.com/2011/03/mobile-web-develope.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/2211868608912840874'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/2211868608912840874'/><link rel='alternate' type='text/html' href='http://greenchiou.blogspot.com/2011/03/mobile-web-develope.html' title='關於Mobile web develope的兩、三事'/><author><name>綠</name><uri>http://www.blogger.com/profile/10866243185938517560</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiROppWVtpB4GpYxBDY_T-AZzPrlMgq71-UD2AMaBewAxJAFPEBE5ccXU3vzceeteWEfSPnvBxBPhFejD55iKs_gygYzs1LCW70HmCi4vUQjwnrisgqhAqI7d06MQ6epw/s220/IMG_6544.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7926047175171636650.post-7857290903652073947</id><published>2011-03-14T13:58:00.011+08:00</published><updated>2011-04-12T11:40:28.597+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="心得"/><title type='text'>[心得]大家來找碴簡易板(Looking for Faults Lite.) 開發筆記</title><content type='html'>呼,距離上次說要發這篇文章,過去了好一段時間,再不趕快寫的話大該就會忘光光了&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;稍微說一下這個遊戲, 其實是由公司開發Windows Phone 開始的,不過當初也沒有version Lite.&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;因為種種的原因, 移植到iPhone 上時, 決定先出一個簡易版跟正事版, 而這個簡易版就被我拿&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;來練功了.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;遊戲本身的機制很簡單, 在限定時間內找出圖片中不一樣的地方, 進入下一關.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikNh9DSr3MX6BXjfxSwLcob6I0kCKoqewv94X3xDy-3t9epiX8bYbbJrJlK5U7-T2wk74YzE4CwIZxcCA1Cfoilnd_qrzXVflc2ZWWL44I_5NR-Vu1gQJsjZugS8L_vOqvaLxGDBelGuse/s1600/pic_02.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;213&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikNh9DSr3MX6BXjfxSwLcob6I0kCKoqewv94X3xDy-3t9epiX8bYbbJrJlK5U7-T2wk74YzE4CwIZxcCA1Cfoilnd_qrzXVflc2ZWWL44I_5NR-Vu1gQJsjZugS8L_vOqvaLxGDBelGuse/s320/pic_02.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
我碰到了幾個問題, 比較有問題的是下面幾點：&lt;br /&gt;
&lt;br /&gt;
1. 操控的差異&lt;br /&gt;
&lt;br /&gt;
在設計是互動的時候, 我一開始是以手指去觸碰, 所以是用手指點擊畫面, 取得&quot;坐標&quot;後&lt;br /&gt;
&lt;br /&gt;
在進行&quot;距離&quot;的運算; 這樣的結果是,效果很差一次要進行五個點的運算, 誤差很大,&lt;br /&gt;
&lt;br /&gt;
實機測試時, 你觸碰的是一個面, 傳回來的點, 並沒有辦法像我所設想的那樣&lt;br /&gt;
&lt;br /&gt;
所以我改用放置區塊(Button)的方式, 用這樣的方法來解決問題.&lt;br /&gt;
&lt;br /&gt;
2. 記憶體管理&lt;br /&gt;
&lt;br /&gt;
在Objective - C 裡面, 記憶體的釋放是一個重要的課題, 我因為沒有管理好,&lt;br /&gt;
&lt;br /&gt;
所以在開發後期一直在處理 leak 的問題&lt;br /&gt;
&lt;br /&gt;
3. Cocoa Method 的使用&lt;br /&gt;
&lt;br /&gt;
在Cocoa的UIImage使用載入圖片有幾種不一樣的方式, 其中&lt;br /&gt;
&lt;pre class=&quot;brush:objc&quot;&gt;[UIImage imageName:(NSString *)]
&lt;/pre&gt;這個method, 在書上查到暫存的時間&lt;br /&gt;
&lt;br /&gt;
長短跟我們實際上使用會不一致, 很容易造成crash&amp;nbsp;的發生, 最後使用&lt;br /&gt;
&lt;br /&gt;
[UIImage imageWithContentsOfFile:] 來解決; 這種問題,&amp;nbsp;不知道該如何避免,&lt;br /&gt;
&lt;br /&gt;
只能遇到再去解決.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
以上就是我自己遇到覺得比較大的問題啦, 其實也可以把這些問題說成是平台不同造成的結果.&lt;br /&gt;
&lt;br /&gt;
================分隔線來了================&lt;br /&gt;
&lt;br /&gt;
我想, iOS 門檻是比較高了些, 也不是遙不可及, 不過許多的東西(內容), 都是需要經驗來累積&lt;br /&gt;
&lt;br /&gt;
所以在這邊我也沒辦法提出些什麼較好的見解, 大概能做的就是把自己練功的一些內容,&lt;br /&gt;
&lt;br /&gt;
以及開發上遇到的問題紀錄下來, 看看有沒有可以解決的方案 跟大家一起分享.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
那麼 這篇就先到這啦 因為我自己也不知道自己在打些什麼 希望大家看完不要檢舉我 = =a&lt;br /&gt;
&lt;br /&gt;
如果有什麼建議也請大家跟我說 謝謝&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://greenchiou.blogspot.com/feeds/7857290903652073947/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://greenchiou.blogspot.com/2011/03/looking-for-faults-lite.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/7857290903652073947'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/7857290903652073947'/><link rel='alternate' type='text/html' href='http://greenchiou.blogspot.com/2011/03/looking-for-faults-lite.html' title='[心得]大家來找碴簡易板(Looking for Faults Lite.) 開發筆記'/><author><name>綠</name><uri>http://www.blogger.com/profile/10866243185938517560</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiROppWVtpB4GpYxBDY_T-AZzPrlMgq71-UD2AMaBewAxJAFPEBE5ccXU3vzceeteWEfSPnvBxBPhFejD55iKs_gygYzs1LCW70HmCi4vUQjwnrisgqhAqI7d06MQ6epw/s220/IMG_6544.JPG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikNh9DSr3MX6BXjfxSwLcob6I0kCKoqewv94X3xDy-3t9epiX8bYbbJrJlK5U7-T2wk74YzE4CwIZxcCA1Cfoilnd_qrzXVflc2ZWWL44I_5NR-Vu1gQJsjZugS8L_vOqvaLxGDBelGuse/s72-c/pic_02.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7926047175171636650.post-2761150952445209595</id><published>2011-03-04T11:25:00.001+08:00</published><updated>2011-03-14T14:03:47.566+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iPhone"/><category scheme="http://www.blogger.com/atom/ns#" term="專案"/><title type='text'>[新案上線][iPhone APP] 大家來找碴 Lite.</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://blog.webgene.com.tw/wp-content/uploads/2011/02/mzl_mojtabkt_320x480-75.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;http://blog.webgene.com.tw/wp-content/uploads/2011/02/mzl_mojtabkt_320x480-75.jpg&quot; width=&quot;480&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
iTunes:&lt;a href=&quot;http://itunes.apple.com/tw/app/id421360555?mt=8&quot;&gt;http://itunes.apple.com/tw/app/id421360555?mt=8&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
新案上線囉，這是我第一個iPhone APP, 因為連結裡有相關的介紹，就不多說了&lt;br /&gt;
&lt;br /&gt;
終於的也在 iOS 上踏出了小小的一步，有種成就感，也讓自己動力滿滿啦 ~ 哈&lt;br /&gt;
&lt;br /&gt;
好啦，廢話也不多說，希望有iPhone的朋友可以支持一下，遇到任何bug也請跟我&lt;br /&gt;
&lt;br /&gt;
反映一下，接下來會準備小小一篇來介紹跟分享這個app開發時遇到的狀況以及相關的內容。&lt;br /&gt;
&lt;br /&gt;
另外也徵求一起學習的夥伴囉 &amp;gt;///////&amp;lt;</content><link rel='replies' type='application/atom+xml' href='http://greenchiou.blogspot.com/feeds/2761150952445209595/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://greenchiou.blogspot.com/2011/03/iphone-app-lite.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/2761150952445209595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/2761150952445209595'/><link rel='alternate' type='text/html' href='http://greenchiou.blogspot.com/2011/03/iphone-app-lite.html' title='[新案上線][iPhone APP] 大家來找碴 Lite.'/><author><name>綠</name><uri>http://www.blogger.com/profile/10866243185938517560</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiROppWVtpB4GpYxBDY_T-AZzPrlMgq71-UD2AMaBewAxJAFPEBE5ccXU3vzceeteWEfSPnvBxBPhFejD55iKs_gygYzs1LCW70HmCi4vUQjwnrisgqhAqI7d06MQ6epw/s220/IMG_6544.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7926047175171636650.post-929533033087046248</id><published>2011-01-06T10:45:00.001+08:00</published><updated>2011-03-29T12:24:08.591+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ActionScript3"/><category scheme="http://www.blogger.com/atom/ns#" term="Flash"/><title type='text'>gQuery&#39;s Commands 介紹</title><content type='html'>Flash開發一陣子後，想必大家都有屬於自己的libs了，這次要來介紹的是自己寫的libs，姑且就先命名為gQuery吧!!這次要介紹的內容是 Command ，跟Design Pattern的Command Pattern又不大一樣，因為主要是參考&lt;a href=&quot;http://cjcat.blogspot.com/&quot; target=&quot;_blank&quot;&gt;CJcat&lt;/a&gt;的&lt;a href=&quot;http://cjcat.blogspot.com/2010/03/thinking-in-commands.html&quot; target=&quot;_blank&quot;&gt;文章&lt;/a&gt;後自己嘗試寫出來的。雖然有算是練習的作品，不過來來去去也修改了不少次；也算是小弟我的一點點心血，所以就拿出來介紹一下，順便也幫自己複習一下。&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;因為CJcat的文章已經對原理有完整的介紹了，所以我就不在這方面有其他的琢磨了，就直接介紹如何使。&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Commands&lt;/b&gt;&lt;br /&gt;
Commands，我主要是把它當作一個容器，可以存放多個命令，讓命令依序/同時進行，使用方式有addCommand、setCommand，建議只使用addCommand就可以了。&lt;br /&gt;
&lt;pre class=&quot;brush:as3&quot;&gt;/**
 * @param ... $Commands 加入的命令必須是 commands 或是 array 所包覆之 function 或 commands 
**/
addCommand( ... $Commands);
//example
addCommand( 
    function():void{trace(&quot;step1&quot;);},
    [function():void{trace(&quot;step2-1&quot;);},
     function():void{trace(&quot;step2-2&quot;);  ],
    function():void{trace(&quot;step3&quot;)}
);

&lt;/pre&gt;其中用&quot;[...]&quot;(array)包起來的動作，是同時執行的(並聯)；其他的則是串聯(一個結束後，接續下一個)的執行方式，下面就是完整的範例程式碼。&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:as3&quot;&gt;import gquery.command.Commands;
import gquery.command.DoNomalCommand;
import gquery.command.DoTweenNanoTo;
import gquery.events.CommandEvent;

var cast1 = new Sprite();
var cast2 = new Sprite();
cast1.graphic.beginFill( 0x000000 );
cast1.graphics.drawRect(0, 0, 100, 100);
cast1.graphics.endFill();
cast2.graphic.beginFill( 0x000000 );
cast2.graphics.drawRect(0, 0, 100, 100);
cast2.graphics.endFill();
cast2.y = 110;
addChild( cast1 );
addChild( cast2 );

var com:Commands = new Commands();
//為com加上監聽器，在com執行完畢的時候觸發
com.addEventListener(CommandEvent.COMPLETE , onCommandCompleteHandle);
com.addCommand(
    new DoTweenNanoTo( cast1 , 1 , {x:100} ),
    new DoTweenNanoTo( cast2 , 1 , {alpha:0} ),
    [new DoTweenNanoTo( cast1 , 1 , {x:0} ),
     new DoTweenNanoTo( cast2 , 1 , {alpha:1} )]
);
//開始執行 com
com.execute();

function onCommandCompleteHandle(e:CommandEvent):void
{
    //這邊可以做command完成後的動作
    trace(&quot;com 執行完畢&quot;);
}
&lt;/pre&gt;&lt;br /&gt;
下面來介紹幾個command的用法：&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;DoTweenNanoTo&lt;/b&gt; &lt;br /&gt;
&lt;b&gt;DoTweenMaxTo&lt;/b&gt;&lt;br /&gt;
相信大家看到這個都覺得很眼熟， 這是使用&lt;a href=&quot;http://www.greensock.com/&quot; target=&quot;_blank&quot;&gt;greensock&lt;/a&gt;的Tween libs所建立的，所以他的使用方式也跟原本的差不多。&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: red; font-size: x-small;&quot;&gt;ps.如果要同時對同一個物件使用這Class的話，可能會有tween overwrite的問題需要注意一下&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;brush:as3&quot;&gt;DoTweenNanoTo( $target:DisplayObject , $duration:Number , $vars:Object );
DoTweenMaxTo( $target:DisplayObject , $duration:Number , $vars:Object );
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;DoFrameCommand&lt;/b&gt;&lt;br /&gt;
&lt;pre class=&quot;brush:as3&quot;&gt;/**
 * @param $target 目標
 * @param $startFrame 開始影格(int or FrameLabel) 
 * @param $EndFrame 結束影格(int or FrameLabel)
 */
DoFrameCommand($target:MovieClip , $startFrame:* , $EndFrame:* )
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;DoNormalCommand&lt;/b&gt;&lt;br /&gt;
&lt;pre class=&quot;brush:as3&quot;&gt;/**
 * 建立命令容器實體
 * @param $function 要執行的Function
 * @param $delay 要延遲秒數 
 */
DoNomalCommand($function:Function , $delay:Number = 0)
&lt;/pre&gt;&lt;br /&gt;
到這邊，就是目前整理出來比較完整的部分了，希望能對大家有些許的幫助。&lt;br /&gt;
&lt;br /&gt;
參考網址：&lt;a href=&quot;http://cjcat.blogspot.com/2010/03/thinking-in-commands.html&quot; target=&quot;_blank&quot;&gt;CJ&#39;s Blog Thinking in Commands&lt;/a&gt;&lt;br /&gt;
範例檔案： &lt;a href=&quot;http://1001.webgene.tw/green/flash/source/gquery.zip&quot;&gt;點我下載&lt;/a&gt; (libs也包進去了)&lt;br /&gt;
在這邊囉嗦一下，其實再發這篇文章的時候內新是挺掙扎的，畢竟這個libs說起來也不難，只是一個簡單的小概念；比起cjcat的詳細介紹，覺得自己寫這篇沒甚麼意義；最後決定還是要寫，一方面是記錄，另外也是學習著寫自己的libs，不過在文章內容上就偏向使用方面去介紹，就不再解說相關的概念。&lt;br /&gt;
最後希望大家再使用方面如果有遇到什麼bug可以跟我說一下，也期許自己能夠繼續進步，最後2011年啦，在這邊跟大家補個新年快樂~~~</content><link rel='replies' type='application/atom+xml' href='http://greenchiou.blogspot.com/feeds/929533033087046248/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://greenchiou.blogspot.com/2011/01/gquerys-commands.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/929533033087046248'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/929533033087046248'/><link rel='alternate' type='text/html' href='http://greenchiou.blogspot.com/2011/01/gquerys-commands.html' title='gQuery&#39;s Commands 介紹'/><author><name>綠</name><uri>http://www.blogger.com/profile/10866243185938517560</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiROppWVtpB4GpYxBDY_T-AZzPrlMgq71-UD2AMaBewAxJAFPEBE5ccXU3vzceeteWEfSPnvBxBPhFejD55iKs_gygYzs1LCW70HmCi4vUQjwnrisgqhAqI7d06MQ6epw/s220/IMG_6544.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7926047175171636650.post-7008582047951385458</id><published>2010-12-28T22:10:00.000+08:00</published><updated>2010-12-28T18:13:44.050+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Facebook"/><category scheme="http://www.blogger.com/atom/ns#" term="Graphic API"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript"/><title type='text'>計算 Facebook 互動次數的方式</title><content type='html'>最近看到幾個跟Facebook結合的活動，發現似乎抓到的朋友，都是在塗鴉牆上跟自己互動較多的朋友，就找了一下是不是有相關的API可以使用；不過最後發現並沒有這樣的API，其實這個數字是計算出來的，&lt;a href=&quot;http://forum.developers.facebook.net/viewtopic.php?id=66109&quot;&gt;相關的規範&lt;/a&gt;可以參考一下；由前面提供的 相關規範 &amp;nbsp;，我們會了解到我們所計算出來的數據，並不會完全正確，因為是抓取一段範圍內的資料來進行統計，所以會有些許失真的情況，並不會達到百分之百的正確。那麼接下來就介紹一下如何計算。&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
這邊我的做法是去計算在我的塗鴉牆上，有回應的人，以及有哪些人按讚；其中一則stream訊息只能點一次贊，所以計算一次；而回應stream可能會有一次以上的情況，所以我是記算有幾次回應就計幾次。&lt;br /&gt;
&lt;br /&gt;
前置的作業，也就是初始化FB的部分，就不額外講解了，如有需要請參考 &lt;a href=&quot;http://greenchiou.blogspot.com/2010/12/javascript-facebook-sdk-width-graphic.html&quot;&gt;使用 Javascript Facebook SDK with Graphic API&lt;/a&gt;。&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;這邊要記得要求相關的 Permission：&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: #6aa84f;&quot;&gt;read_stream&amp;nbsp;&lt;/span&gt;這樣才有辦法獲得 User 塗鴉牆上的資料，再登入完成之後，我們就要開始讀取塗鴉牆上的文章：&lt;/div&gt;&lt;div&gt;在這邊我使用fql的方式來取得相關的資料&lt;/div&gt;&lt;div&gt;&lt;pre class=&quot;brush:js&quot;&gt;//宣告相關的變數
var fuids_data = {}; // 記錄uid出現的次數
var tmp_ary = []; // 用來排序 uid 的array
var params; 
var comments_point;
var tmp_id;
var tmp_name;
var fuids = &quot;&quot;; // 將朋友的uid串成字串 在最後取得相關資料
// 取得塗鴉牆上來源/目標為user的訊息comments(回覆)/likes(讚)建議限定筆數不然會抓不到資料 目前還沒抓到上限
var query = FB.Data.query(&#39;SELECT comments,likes FROM stream WHERE target_id=&quot;{0}&quot; or source_id=&quot;{0}&quot; limit 0,50&#39;, [uid );
query.wait(function(rows) {  
 for(params in rows )
 {
  //取得有回復的 朋友ID
  for(comments_point = 0 ; comments_point &amp;lt; rows[params].comments.comment_list.length ; comments_point++ )
  {
   tmp_id = rows[params].comments.comment_list[comments_point].fromid;
   if(uid == tmp_id) continue;
   if(fuids_data[tmp_id] == undefined)
   {
    fuids_data[tmp_id] = {
     uid:tmp_id,
     name:null,
     pic:null,
     counts:1
    };
    tmp_ary.push( fuids_data[tmp_id] );
   }else fuids_data[tmp_id].counts++;
  }
  for(comments_point = 0 ; comments_point &amp;lt; rows[params].likes.friends.length ; comments_point++ )
  {
   //取得朋友中按讚的ID
   tmp_id = rows[params].likes.friends[comments_point];
   if(uid == tmp_id) continue;
   if(fuids_data[tmp_id] == undefined)
   {
    fuids_data[tmp_id] = {
     uid:tmp_id,
     name:null,
     pic:null,
     counts:1
    };
    tmp_ary.push( fuids_data[tmp_id] );
   }else fuids_data[tmp_id].counts++;
  }
  }
  for(params in fuids_data ) html_code += &quot;[&quot;+params+&quot;] counts: &quot;+fuids_data[params].counts+&quot;
&quot;;
  var tmp_obj;
  // 因為我找不到直接排序的方式 所以用程式排序
  for(var i = 0 ; i &amp;lt; tmp_ary.length-1 ; i++ )
  {
   for(var j=i+1 ; j &amp;lt; tmp_ary.length ; j++)
   {
    if(tmp_ary[i].counts &amp;gt; tmp_ary[j].counts)
    {
     tmp_obj = tmp_ary[i];
     tmp_ary[i] = tmp_ary[j];
     tmp_ary[j] = tmp_obj;
    }
   }
  }
  tmp_ary = tmp_ary.reverse();
&lt;/pre&gt;&lt;/div&gt;到這邊，已將將最新的一百則stream資訊取出，並且完成了解析的動作，接下來只要再將朋友的資料抓取出來就好。&lt;br /&gt;
&lt;div&gt;&lt;pre class=&quot;brush:js&quot;&gt;//將所有的UID串成字串 再取得朋友們的資料
for(i=0 ; i &amp;lt; tmp_ary.length ; i++)
{
 fuids = i != tmp_ary.length-1 ? fuids+tmp_ary[i].uid+&quot;,&quot;:fuids+tmp_ary[i].uid;
}
getUserInfo(fuids);
function getUserInfo(uids)
{
 //取得user的相關資料
 var query = FB.Data.query(&#39;select uid,name,pic  from user where uid in ({0})&#39;, uids);
    query.wait(function(rows) {
  for(var i=0 ; i &amp;lt; rows.length ; i++)
  {
   fuids_data[rows[i].uid].name = rows[i].name;
   fuids_data[rows[i].uid].pic  = rows[i].pic;
  }
 });
}
&lt;/pre&gt;&lt;/div&gt;這樣就大功告成了。希望這篇也可以帶給大家一些幫助囉~&lt;br /&gt;
相關連結：&lt;a href=&quot;http://1001.webgene.tw/green/facebook/jssdk/interacitve_high.html&quot;&gt;Demo&lt;/a&gt;&amp;nbsp;, &lt;a href=&quot;http://1001.webgene.tw/green/facebook/jssdk/source_interactive.zip&quot;&gt;Source&lt;/a&gt;&lt;br /&gt;
參考網址：&lt;a href=&quot;http://developers.facebook.com/docs/reference/fql/stream/&quot;&gt;FQL-stream&lt;/a&gt;&amp;nbsp;, &lt;a href=&quot;http://developers.facebook.com/docs/reference/fql/comment/&quot;&gt;FQL-comments&lt;/a&gt;&amp;nbsp;, &lt;a href=&quot;http://developers.facebook.com/docs/reference/javascript/fb.data.query/&quot;&gt;FB.Data.query&lt;/a&gt;&amp;nbsp;,&amp;nbsp;&lt;a href=&quot;http://forum.developers.facebook.net/viewtopic.php?id=66109&quot;&gt;相關的規範&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://greenchiou.blogspot.com/feeds/7008582047951385458/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://greenchiou.blogspot.com/2010/12/facebook.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/7008582047951385458'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/7008582047951385458'/><link rel='alternate' type='text/html' href='http://greenchiou.blogspot.com/2010/12/facebook.html' title='計算 Facebook 互動次數的方式'/><author><name>綠</name><uri>http://www.blogger.com/profile/10866243185938517560</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiROppWVtpB4GpYxBDY_T-AZzPrlMgq71-UD2AMaBewAxJAFPEBE5ccXU3vzceeteWEfSPnvBxBPhFejD55iKs_gygYzs1LCW70HmCi4vUQjwnrisgqhAqI7d06MQ6epw/s220/IMG_6544.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7926047175171636650.post-3252009474396766444</id><published>2010-12-22T07:46:00.000+08:00</published><updated>2010-12-28T18:28:22.361+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Facebook"/><category scheme="http://www.blogger.com/atom/ns#" term="Graphic API"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript"/><title type='text'>使用 Javascript Facebook SDK with Graphic API</title><content type='html'>最近因為專案的需求，小小的研究了一下基礎的 Javascript Facebook SDK。這次的範例是以活動網站的部分進行解說，不多說接下來就直接進入主題。&lt;br /&gt;
&lt;br /&gt;
2010/12/22 17:17 (調整內容)&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
1.Facebook connect Authentication&lt;br /&gt;
建立一個新的Facebook app，&lt;a href=&quot;http://www.facebook.com/developers/&quot;&gt;這邊建立&lt;/a&gt; &lt;a href=&quot;http://developers.facebook.com/docs/guides/canvas&quot;&gt;參考網址&lt;/a&gt;，取得api key。接下來再html輸入下列的code&lt;br /&gt;
&lt;pre class=&quot;brush:js;&quot;&gt;&lt;div id=&quot;fb-root&quot;&gt;&lt;/div&gt;window.fbAsyncInit = function() {
    FB.init({appId: api_key, status: true, cookie: true, xfbml: true});
    // FB.getLoginStatus 可以判斷是否已經有FB的login session 如果以登入 可以跳過登入的步驟進行下一步
    FB.getLoginStatus(function(response) {
        if (response.session) {
            alert(response.session);
        }
    })
};
(function() {
    var e = document.createElement(&#39;script&#39;);
    e.type = &#39;text/javascript&#39;;
    e.src = document.location.protocol + &#39;//connect.facebook.net/zh_TW/all.js&#39;;
    e.async = true;
    document.getElementById(&#39;fb-root&#39;).appendChild(e);
}());
&lt;/pre&gt;並且在 html 的 tag 中加入 xmlns:fb=&quot;http://www.facebook.com/2008/fbml&quot; 加完大該會長下面這樣&lt;br /&gt;
&lt;pre class=&quot;brush:html;&quot;&gt;&amp;lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xmlns:fb=&quot;http://www.facebook.com/2008/fbml&quot;&amp;gt;
&lt;/pre&gt;有了這些之後，我們就可以開始進行facebook 的connect 動作，也就是登入。登入有兩種方式，第一種是直接使用 fb提供的Social plugins，在perms可以填入要求的permission。&lt;br /&gt;
&lt;pre class=&quot;brush:html;&quot;&gt;&lt;fb:login-button autologoutlink=&quot;true&quot; perms=&quot;email,user_birthday,status_update,publish_stream&quot;&gt;&lt;/fb:login-button&gt;
&lt;/pre&gt;另一種方式是使用 API 提供的 FB.login(callback, perms);&lt;br /&gt;
&lt;pre class=&quot; brush:js;&quot;&gt;FB.login(function(response){
    // do some after
      
    }, 
    {perms:&#39;read_stream,publish_stream,offline_access&#39;}
);
&lt;/pre&gt;到這邊，就已經成功的與facebook連結並取得相關登入後相關的資訊。在登入成功後，並不會取得user的資料，如果有需要取得user的相關資料，必須要再另外做處理。&lt;br /&gt;
&lt;br /&gt;
2.基礎的運用&lt;br /&gt;
&lt;br /&gt;
接著來介紹如何運用一些相關的API，在fb graphic api 中，要去呼叫函試的方式要使用 FB.ui() 或是 FB.api()，自己小測了幾個method發現其實都可以互通的，差別的是回傳的東西有些微的不同以及FB.ui會有對話框(Dialogs)。&lt;br /&gt;
&lt;br /&gt;
FB.api 使用的使用方法有分兩種&lt;br /&gt;
&lt;pre class=&quot;brush:js&quot;&gt;FB.api(path, methed, params, callback);
FB.api(params, callback);
&lt;/pre&gt;上述第二種方式 主要是用來呼叫 &lt;a href=&quot;http://developers.facebook.com/docs/reference/rest/&quot;&gt;Old REST API&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
exam1:&lt;br /&gt;
取得自己/其他user的資訊&lt;br /&gt;
&lt;pre class=&quot;brush:js&quot;&gt;FB.api(&quot;/me&quot;,function(response)
{
    alert(response.name)//取得 user&#39;s name
});
&lt;/pre&gt;如果是想查其他人，也可以將me改成user的 uid or user&#39;s name 來查詢&lt;br /&gt;
&lt;a href=&quot;http://developers.facebook.com/docs/reference/api/&quot;&gt;reference&lt;/a&gt;&amp;nbsp;可以前往查詢傳回來的相關數值&lt;br /&gt;
&lt;br /&gt;
這邊則是用fql.query來查詢user的名字&lt;br /&gt;
exam2:&lt;br /&gt;
&lt;pre class=&quot;brush:js&quot;&gt;FB.api(
  {
    method: &#39;fql.query&#39;,
    query: &#39;SELECT name FROM user WHERE uid=5526183&#39;
  },
  function(response) {
    alert(&#39;Name is &#39; + response[0].name);
  }
);
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
另外特別介紹較常用到 stream.publish 使用的方式：&lt;br /&gt;
a.FB.ui 使用的方式與 FB.Connect.streamPublish 差不多：&lt;br /&gt;
&lt;pre class=&quot;brush:js&quot;&gt;FB.ui({
 method: &#39;stream.publish&#39;,
 message: &#39;我說{$message}&#39;,
 attachment: {
  name: &quot;內文標題{$title}&quot;,
  caption: &#39;&#39;,
  description: (&quot;測試內文&quot;),
  href: &quot;http://1001.webgene.tw/green/facebook/jssdk/&quot;
 },
 action_links: [ { text: &quot;Green&#39;s Practice&quot;, href: &quot;http://1001.webgene.tw/green/facebook/jssdk/&quot; } ],
 target_id:userData.uid,
 user_prompt_message: &quot;說&quot;,
},
 function(response) {
  if(response &amp;amp;&amp;amp; response.post_id)
  {
    //publish is successed.
   alert(response.post_id);
  }
  else
  {
   //public is failured.
   
  }
 }
);
&lt;/pre&gt;在一般的情況下使用這樣的方式就應用在大多數的地方了，但是如果想要讓他自動發佈，就需要用第二種方式&lt;br /&gt;
b. FB.api ：&lt;br /&gt;
&lt;pre class=&quot;brush:js&quot;&gt;FB.api(&#39;/[target_id]/feed&#39;,&#39;post&#39;, 
 {
  method: &#39;stream.publish&#39;,
  message: &#39;User 說{$message}&#39;,
  picture : &#39;http://www.takwing.idv.hk/facebook/demoapp_jssdk/img/logo.gif&#39;,
  link : &#39;http://1001.webgene.tw/green/facebook/jssdk/&#39;,
  name: &#39;JS SDK($title)!&#39;,
  caption: &#39;Caption of the Post($subTitle)&#39;,
  description: &#39;It is not fun to write Facebook App!($descript)&#39;,
  actions : { name : &#39;變很大的Graphic API&#39;, link : &#39;http://1001.webgene.tw/green/facebook/jssdk/&#39;}
 } , function(response) {
 if (!response || response.error) {
  alert(&#39;Error occured&#39;);
 } else {
  alert(&#39;Post ID: &#39; + response.id);
 }
});
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
以上就是小弟我這一天來練習的一些整理，雖然寫的內容不是很滿意(不得不承認，不大會寫這種文章)希望之後可以寫得越來越好。也希望我的下一篇文章能趕快生出來 .... (逃)&lt;br /&gt;
&lt;br /&gt;
如果內容有錯誤的地方寫請大家幫忙指證，感激不盡。&lt;br /&gt;
&lt;br /&gt;
最後感謝p哥幫忙，幫我解決了不少問題&amp;lt;(_ _)&amp;gt;&lt;br /&gt;
&lt;br /&gt;
參考網址：&lt;br /&gt;
&lt;a href=&quot;http://thinkdiff.net/facebook/graph-api-javascript-base-facebook-connect-tutorial/&quot;&gt;Graph api &amp;amp; javascript base Facebook Connect tutorial&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://developers.facebook.com/docs/&quot;&gt;facebook Developers&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://greenchiou.blogspot.com/feeds/3252009474396766444/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://greenchiou.blogspot.com/2010/12/javascript-facebook-sdk-width-graphic.html#comment-form' title='3 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/3252009474396766444'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/3252009474396766444'/><link rel='alternate' type='text/html' href='http://greenchiou.blogspot.com/2010/12/javascript-facebook-sdk-width-graphic.html' title='使用 Javascript Facebook SDK with Graphic API'/><author><name>綠</name><uri>http://www.blogger.com/profile/10866243185938517560</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiROppWVtpB4GpYxBDY_T-AZzPrlMgq71-UD2AMaBewAxJAFPEBE5ccXU3vzceeteWEfSPnvBxBPhFejD55iKs_gygYzs1LCW70HmCi4vUQjwnrisgqhAqI7d06MQ6epw/s220/IMG_6544.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7926047175171636650.post-394395604142968685</id><published>2010-07-23T12:20:00.000+08:00</published><updated>2011-01-12T11:38:47.101+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ActionScript3"/><category scheme="http://www.blogger.com/atom/ns#" term="Flash"/><category scheme="http://www.blogger.com/atom/ns#" term="JSON"/><title type='text'>AS3 + JSON 的應用</title><content type='html'>這算是這個blog的開山文章，其實之前就有想要開個blog來分享一些東西了不過腦袋裡一堆想法不知道寫才好，最後都選擇了放棄；想想這樣下去也不是辦法，所以就找了個一個比較簡單點的主題來分享。&lt;br /&gt;
&lt;br /&gt;
JSON (JavaScript Object Notation)，是一個輕量型的資料交換格式，在這邊就不做詳細的介紹，有興趣的人可以到&lt;a href=&quot;http://zh.wikipedia.org/zh-tw/JSON&quot;&gt;wiki&lt;/a&gt;去看看。&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
再開始之前，會需要AS3的JSON code，可以到 Adobe提供的 class libs去下載 ，&lt;a href=&quot;http://code.google.com/p/as3corelib/&quot;&gt;Link&lt;/a&gt;。&lt;br /&gt;
&lt;br /&gt;
以下的範例 是以 PHP 為後台程式處理。&lt;br /&gt;
PHP 傳值給 AS：&lt;br /&gt;
php result.php&lt;br /&gt;
&lt;pre class=&quot;brush:php;&quot;&gt;$arr[] = array(&quot;name&quot;=&amp;gt;&quot;測試員&quot;,&quot;age&quot;=&amp;gt;&quot;21&quot;);
$arr[] = array(&quot;name&quot;=&amp;gt;&quot;測試員1&quot;,&quot;age&quot;=&amp;gt;&quot;22&quot;);
$arr[] = array(&quot;name&quot;=&amp;gt;&quot;測試員2&quot;,&quot;age&quot;=&amp;gt;&quot;23&quot;);
$arr[] = array(&quot;name&quot;=&amp;gt;&quot;測試員3&quot;,&quot;age&quot;=&amp;gt;&quot;24&quot;);
echo json_encode( $arr );
&lt;/pre&gt;as&lt;br /&gt;
&lt;pre class=&quot;brush:as3;&quot;&gt;import com.adobe.serialization.json.JSON;

var request:URLRequest = new URLRequest();
request.url = &quot;result.php&quot;;
request.method = URLRequestMethod.POST;
request.contentType = URLLoaderDataFormat.TEXT;

var myLoader:URLLoader = new URLLoader();
myLoader.addEventListenter(Event.COMPLETE , onLoadCompleted );
myLoader.load( request );

function onLoadCompleted ( e:Event ):void{
    var mydata:Array = JSON.decode( e.target.data );
    trace( mydata.length ); //output:4 
    trace( mydata[0].name , mydata[0].age);//output:測試員,21 
}&lt;/pre&gt;&lt;br /&gt;
AS 傳送資料給 PHP：&lt;br /&gt;
as&lt;br /&gt;
&lt;pre class=&quot;brush:as3;&quot;&gt;import com.adobe.serialization.json.JSON;
var myVar:URLVariables = new URLVariables();
var mydata:Array = [{name:&quot;測試者&quot;,age:&quot;21&quot;}];
myVar.postData = JSON.encode( mydata );

var request:URLRequest = new URLRequest();
request.url = &quot;echo.php&quot;;
request.method = URLRequestMethod.POST;
request.data = myVar;

navigateToURL( request , &quot;_blank&quot; );

&lt;/pre&gt;php echo.php&lt;br /&gt;
&lt;pre class=&quot;brush:php&quot;&gt;$data = $_POST[&#39;postData&#39;];
$arr = json_decode( $data );
echo &quot;undecode data:&quot;.$data;//output:   undecode data: [{&quot;age&quot;:&quot;21&quot;,&quot;name&quot;:&quot;測試者&quot;}]
echo &quot;decode data:&quot; . $arr;//output: decode data:Array
echo &quot;data&#39;s name:&quot;. $$arr[0]-&gt;name;//output:  data&#39;s name:測試者
echo &quot;data&#39;s age:&quot;. $$arr[0]-&gt;age;//output:  data&#39;s age:21
&lt;/pre&gt;這樣的寫法比起xml是不是變的簡潔了許多，在後台就不用在像使用xml需要宣告一個xml的格式去將資料傳回as中，有興趣的人可以嘗試運用在自己的程式當中。</content><link rel='replies' type='application/atom+xml' href='http://greenchiou.blogspot.com/feeds/394395604142968685/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://greenchiou.blogspot.com/2010/07/as3-json.html#comment-form' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/394395604142968685'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7926047175171636650/posts/default/394395604142968685'/><link rel='alternate' type='text/html' href='http://greenchiou.blogspot.com/2010/07/as3-json.html' title='AS3 + JSON 的應用'/><author><name>綠</name><uri>http://www.blogger.com/profile/10866243185938517560</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiROppWVtpB4GpYxBDY_T-AZzPrlMgq71-UD2AMaBewAxJAFPEBE5ccXU3vzceeteWEfSPnvBxBPhFejD55iKs_gygYzs1LCW70HmCi4vUQjwnrisgqhAqI7d06MQ6epw/s220/IMG_6544.JPG'/></author><thr:total>1</thr:total></entry></feed>