2013年4月30日 星期二

關於 property 的二三事

在現行的的教學書籍都只是說 IBOutlet 需要用 property
接下來就沒有了
其實 property 包含了你所不知道的東西

property 其實是會自動產生 Setter 與 Getter 的兩個 Method
但是這兩個 Method 的實作是可以被覆寫的
你可以做你想要的實作動作
像是你做了 @property (nonatomic, retain) UIImage *image;
之後你可以在 m 檔中覆寫 Setter 的實作

- (void)setImage:(UIImage *)image
{	UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
	[imageView setFrame:self.view.bounds];
	[imageView setTag:1];
	
	[self.view addSubview:imageView];
	[imageView release];
}

當你覆寫 Setter 的時候你不需要使用 @synthesize image = _image;
因為你自己決定了 Setter 傳入參數的作用了
不過當覆寫 Setter 時,Getter 也需要被覆寫
所以就來做覆寫 Getter 的 Method

- (UIImage *)image
{	UIImageView *imageView = (UIImageView *)[self.view viewWithTag:1];
	
	return imageView.image;
}

這時候外部的 Class 也可以取得這個 image 的資訊了
另外 property 有 readonly 的參數
這時候就只要覆寫 Getter 就好了

當我知道原來 property 可以這樣子做之後我的程式的寫法就比較活了
因為可以用一行字取代兩個 Method 的宣告
而且同時能做到原來 property 的動作
可以說是一間樹德一兼數得阿

最後,下次的教學是如何使用 CGPath 來圍出一個觸碰的區域。

2013年4月23日 星期二

使用 UIBezierPath 製作圖片

之上一篇 " 解決經常使用相同的圖片所造成記憶體使用量增加的問題 " 其實有另外一個用法
就是搭配 UIBezierPath 來繪製圖片
所以這邊就教簡單的 UIBezierPath 繪製多邊形的方法
首先 UIBezierPath 可以使用在兩種情況下
一個是寫在 - (void)drawRect:(CGRect)rect Method 裡面
但是這個 Method 只會在繼承 UIView Class 中出現
在 UIViewController 中沒有這個 Method
所以變成要轉換成 UIImge 才能使用
接下來的教學會以用這顏色來區分這兩者的差異

深灰色為不會在 - (void)drawRect:(CGRect)rect Method 出現的 Code
橘色為只會在 - (void)drawRect:(CGRect)rect Method 出現的 Code

// 建立繪圖的畫布,其中的 Size 是畫布的大小
UIGraphicsBeginImageContext(self.view.bounds.size);
// 建立畫布的 Context
CGContextRef context = UIGraphicsGetCurrentContext();


// 建立繪圖的路徑
UIBezierPath *additionPolygon = [UIBezierPath bezierPath];
// 建立路徑的起始點
[additionPolygon moveToPoint:view.center]
// 建立一條線從起始點到指定的點;
[additionPolygon addLineToPoint:CGPointMake(x, y)];
// 再畫另一條線
[additionPolygon addLineToPoint:CGPointMake(width, y)];
// 封閉這個路徑
[additionPolygon closePath];

// 建立填滿這個路徑的顏色
CGContextSetFillColorWithColor(context, [[UIColor redColor] CGColor]);
[[UIColor redColor] setFill];
// 將顏色填滿這個路徑
[additionPolygon fill];

// 建立路徑邊線的顏色
CGContextSetStrokeColorWithColor(context, [[UIColor redColor] CGColor]);
[[UIColor redColor] setStroke];
// 設定邊線的粗細
[additionPolygon setLineWidth:10.0f];
// 將顏色填滿這個路徑的邊線
[additionPolygon stroke];


// 將這個路徑轉成 UIImage 的形態
UIImage *bezierImage = UIGraphicsGetImageFromCurrentImageContext();

// 結束這個畫布
UIGraphicsEndImageContext();

// 將畫出來的圖片放入 imageView
UIImageView *imageView = [UIImageView imageViewWithFrame:self.view.bounds];
[imageView setImage:bezierImage];

[self.view addSubview:imageView];



這樣子就可以靠程式碼畫一張簡單的圖片了
UIBezierPath 是一個萬能的繪圖路徑
它也有弧線、貝茲曲線、圓角矩形等路徑可以使用
另外我也推薦一個可以更快速繪圖的程式 PaintCode
它像是 Photoshop 一樣可以透過圖形介面進行繪畫
畫完後會自動轉成程式碼給你使用,只不過需要 NTD 2990
倒是有點貴就是了。

2013年4月16日 星期二

解決經常使用相同的圖片所造成記憶體使用量增加的問題

這次是一個 Category 的進階應用
在某些時候會需要經常重複使用同一張圖片
有可能會造成記憶體使用量的增加,造成不必要的記憶體消耗
這時候可以使用以下方法

先建立一個基於 UIImage 的 Catagory
在 h 檔中建立以下 Code
+ (id)aImage

之後在 m 檔建立以下 Code
其中 aImage 是可以由你自行決定名稱
static UIImage aImage = nil;

+ (id)aImage
{
	if (aImage == nil) {
		aImage = [[UIImage imageNamed:@"__imageName__"] retain];
	}
	
	return aImage;
}

這時候在需要使用這張圖的時候可以直接使用 [UIImage aImage]; 就可以調用這張圖片
而且用過後會一直保留在記憶體中,直到這個程式被終結掉為止,
這樣子就不用一直將相同的圖片重新載入記憶體而造成記憶體的消耗。