2012年12月31日 星期一

UIImage的縮放處理

首先這個問題出現在UILabel要放入一個圖片時,我們必須要將圖片縮放來適應Label的大小,但是Xcode中沒有現成可用的function,因此需要寫一個轉換的Function。

很幸運地在網路上發現了相關的技術
參考 http://my.oschina.net/rareliu/blog/24322

1.等比率缩放
- (UIImage *)scaleImage:(UIImage *)image toScale:(float)scaleSize
{
UIGraphicsBeginImageContext(CGSizeMake(image.size.width * scaleSize, image.size.height * scaleSize);
[image drawInRect:CGRectMake(0, 0, image.size.width * scaleSize, image.size.height * scaleSize)];
UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

return scaledImage;
}

2.自定长宽
- (UIImage *)reSizeImage:(UIImage *)image toSize:(CGSize)reSize
{
UIGraphicsBeginImageContext(CGSizeMake(reSize.width, reSize.height));
[image drawInRect:CGRectMake(0, 0, reSize.width, reSize.height)];
UIImage *reSizeImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

return reSizeImage;
}
以下是我的使用方法 

UILabel *r1_Label = [[UILabel alloc] initWithFrame:CGRectMake(20, 350, 60, 60)];
 UIImage *img = [UIImage imageNamed:@"Aqua.png"];
    

 CGSize imgSize = r1_Label.frame.size;

    r1_Label.backgroundColor = [UIColor colorWithPatternImage:[self reSizeImage:img toSize:imgSize]];



這樣就可以將圖片縮放到Label所要的大小了。理論上這也可以用到其他相關的UIView的元件上。

2012年12月30日 星期日

UIColor 的使用設定(ㄧ)

我們在設定顏色時,一般都使用UIColor來作設定,現在來瞭解一下UIColor的使用

官方使用參考
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIColor_Class/Reference/Reference.html


一般使用
xxx.color = [UIColor  redColor];
               = [UIColor  blackColor];
               = [UIColor greenColor];
               .... 基本顏色外

比較特殊的是設定透明色
 [UIColor clearColor];
 


還可以自定顏色如下例:(紅  綠  藍  透明度)
[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:1.0];
 
[UIColor colorWithRed:0.75 green:0.75 blue:0.75 alpha:1.0], // 銀色
[UIColor colorWithRed:1.00 green:0.84 blue:0.00 alpha:1.0], // 金色
 
使用方法
My Color: #e7008d with RGB: R: 231, G: 0, B: 141

R: 231/255 = 0.905
G: 0/255 = 0
B: 141/255 = 0.552 
 
透明度 1是不透明 0是完全透明 (白色的透明為黑色)
 
 
另外還有一種顏色的設定方法(分別是H指hue(色相)、S指saturation(飽和度)、L指lightness(亮度))
[UIColor colorWithHue:0.223404 saturation:0.944000 brightness:0.990291 alpha:1.0]; 
 
此處定義可參考wiki
http://zh.wikipedia.org/wiki/HSL%E5%92%8CHSV%E8%89%B2%E5%BD%A9%E7%A9%BA%E9%97%B4 


參考設定
+ (UIColor *)colorWithHueDegrees:(CGFloat)hue saturation:(CGFloat)saturation brightness:(CGFloat)brightness {
    return [UIColor colorWithHue:(hue/360) saturation:saturation brightness:brightness alpha:1.0];
}

+ (UIColor *)aquaColor {
    return [UIColor colorWithHueDegrees:210 saturation:1.0 brightness:1.0];
}

+ (UIColor *)paleYellowColor {
    return [UIColor colorWithHueDegrees:60 saturation:0.2 brightness:1.0];
}


與RGB轉換的參考程式碼可參考網址
https://github.com/alessani/ColorConverter


2012年12月29日 星期六

admob廣告的大小位置設定

在使用admob以來,一直不確定有時廣告為何沒有出現,因此確認一下Google在這裡的設定。


1. 一般標準設定

使用方法
bannerView_ = [[GADBannerView alloc] initWithAdSize:kGADAdSizeFullBanner  origin:CGPointMake(0, 690)];

origin: 設定廣告左上角的位置
綠色的字體:是Google建議的廣告大小


2. 聰明(特殊)設定

使用方法
bannerView_ = [[GADBannerView alloc] initWithFrame:CGRectMake(0.0, 670.0, 1024.0, 90.0)];
在此的例子使用1024x90的iPad Landscape




一位台湾软件工程师的心路历程

給有需要的人看看

轉貼自 http://blog.jobbole.com/30525/


前言:台湾的IT环境是什么样的,我们很少关注过。本文作者superbcde是一位台湾程序员,他没有显赫的教育背景,从IT培训学校开始,一步一步走向自己的奋斗目标。他告诫年轻人:要趁着年轻多学习,下定决心,自己不懂什么学什么,最好到硅谷去,因为那里才是 IT 人士的天堂,并透露了台湾的创业环境比较差。本文最初来自PTT论坛,INDIDE做了二次整理,原标题:軟體人的心路歷程分享,TECH2IPO 稍作修改并注释,图片和本文主人公无关。
我是个半路出家的资讯人员(类似于大陆的 IT 人,编辑注),说起来很见笑,我没有深厚背景,也不是正规本科或大学,只是个专科毕业的,补个二技/科大文凭,大学毕业后连一个像样的国立研究所也考不 上。台清交成(台湾大学,新竹清华大学,交通大学,成功大学,编辑注)没有一家我敢投,最后只好报效“国家”二年去,还顺便去外岛进修。
从“巨匠”开始
对,你没看错,当你大学毕业又什么都没有的时候,年轻人是很好骗的。我记得很清楚,那时巨匠(巨匠是台湾最大的IT培训学校,台湾巨匠电脑子公司, 编辑注)有所谓的 SCJP/MCSE 说明会。反正毕业了,没工作又刚退伍,收到这一类的某某进修广告,又免费,当然就去了。
不得不配服巨匠的讲师,详情我忘了,反正我当天听完那门课,只觉得一股热血。觉得有为者亦若是,整个讲题跟技术无关,讲师一堆引经据典,反正简单的讲:“取得认证你就发了,百万年薪等着你。” 当时回家,硬是跟爸妈要了五万多元,办了巨匠白金卡,买了上课卷,然后开始了我的 MCSE + SCJP 课程。至于结果怎么样,我想大家心里有数。我不怪那个说明会的讲师,我自己后来也和不少在巨匠兼任的讲师变成好友。一小时的说明会领不了多少钱,他如果不 是报喜不报忧,我看以后就没人请了,人家不过是混一口饭吃。当然,这是好几年后才了解的。
其实巨匠帮了我很多,但巨匠最大的问题是,你报名时,报的是课程,至于谁教你,你永远不知道。巨匠有不少的好老师,举个例来说,曹祖圣老师。他讲过 很多次 Technet,我也听过他一、二次课,很推荐。可惜的是,因为讲师调度或是节省成本,其实一门 200 小时的课,很有可能只有 1/7 是好老师,剩下的很普通,甚至很糟。我也遇过很差的老师,把电脑课当成英文课在上(英翻中),有上过认证课程就知道我在讲什么(原文教材嘛!)。


当时年轻的我很拼,上课前一定预习。不懂的单词早就查完,上课只想拼命吸收。当你遇到一个很糟的老师,那种挫折感真的很难形容。我和班主任反应了好几次,每次都是得到“喔~我会跟老师沟通”这一类的回应。别闹了好吗,不会教就是不会教,烂老师就是烂,他不会因为一句话就改变。就算他要改变也要时间,不是马上的。
好像有点离题了,总而言之,对不起我爸妈。家里没什么钱,硬是标会借了五万给我上课,最后我放弃了。一直到今天,我还是觉得很欠爸妈这份恩情。总而言之,我想分享的第一件事就是。不管你去巨匠,去 uuu 还是去 iii,最重要的是跟对讲师。如果一门课程的讲师不事先确定(或是讲师不好),不如不要上,真的是好的老师让你上天堂,不好的老师就…。
其实写程序这种东西如果有热情,肯读书,多多少少、或快或慢都会进步。我的第二个建议就是,不要放弃进修,靠自己虽然慢,但是扎实。话 说回来,很多中文书很糟糕,这也不能怪作者。多年后我自己也出版了一本书(卖得很烂),不过作者的稿费其实不高。一刷(第一次印刷) 1500 本,写一本书如果花半年认真写,1500 本卖了 1000 本,然后一本订价 500 (新台币,约107元人民币,编辑注),可能连饭钱都不够。至于比较高的稿费是那种“大师”,像是侯捷老师(台湾著名C++技术专家,编辑注)等级才有可能拿到的价码。也许大家可以试着打给出版社问问,就知道了。要卖到二刷?那你大概要上TOP榜才有可能。
那时我评估过一些选项,也试过不少,不过下场都不这么好。我试过开公司,然后倒掉(没赔多少钱,就当做白工)。写程序容易,找客户难。那时很傻,以为到处都需要 ERP。到 104 接案网(台湾外包网站,编辑注)去找案子,后来发现做的要死要活其实没什么钱,还要应付客户。
也试过人力派遣,薪水不错,一个月可以有六万。不过对不起,没退休年资,案子结束就走人,短期打工(半年~一年)可以。但后来想想,你以为你赚,其实你只是没亏,公司只是把你未来的退休金先付给你而已。当然,不算差,很多人中年被资遣更惨,连退休金都没了。
我摸摸自己的良心,二十几岁的我最大的本钱就是年轻的心。花了二、三年就存了一桶金(一百万),反正就是二份工 作(甚至三份),IT人的好处就是兼职容易。除了体重直线上升,然后缺乏运动,然后有一天就过劳进医院了。因此,最后报个科大混个硕士,毕业后考了个铁饭 碗,反正日子也就这样过了。其实铁饭碗的日子挺不错的,钱虽不多,中油、台电、中华电信、一类的,我想公司倒掉到不至于。虽不是公务员的钢饭碗,但其实不 要太混、准时上下班还是过的去。

下定决心走出台湾
我问问我自己,是有一些优点的:
年轻,然后肯拼(那时 26~27 岁);认份,有责任感;肯读书,想进修。
但我其实对未来感到很迷惘,直到有一天,过到了一个外商的经理(听说月薪 40 万),是一个香港人,刚好和我在一个政府标案里合作。我常常在想,为什么他可以领 40 万,他很厉害,但没有我十倍厉害吧?我也想月领 40 万,谁不想……
总之,回头看回去,下面是我当时的结论(冒犯请见谅):
台湾是没有「软件」产业的,这几年好一点,有地图日记、appworks 一类的软件(or 创投),顶多有 TrendMicro,或是一些接标案为主的IT公司。IT最大的需求大概都在金融业(需要资讯人员)。最大的需求大概都是架网站一类的,这种市场竞争很激烈,然后没美工合作很难生存,就算是架个网站购物车一类的,也只是跑单帮,很难长久。
想领 40 万,真的不可能,外商也许有机会。如果有 40 万的工作,那也是万中选一,轮不到我这个半路出家的巨匠肆业生。那只剩下一条路:
去硅谷。
我爸爸不是什么高等教育份子,不过他常常跟我说:“不要在山上要吃海产,去海边才要吃山珍。”他想劝我人要认 份,但年轻的我解读错他的意思:“想吃山珍我就到山上去。”同理,想走金融业请到华尔街。为什么?因为市场就是供给和需求决定价格。台湾的需求太少 了,IT公司不可能出高价格。供给不够(IT人材),价格自然就上升。分享一下,其实硅谷这几年一直到现在都很缺IT人材。我知道很多名校高手,英文好, 实力好可以直冲硅谷,不过我不是。我知道自己是什么料,没有个五六年,我的英文不可能通得过面试。
所以我放下自己,放下工作,从头练起。过去的六年间:我把英文练起来,我的经验是:
●没钱我就到系上当助教,一开始助教找不到就四处找帮忙写程序的研究助理(相信我,这很好找)。美国的物价贵,学校研究助理一个月也不多,大概都只能吃吐司或是微波食品。
●从头念起,把 CS(Computer Science 电脑科学)大学部的课自己需要的部份都修一次或旁听,然后念一个硕士,再念一个 CS PhD。学历也补起来,没办法进 Stanford/MIT,至少也读个叫得出来的 PhD。
●每个暑假都去 Intern 赚钱。

简单的讲,认清自己缺什么,就补什么。缺英文补英文,缺学历补学历等。后来才发现,这些工作反而帮了我很多。当 助教免费练英文口说,所以我的口说进步神速。接案或是当研究助理写程序,逼我学起整套 Linux 及很多的 open source project(学术界没钱,一律都是open source)然后念 PhD 让我到世界各地去参加 conference,认识领域理的大咖。相信我,等你亲自见到 internet、python … 等的发明人,你会发现他们非常谦虚。然后没钱去 intern(所以很怕对方不要我),所以很拼。最后交了一堆朋友,还没毕业工作就找好了,然后累积了一堆 Project 经验。

选择环境或适应环境
当然,这只是个案例,但毕业时第一份工作,我的年薪含保证的奖金,有 1/3 是奖金,2/3 是本薪。当然,第一年因为有 sign up bonus(签约奖金),不过之后只要努力,我想薪水比起第一年来说不会差太多。这里不想讨论税多重、生活费等问题。但缴完税省一点,一年可以存 8~10 万左右。如果自己买房,省下租金可以更多(但是要缴房贷)。以一间 3 房 2 卫的独栋房子,目前好一点的区(不是 Palo Alto 一类的顶级区)硅谷大概 80~100 万左右。
也就是说,顺利的话,不到十年就可以还清。而且我相信只要肯拼,薪水只会更高,不会更低。也有听过 CS 博士毕业拿 30 万以上的(当然都只是听说)。1/3 的走教职,1/3 的去研究单位,剩下去业界的样本不多。不过我想整个 package 加起来超过 20 万是很基本(有料的 PhD)。然后工作大致上一天八小时,很少需要加班,不用 on-call。当然,自己决定留在公司念书或上网吹冷气不能算加班,我讲的是真的工作。
P.S.对这些薪水很有兴趣的可以参考这一篇《北美2011年各大公司H1B工资全记录》。有高手拿出来分享,这是去年 H1B 的资料(外国人在美国申请工作签证)
上面的数据只有“底薪”,另有实拿股票 + 各式各样 bonus。工程师可能要再加 20~30% 上去,尤其是第一年。现在抢人抢很凶,刚毕业有可能就被开 4~5 万以上的 sign up bonus,甚至大陆圈子里在传 Facebook 最高开到 10 万的 sing up bonus。如果是高阶的职务,底薪可能只占不到1/3,因为这些工作都会绑绩效,而且绑很多。
这里不是要批评台湾薪水低。每个地方,都有他的供给与需求。如果你想从事IT产业,然后你的思想还算新鲜。我真的建议「走出去」。我 也想回台湾,台湾 Yahoo 的猎头有找上我。考虑物价后,我开了十万美元(整个 package)当条件,对方面试都不面试。当然也不是真的非十万美元不可,不过想当然尔,台湾的供给(IT工程师)很多,我是他的话我也不想花 300 万台币找一个。对他们来说,300 万可以请 12~13 个 22k。
假设付得起,今天你生病要开刀,一个顶级名医要价 30 万,或是你可以请 10 个 3 万的普通医生来会诊,你会选那个?经验这种东西不是十个人就打的赢一个的,但是如果是写网页,我相信十个人也许有机会写赢一个专家。但网站挂点,不会动就 是不会动,找十个人 debug 不一定比较快。经验和能力的价值不是劳力可以单纯取代的,尤其是对技术和经验要求更高的工作或专案而言。对未来,我还是有一些想法,但回首过去,我很庆幸 我当初有放下身段和收入,然后从头学起。
我不会去问当初我留下来的话,现在我会怎样又怎样。但我知道一件事,人要看下一个十年,然后再下一个十年。有一天,你我都会老,都会 35,都会 45,都会 55。55 岁的人学技术是学不赢 25 岁的好吗,真的。你要累积那种 25 岁的人不可能轻易复制的经验。
举个例来说,想读 PhD 的话,请在 35 岁前读,35 岁以后读起来是很困难的。想创业的话,请在 35 岁以前创,因为你失败了可以容易再爬起来。我看到很多比我优秀很多的年轻人,在浪费他们的年轻的资本,在浪费他们的 25~35。其实,IT生涯有无限的可能,Dropbox 的创办人 24 岁就创立了公司,Google 和 Facebook 的创立,那些人也都才几岁?(p.s 不是创业都会成功,请别误解)

总结:
我真的想鼓励那些年轻的朋友,如果你真的想改变,Just do it!我当时只想要一个月赚 40 万台币,现在我在幻想一个月能不能赚 400 万。其实密诀很简单,找一个赚那么多的人,然后比较你和他的不同,然后给自己十年去追上去,然后不要放弃。
这篇文章写给年轻人,也写给我自己,希望十年后能回来再写一次 :)
大家一起加油吧!

2012年12月28日 星期五

透明的Button (一)

透明的Button有兩種,一種是圖檔方式,另一種是文字模式。

圖檔方式

首先要使用Photoshop或Gimp之類的圖形處理軟體先產生一個背景為透明的PNG檔,因為PNG檔可以記錄背景為透明的資料,其它圖檔如JPG或BMP是不能記錄背景為透明的檔案。

一個在GIMP下顯示的透明圖檔效果


然後放到Xcode的效果,當背景為紅色,上圖為JPG檔,下圖為PNG檔。


文字模式

在Xcode下,將type設為Custom模式,就可以了

效果如下




2012年12月27日 星期四

Core Animation的基本使用(二十二)

CAGradientLayer可以方便的加入颜色渐变的layer。

一個最簡當的例子,在主畫面的背景中加入一個紅綠藍的連續色圖。暫時還不知道要應用到那種設計上。

CAGradientLayer *gradient = [CAGradientLayer layer];
    gradient.frame = CGRectMake(0, 0, 1024, 768); // self.view.bounds
    gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor redColor] CGColor],
                       (id)[[UIColor greenColor] CGColor],
                       (id)[[UIColor blueColor] CGColor],
                       nil]; // 由上到下的漸層顏色
    

    [self.view.layer  insertSublayer:gradient atIndex:0];  // 加到最上層



產生如下的結果

2012年12月26日 星期三

動態產生 UIViewController (三)

前一篇的實作使用了Navigation Bar來做聯結,現在要嘗試不要使用Navigation Bar,亦不用Segue。

實作如下
1. 開啓一個新的專案

2. 一樣加入一個新的UIViewController 的Class檔


3. 在storyboard上加入一個Button,來作啓動

4. 現在先從mainViewController.h開始
#import <UIKit/UIKit.h>
#import "secondViewController.h"

@interface mainViewController : UIViewController

@property (nonatomic) secondViewController  *secondView;

@end

5.在mainViewController.m加入啓動second ViewController程式碼
#import "mainViewController.h"

@interface mainViewController ()

@end

@implementation mainViewController

@synthesize secondView;

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)toSecondViewController:(id)sender {
    secondView = [[secondViewController alloc] init];
   
    // secondView.view.backgroundColor = [UIColor yellowColor];
   
    NSString *Stringvalue = [NSString stringWithFormat:@"%d",345];
   
    [secondView setValue:Stringvalue forKey:@"transferString"];
   
    [self presentViewController:secondView animated:YES completion:^{}];
}

@end





 

6. 在secondViewController.h加入所需傳送變數及呼叫的Function定義。
#import <UIKit/UIKit.h>

@interface secondViewController : UIViewController
{
    NSString *transferString;
}

- (void) goBackMainViewController;


@end


7. 在secondViewController.m加入顯示及回歸的程式碼
#import "secondViewController.h"

@interface secondViewController ()

@end

@implementation secondViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
   
    NSLog(@"%@", transferString);
   
    self.view.backgroundColor = [UIColor yellowColor];
   
    UIButton *aButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [aButton setFrame:CGRectMake(300, 300, 75, 37)];
    aButton.backgroundColor = [UIColor  redColor];
    [aButton setTitle:transferString forState:UIControlStateNormal];
   
    [aButton addTarget:self action:@selector(goBackMainViewController) forControlEvents:UIControlEventTouchUpInside];
   
    [self.view addSubview:aButton];

   
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void) goBackMainViewController
{
    
    [self dismissViewControllerAnimated:YES completion:^{}];
}

@end



8. 顯示結果


2012年12月25日 星期二

xcode 4.5.2的Bug

在網址ㄓ今天發現一個bug在Xcode4.5.2,我的SDK是IOS6.0

事件經過
1. 起因於改變delopment target 到4.3

2. 然後再一次Build就會出現紅色的錯誤Storyboards are unavailable on iOS 4.3 and prior,這個錯誤不論重開機或是重建一個專案,都無法消除。在網址
http://stackoverflow.com/questions/7781483/ios5-storyboard-error-storyboards-are-unavailable-on-ios-4-3-and-prior

3. 發現解法,試過數個還是不能解決。最後一個方法,將storyboard砍掉,但不從目錄移除,只移除reference,然後再一次Build就可以了。這時沒有storyboard,就再一次建一個新的storyboard就可以了。此處建議用一個新的專案來做測試比較好。


4. 目前情況是deployment target可以設到5.0,但IOS Simulator只能使用6.0版。這個bug似乎從xcode 5.0以後就出現了。可是Apple似乎還沒解決???

5. 所有的解法看過一遍,似乎大家都沒有很好的解釋其成因,而我自己的解法,看起來是最簡單的了。

2012年12月24日 星期一

動態產生 UIViewController (二)

一般使用動態的UIViewController,就是為了要產生一個新的頁面。以下實作一個動態產生的UIViewController,配合Navigation來做回歸前頁的動作,並且傳送一個值到新的UIViewController上,然後顯示在動態產生的Button上。此處不會用到Segue。

1. 開啓一個專案

2. 加入一個button到Storyboard上作為啓動新的動態UIViewController
3. 加入一個UIVeiwController 的Class檔到專案中


4. 在mainViewController.h加入動態UIViewController的變數
#import <UIKit/UIKit.h>
#import "secondViewController.h"

@interface mainViewController : UIViewController

@property (nonatomic) secondViewController  *secondView;

@end


5. 在mainViewController.m加入啟動動態UIViewController的程式碼
#import "mainViewController.h"

@interface mainViewController ()

@end

@implementation mainViewController

@synthesize secondView;

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)genDynamicViewController:(id)sender {
   
    secondView = [[secondViewController alloc] init];
   
   // secondView.view.backgroundColor = [UIColor yellowColor];  //不可先設定,會呼叫到viewDidLoad,而使得傳值
較慢被呼叫,因此無法將值傳到secondView。 
   
    NSString *Stringvalue = [NSString stringWithFormat:@"%d",123];
   
    [secondView setValue:Stringvalue forKey:@"transferString"];
   
    [self.navigationController pushViewController:secondView animated:YES];

}

@end



6. 在secondViewController.h加入傳送變數
#import <UIKit/UIKit.h>

@interface secondViewController : UIViewController
{
    NSString *transferString;
}

@end



7. 在secondViewController.m加入啓動程式碼
#import "secondViewController.h"

@interface secondViewController ()

@end

@implementation secondViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
   
     NSLog(@"%@", transferString);
   
     self.view.backgroundColor = [UIColor yellowColor];
   
    UIButton *aButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [aButton setFrame:CGRectMake(300, 300, 75, 37)];
    aButton.backgroundColor = [UIColor  redColor];
    [aButton setTitle:transferString forState:UIControlStateNormal];
   
    [self.view addSubview:aButton];

   
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end


8. 執行結果


2012年12月23日 星期日

UIColor 處理

網路上發現兩篇關於UIColor的文章,在此整理一下。

1. UIColor获取RGB值

找出UIColor的RGB設定

2. 将RGB颜色值转换为UIColor 

將RGB值設定成UIColor的顏色



2012年12月22日 星期六

Popover在iPad上的使用(三)

一個動態產生的Popover

實作如下

1. 開啓一個專案

2. 在storyboard加上一個button

3. 在mainViewController.h加上一個popover的變數

#import <UIKit/UIKit.h>

@interface mainViewController : UIViewController
{
    UIPopoverController  *popover;
}

@end

4. 在mainViewController.m加上程式碼
#import "mainViewController.h"

@interface mainViewController ()

@end

@implementation mainViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
- (IBAction)startPopover:(id)sender {
   
    UIView *anchor = sender;
   
    UIViewController *showView1 = [[UIViewController alloc] init];
   
    showView1.view.backgroundColor = [UIColor redColor];
   
   
    UILabel *testLabel =[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 150, 150)];
    testLabel.backgroundColor = [UIColor clearColor];
    testLabel.textColor = [UIColor blackColor];
    testLabel.text = @"Hello";
   
    [showView1.view addSubview:testLabel ];
   
   
    popover = [[UIPopoverController alloc]
               initWithContentViewController:showView1];
   
    [popover setPopoverContentSize:CGSizeMake(300, 300)];
   
    [popover presentPopoverFromRect:anchor.frame inView:anchor.superview permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
   
}

@end

5. 執行結果,因為popover不能設定x方向的位置,所以x位置為0。

2012年12月21日 星期五

NSRect V.S. CGRect


1. NSRect is used in Cocoa // #import <Cocoa/Cocoa.h>

2. CGRect is used in Core Graphics and Core Image //  #import <UIKit/UIKit.h>






在此我們看到官方文件註明,因此兩個幾乎是一樣的,只是在不同的OS使用而已。
// NSValue/+valueWithRect:(NSRect)rect is available on Mac OS X
// NSValue/+valueWithCGRect:(CGRect)rect is available on iOS

參考
http://developer.apple.com/library/ios/#qa/qa1620/_index.html#//apple_ref/doc/uid/DTS40008060


其他官方文件
1. https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaDrawingGuide/QuartzOpenGL/QuartzOpenGL.html#//apple_ref/doc/uid/TP40003290-CH211-BAADHIAF

2. https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation_DataTypes/Reference/reference.html


Cocoa defines several fundamental data types for manipulating geometric information in the drawing environment. These data types include NSPoint, NSRect, and NSSize. You use these data types to specify lines, rectangles, and width and height information for the shapes you want to draw. Everything from lines and rectangles to circles, arcs, and Bezier curves can be specified using one or more of these data structures.

The coordinate values for point, rectangle, and size data types are all specified using floating-point values. Floating-point values allow for much finer precision as the resolution of the underlying destination device goes up.
The NSPoint, NSRect, and NSSize data types have equivalents in the Quartz environment: CGPoint, CGRect, and CGSize. Because the layout of the Cocoa and Quartz types are identical, you can convert between two types by casting from one type to its counterpart.







NSPoint

Represents a point in a Cartesian coordinate system.
typedef struct _NSPoint {
      CGFloat x;
      CGFloat y;
} NSPoint; 
 

NSSize

Represents a two-dimensional size.
typedef struct _NSSize { 
             CGFloat width; 
             CGFloat height; 
} NSSize;
 

NSRect

Represents a rectangle.
typedef struct _NSRect { 
            NSPoint origin; 
            NSSize size; 
} NSRect;
 
NSRECT example

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

- (void)drawRect:(NSRect)dirtyRect
{
   NSLog(@"have draw");
    if (flag==0) {
        [[NSColorredColor] set]; //设置颜色
        NSRectFill(dirtyRect);
    }else
    {
        [[NSColoryellowColor] set]; //设置颜色
        NSRectFill(dirtyRect);
        flag=0;
    }
   //填充rect区域.
}

CGRECT Example
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self setup]; // get initialized if someone uses alloc/initWithFrame: to create us
    }
    return self;
}
- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
   
    CGPoint midPoint; // center of our bounds in our coordinate system
    midPoint.x = self.bounds.origin.x + self.bounds.size.width/2;
    midPoint.y = self.bounds.origin.y + self.bounds.size.height/2;
   
    CGFloat size = self.bounds.size.width / 2;
    if (self.bounds.size.height < self.bounds.size.width) size = self.bounds.size.height / 2;
    size *= self.scale; // scale is percentage of full view size
   
    CGContextSetLineWidth(context, 5.0);
    [[UIColor blueColor] setStroke];
   
    [self drawCircleAtPoint:midPoint withRadius:size inContext:context]; // head
}



其他的轉換例
refer to http://cocoadev.com/wiki/NSRectToCGRect

From Mac OS X 10.5 (Leopard) onwards, Apple provide an inline function to do this:

CGRect NSRectToCGRect(NSRect nsrect);

as well as the matching function:

NSRect NSRectFromCGRect(CGRect cgrect);













2012年12月20日 星期四

Core Animation的基本使用(二十一)

CAKeyframeAnimation

先大致瞭解一下动画类和定时
core animation提供了一组富于表现力的动画类,你在程序中可以使用他们:
1. CABasicAnimation 为层属性提供了简单的插值。(Core Animation的基本使用(五))
2. CAKeyframeAnimation 提供了关键帧动画支持。你指定需要做动画的层属性的键路径,由一组值组成的数组代表动画每个阶段的值,同样可以用数组指定关键帧时间和定时含税。在动画运行过程中,每个值依次使用指定的插值设置。
3.CATransition提供了一个过度效果,能够影响整个层的内容。在动画进行时,它淡入淡出,推入和暴露层的内容。现有的过渡效果可以被扩展,你可以提供自定义的Core图像过滤器。 (Core Animation的基本使用(ㄧ))
4. CAAnimationGroup允许一些动画对象的数组组合在一起同时运行。


任何动画要表现出运动或者变化,至少需要两个不同的关键状态,而中间的状态的变化可以通过插值计算完成,从而形成补间动画,表示关键状态的帧叫做关键帧.
CABasicAnimation 其实可以看作一种特殊的关键帧动画,只有头尾两个关帧.
CAKeyframeAnimation则可以支持任意多个关键帧,关键帧有两种方式来指定,
1. 使用path或者使用values,path是一个CGPathRef的值,且path只能对CALayer的 anchorPoint 和 position 属性起作用,且设置了path之后values就不再起效了.
2. values则更加灵活. keyTimes这个可选参数可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0,keyTimes中的每一个时间值都对应values中的每 一帧.当keyTimes没有设置的时候,各个关键帧的时间是平分的.

other. 还可以通过设置可选参数timingFunctions(CAKeyframeAnimation中timingFunction是无效的)
为关键帧之间的过渡设置timingFunction,如果values有n个元素,那么timingFunctions则应该有n-1个.但很多时候并不需要 timingFunctions,因为已经设置了够多的关键帧了,比如没1/60秒就设置了一个关键帧,那么帧率将达到60FPS,完全不需要相邻两帧的 过渡效果(当然也有可能某两帧 值相距较大,可以使用均匀变化或者增加帧率,比如每0.01秒设置一个关键帧).
在关键帧动画中还有一个非常重要的参数,那便是calculationMode,计算模式.其主要针对的是每一帧的内容为一个座标点的情况,也就是对 anchorPoint 和 position 进行的动画.当在平面座标系中有多个离散的点的时候,可以是离散的,也可以直线相连后进行插值计算,也可以使用圆滑的曲线将他们相连后进行插值计算. calculationMode目前提供如下几种模式 kCAAnimationLinear
kCAAnimationDiscrete
kCAAnimationPaced
kCAAnimationCubic
kCAAnimationCubicPaced
kCAAnimationLinear calculationMode的默认值,表示当关键帧为座标点的时候,关键帧之间直接直线相连进行插值计算;
kCAAnimationDiscrete 离散的,就是不进行插值计算,所有关键帧直接逐个进行显示;
kCAAnimationPaced 使得动画均匀进行,而不是按keyTimes设置的或者按关键帧平分时间,此时keyTimes和timingFunctions无效;
kCAAnimationCubic 对关键帧为座标点的关键帧进行圆滑曲线相连后插值计算,对于曲线的形状还可以通过tensionValues,continuityValues,biasValues来进行调整自定义,这里的数学原理是Kochanek–Bartels spline,这里的主要目的是使得运行的轨迹变得圆滑;
kCAAnimationCubicPaced 看这个名字就知道和kCAAnimationCubic有一定联系,其实就是在kCAAnimationCubic的基础上使得动画运行变得均匀,就是系统时间内运动的距离相同,此时keyTimes以及timingFunctions也是无效的。
此處的運用還頗為複雜,待有需要再來研究。

官方文件
https://developer.apple.com/library/mac/#documentation/GraphicsImaging/Reference/CAKeyframeAnimation_class/Introduction/Introduction.html#//apple_ref/occ/cl/CAKeyframeAnimation

先留一段example,待有空再來研究細節的使用。

CALayer *layer = imageView.layer;
    CAKeyframeAnimation *animation;
    animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"];
    animation.duration = 8;
    animation.cumulative = NO;
    animation.repeatCount = 0;
    animation.values = [NSArray arrayWithObjects:           // i.e., Rotation values for the 3 keyframes, in RADIANS
                        [NSNumber numberWithFloat:[self dialStartPosition] * M_PI], 
                        [NSNumber numberWithFloat:2.5 * M_PI], 
                        [NSNumber numberWithFloat:[self dialEndPosition] * M_PI], nil]; 
    animation.keyTimes = [NSArray arrayWithObjects:     // Relative timing values for the 3 keyframes
                          [NSNumber numberWithFloat:0], 
                          [NSNumber numberWithFloat:.055], 
                          [NSNumber numberWithFloat:1], nil]; 
    animation.timingFunctions = [NSArray arrayWithObjects:
                                 [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn],
                                 // from keyframe 1 to keyframe 2
                                 [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut], nil]; // from keyframe 2 to keyframe 3
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;

    [layer addAnimation:animation forKey:nil];
  

實作一個基本例來測試僅就path的地方簡單的測試一下。
1. 開啓一個專案

2. 在Storyboard加上一個Button

3. 在mainViewController.h加上instance變數
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>

@interface mainViewController : UIViewController
{
    CALayer *pinLayer;
   
    CGMutablePathRef starPath;
}

@end

4. 在mainViewController.m加上程式碼
#import "mainViewController.h"

@interface mainViewController ()

@end

@implementation mainViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
   
    [self createPath];
   
    pinLayer = [CALayer layer];
    [pinLayer setBounds:CGRectMake(0.0, 0.0, 10.0, 10.0)];
    // Set the corner radius to half the size of the
    // bounds to simulate a circle.
    [pinLayer setCornerRadius:5.0];
    [pinLayer setBackgroundColor:[[UIColor redColor] CGColor]];
    [pinLayer setPosition:CGPointMake(160.0, 260.0)];
      
    self.view.layer.backgroundColor = [[UIColor blueColor] CGColor];
   
    [self.view.layer insertSublayer:pinLayer atIndex:0];
 
}

- (void)createPath;
{
    CGMutablePathRef starPath = CGPathCreateMutable();
    CGPathMoveToPoint(starPath,NULL,160.0, 260.0);
}


- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
- (IBAction)startAnimation:(id)sender {
   
    if( starPath )
     {
    // Reset our starPath CGMutablePathRef if
    // it has already run before
    CFRelease(starPath);
    [self createPath];
   
    }
   
    // Define a path for the star shape.
    CGMutablePathRef path = CGPathCreateMutable();

   
    CGPathMoveToPoint(path,NULL,160.0, 380.0);
   
    CGPathAddLineToPoint(path, NULL, 101.0, 179.0);
    CGPathAddLineToPoint(path, NULL, 255.0, 290.0);
    CGPathAddLineToPoint(path, NULL, 64.0, 290.0);
    CGPathAddLineToPoint(path, NULL, 218.0, 179.0);
    CGPathCloseSubpath(path);
   
    CAKeyframeAnimation *animation =
    [CAKeyframeAnimation
     animationWithKeyPath:@"position"];

    [animation setDuration:10.0f];
    [animation setDelegate:self];
   
    // Set the animation's path
    [animation setPath:path];
   
    [pinLayer addAnimation:animation forKey:@"position"];       
}

@end

5.執行結果,紅點會以五星圖的位置移動。


 

2012年12月19日 星期三

Core Animation的基本使用(二十)

Autoresizing Mask

在CALayer Class Guide有描述此功能,但實作時發現沒有相關的property,無法使用,查看了網路資料,例子好像都是2009以前的,因此懷疑已被Apple移除,現在只從在UIView相關的Class還有此功能。

kCALayerHeightSizable
如果被设置,层的高度随超层的高度改变。否则,层的高度不随超层的高度改变。

kCALayerWidthSizable
如果被设置,层的宽度随超层的宽度改变。否则,层的宽度不随超层的宽度改变。

kCALayerMinXMargin
如果被设置,层的左边缘将随超层的宽度重新定位。否则,层的左边缘相对于超层的边缘保持相同的位置。

kCALayerMaxXMargin
如果被设置,层的右边缘将随超层的宽度重新定位。否则,层的右边缘相对于超层的边缘保持相同的位置。

kCALayerMaxYMargin
如果被设置,层的上边缘将随超层的宽度重新定位。否则,层的上边缘相对于超层的边缘保持相同的位置。

kCALayerMinYMargin
如果被设置,层的下边缘将随超层的宽度重新定位。否则,层的下边缘相对于超层的边缘保持相同的位置。
举例来说,为了让层保留在其超层的左下角,可使用kCALayerMaxXMargin | kCALayerMaxYMargin掩码。当在同轴方向上有多个活动掩码时,改变值将在它们之中均匀的分布,图1提供了这些常量值位置的图形表示。

图1 层的autoresizing mask常量


当这些常量之一被省略时,层的布局在那个方面被固定。如果一个常量出现在掩码中,那层的布局在那个方面是活动的。

层的子类可以覆盖resizeSublayersWithOldSize: 和 resizeWithOldSuperlayerSize: 方法,来自定义层的autoresizing行为。只要层的bounds属性被修改,resizeSublayersWithOldSize:将被自定调 用,并发送一个resizeWithOldSuperlayerSize:消息给每一个子层。每一个子层将旧的bounds size和新的size做比较,并根据autoresizing mask调整其位置和尺寸。

2012年12月18日 星期二

Core Animation的基本使用(十九)

CAAnimationGroup允许将一组动画放在一个数组里面,然后同时执行。

官方文件
https://developer.apple.com/library/ios/#documentation/GraphicsImaging/Reference/CAAnimationGroup_class/Introduction/Introduction.html#//apple_ref/occ/cl/CAAnimationGroup


直接用實作來看看執行結果

1. 沿用前一個專案,然後加上一個Button。

2. 在mainViewController.m加上程式碼
- (IBAction)startAnimationGroup:(id)sender {
   
    CGRect oldRect = CGRectMake(0.0, 0.0, 100.0, 100.0);
   
    CGRect newRect = CGRectMake(0.0, 0.0, 300.0, 300.0);
   
    CABasicAnimation *boundsAnimation =[CABasicAnimation animationWithKeyPath:@"bounds"];
   
    [boundsAnimation setFromValue:[NSValue valueWithCGRect:oldRect]];
   
    [boundsAnimation setToValue:[NSValue valueWithCGRect:newRect]];
   
    [boundsAnimation setDuration:15.0f];
   
    [boundsAnimation setBeginTime:0.0f];
   
    CABasicAnimation *positionAnimation =   [CABasicAnimation  

animationWithKeyPath:@"postition"];
   
    [positionAnimation setFromValue:[NSValue valueWithCGPoint:mainLayer.position]];
   
    [positionAnimation setToValue:[NSValue valueWithCGPoint:CGPointMake(0,0)]];
   
    [positionAnimation setDuration:15.0f];
   
    [positionAnimation setBeginTime:5.0f];
   
    CABasicAnimation *borderWidthAnimation = [CABasicAnimation animationWithKeyPath:@"borderWidth"];
   
    [borderWidthAnimation setFromValue:[NSNumber numberWithFloat:5.0f]];
   
    [borderWidthAnimation setToValue:[NSNumber numberWithFloat:30.0f]];
   
    [borderWidthAnimation setDuration:15.0f];
   
    [borderWidthAnimation setBeginTime:10.0f];
   
    CAAnimationGroup *group = [CAAnimationGroup animation];
   
    [group setDuration:15];
   
    [group setAnimations:
    
     [NSArray arrayWithObjects:boundsAnimation,
     
      positionAnimation,
     
      borderWidthAnimation, nil]];
   
    [mainLayer addAnimation:group forKey:nil];

}


3. 執行結果,從原始的狀態,然後變成一個小的開始漸漸變大。


 


2012年12月17日 星期一

Core Animation的基本使用(十八)

CALayer的属性contentsGravity允许你在图层的边界内容修改图层的contents图片的位置或者伸缩值。


使用contentsGravity位置常量,你可以指定图片位于图层任何一个边界,比如位于图层的角落,或者图层边界的中心。然而当你使用位置常量的时候,contentsCenter属性会被忽略。表1列举了位置常量和他们相应的位置。

表1 层的contentsGravity属性的定位常量

定位常量
描述

kCAGravityTopLeft
将内容图像定位到层的左上角。

kCAGravityTop
将内容图像定位到层的上边缘的水平居中位置。

kCAGravityTopRight
将内容图像定位到层的右上角。

kCAGravityLeft
将内容图像定位到层的左边缘的垂直居中位置。

kCAGravityCenter
将内容图像定位到层的中心。

kCAGravityRight
将内容图像定位到层的右边缘的垂直居中位置。

kCAGravityBottomLeft
将内容图像定位到层的左下角。

kCAGravityBottom
将内容图像定位到层的下边缘的水平居中位置。

kCAGravityBottomRight
将内容图像定位到层的右下角。

“层坐标系”标明了所支持的内容位置和相应的常量。

图1 层的contentsGravity属性的定位常量



    通过设置contentsGravity属性为其他一个常量(如表2所示)。图层的内容图片可以被向上或者向下拉伸, 仅当使用其他任何一个调整大小的常量的时候,contentsCenter属性才会对内容图片起作用。另外實作上發現,使用上Top的位置在下面,而Button的位置在上面,不知有什麼問題。

表2 层的contentsGravity的缩放常量

缩放常量
描述

kCAGravityResize
缩放内容图像以填充层边界,可能无视内容的自然比例,这是默认值。

kCAGravityResizeAspect
缩放内容图像使其竟可能占满层边界显示,但他仍然保持自然比例。

kCAGravityResizeAspectFill
缩放内容图片使其占满层显示,但仍保持自然比例。这可能导致内容超越到层边界之外。


“变换层的几何特性”表明了如何使用resizing模式,让一个正方形图像在一个矩形层内调整缩放比例。

图2 层的contentsGravity属性的缩放常量


如果沒有設定,則Default值為kCAGravityResize,讓內容自動填滿Layer。






以下是實作的測試例

1. 沿用前一篇的例子來作修改,加上十二個Button,分別代表十二個屬性,並且選用一個較為適中的圖檔大約300x300pixels,這樣才好看出結果。

 2. 直接在mainViewController.m加上所需要的程式碼。
#import "mainViewController.h"

@interface mainViewController ()

@end

@implementation mainViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
   
    // Create the tach's background layer
    mainLayer = [CALayer layer];
    mainLayer.bounds = CGRectMake(0, 0, 800, 500);
    mainLayer.position = CGPointMake(500, 500);
    mainLayer.contents = (id)[UIImage imageNamed:@"speed.png"].CGImage;
   
    mainLayer.backgroundColor = [[UIColor redColor] CGColor];
   
   
    maskLayer = [CALayer layer];
    maskLayer.frame = CGRectMake(100, 100, 200, 200);
    UIColor *c2 = [UIColor blueColor];
    maskLayer.name = @"maskLayer";
    maskLayer.cornerRadius = 100.0f; //變成圓形的
    [maskLayer setBackgroundColor:(c2.CGColor)];
   
    [self.view.layer addSublayer:mainLayer];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
- (IBAction)startMask:(id)sender {
   
    UIPanGestureRecognizer* panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
    [self.view addGestureRecognizer:panGesture];
   
     [mainLayer setMask:maskLayer];
   
}
-(void)handleGesture:(UIGestureRecognizer*)gestureRecognizer
{
    if([gestureRecognizer isMemberOfClass:[UIPanGestureRecognizer class]])
    {
        UIView* piece = [gestureRecognizer view];
        if ([gestureRecognizer state] == UIGestureRecognizerStateBegan ||
            [gestureRecognizer state] == UIGestureRecognizerStateChanged)
        {
            UIPanGestureRecognizer* panGestureRecognizer = (UIPanGestureRecognizer*)gestureRecognizer;
            CGPoint translation = [panGestureRecognizer translationInView:self.view];
           
            CGFloat X, Y;
           
            X = maskLayer.position.x+translation.x;
            Y = maskLayer.position.y + translation.y;
           
            if (X >600)
                X = 600;
           
            if (X<100)
                X=100;
           
            if (Y > 600)
                Y =600;
           
            if (Y<100)
                Y=100;
           
            maskLayer.position = CGPointMake(X, Y);
           
           
        }
    }
}

- (IBAction)enablekCAGravityTopLeft:(id)sender {
   
    mainLayer.contentsGravity = kCAGravityTopLeft;
}

- (IBAction)enablekCAGravityTop:(id)sender {
   
    mainLayer.contentsGravity = kCAGravityTop;
}

- (IBAction)enablekCAGravityTopRight:(id)sender {
   
    mainLayer.contentsGravity = kCAGravityTopRight;
}

- (IBAction)enablekCAGravityLeft:(id)sender {

    mainLayer.contentsGravity = kCAGravityLeft;
}

- (IBAction)enablekCAGravityCenter:(id)sender {

    mainLayer.contentsGravity = kCAGravityCenter;

}

- (IBAction)enablekCAGravityRight:(id)sender {
   
    mainLayer.contentsGravity = kCAGravityRight;
   
}

- (IBAction)enablekCAGravityBottomLeft:(id)sender{

    mainLayer.contentsGravity = kCAGravityBottomLeft;

}

- (IBAction)enablekCAGravityBottom:(id)sender {
   
    mainLayer.contentsGravity = kCAGravityBottom;
}

- (IBAction)enablekCAGravityBottomRight:(id)sender{
   
    mainLayer.contentsGravity = kCAGravityBottomRight;
}

- (IBAction)enablekCAGravityResize:(id)sender {
   
    mainLayer.contentsGravity = kCAGravityResize;
}

- (IBAction)enablekCAGravityResizeAspectFill:(id)sender {
   
    mainLayer.contentsGravity = kCAGravityResizeAspectFill;
}

- (IBAction)enablekCAGravityResizeAspect:(id)sender {
   
    mainLayer.contentsGravity = kCAGravityResizeAspect;
}


@end

3. 執行結果,依照表格的順序執行,分別截圖。第一張是剛執行App的原始狀態。