2014年5月1日 星期四

從圖片檔案讀取 EXIF 資訊

這次是要如何從檔案中讀取一個 EXIF 資訊回來,
EXIF 是保存由相機拍攝下來的資料,
所以通常只要是相機拍的數位相片都有這項資訊,
但是要怎麼取出這些資訊了?
作法請看下面的教學

首先這個教學需要使用 ImageIO 的 framework,所以自己要實作的時候要記得將他 import 進來。

- (NSDictionary *)imagePropertiesWithPath:(NSString *)path
{
	// 將檔案的路徑轉成 NSURL 物件
	NSURL *imageFileURL = [NSURL fileURLWithPath:path];
	// 讀取這個檔案的資訊
	CGImageSourceRef imageSource = CGImageSourceCreateWithURL((CFURLRef)imageFileURL, NULL);
	
	/* 設定準備讀資料的選項,這裡是不要將檔案使用快取的方式,
		這是避免檔案過大,而消耗過多記憶體空間的問題。 */
	NSDictionary *options = @{(id)kCGImageSourceShouldCache: @(NO)};
	
	// 從檔案資訊中擷取關於圖片的資料
	CFDictionaryRef imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, (CFDictionaryRef)options);
	
	CFRelease(imageSource);
	
	return (NSDictionary *)imageProperties;
}

- (void)viewDidLoad
{
	~
	// 取得剛剛的圖片資訊
	NSDictionary *imageProperties = [self imagePropertiesWithPath:_filePath];
	
	// 再從中取出 EXIF 資訊
	NSDictionary *EXIFInformation = imageProperties[(id)kCGImagePropertyExifDictionary];
	
	// 取出 EXIF Auxiliary 資訊
	NSDictionary *EXIFAuxiliary   = imageProperties[(id)kCGImagePropertyExifAuxDictionary];
	
	~
}

這樣子就能取得 EXIF 資訊,另外還有 GPS 資訊也是可以在 imageProperties 中取得,
另外,這次的範例檔:https://github.com/Darktt/EXIF-Reader
範例檔的使用方法,建議使用模擬器,先執行過一次,在 Log 中能找到

**** Directory Path: 

這個資訊,這後面就是接著你要放數位照片的路徑,
請用 Finder 打開這個路徑,放入你要讀取的照片,
重新執行這個程式,這時候就會讀到這張照片的檔名了。

2014年1月5日 星期日

隱藏 UITableViewCell 的 Edit Control [For iOS 7]

根據之前的 隱藏 UITableViewCell 的 Edit Control 做到了隱藏的效果了,
不過這個作法在 iOS 7 上卻失效了,因為 iOS 7 的 Cell 的 Subview 結構改變了,
所以之前的教學就失效了,因此再度為 iOS 7 多開一次教學。

首先照上次的教學先做一次看看現在的 Cell 的 Subview 結構變成了什麼?

在 iOS 7 的時候 Cell 的 Subview 竟然只剩下 UITableViewCellScrollView 一個!
那個其他的 view 去哪了?

不管怎樣,先看看 UITableViewCellScrollView 裡面有什麼東西,
用跟上次一樣的作法,log 看看 UITableViewCellScrollView 有什麼 subviews
- (void)layoutSubviews
{
	[super layoutSubviews];
	
	if (self.editing) {
		UIView *subview = self.subviews.lastObject;
		
		if ([self.subviews count] == 1 && [NSStringFromClass([subview class]) isEqualToString:@"UITableViewCellScrollView"]) {
			NSLog(@"%@", subview.subviews);
		}
	}
	
}

結果如下,竟然! UITableViewCellScrollView 內部是包著那些消失的 View!

既然這樣子就照著之前的作法將它給隱藏起來。
- (void)layoutSubviews
{
	[super layoutSubviews];
	
	if (!self.editing) {
		return;
	}
	
	void (^enumBlock) (id, NSUInteger, BOOL *) = ^(UIView *subview, NSUInteger idx, BOOL *stop) {
		if ([NSStringFromClass([subview class]) isEqualToString:@"UITableViewCellEditControl"]) {
			[subview setHidden:YES];
	    
			*stop = YES;
		}
	};
	
	UIView *subview = self.subviews.lastObject;
	
	if ([self.subviews count] == 1 && [NSStringFromClass([subview class]) isEqualToString:@"UITableViewCellScrollView"]) {
		[subview.subviews NSEnumerationReverse
	}
}

如果你需要支援 iOS7 以下的版本的話就可以這樣子用。
- (void)layoutSubviews
{
	[super layoutSubviews];
	
	if (!self.editing) {
		return;
	}
	
	void (^enumBlock) (id, NSUInteger, BOOL *) = ^(UIView *subview, NSUInteger idx, BOOL *stop) {
		if ([NSStringFromClass([subview class]) isEqualToString:@"UITableViewCellEditControl"]) {
			[subview setHidden:YES];
	    
			*stop = YES;
		}
	};
	
	UIView *subview = self.subviews.lastObject;
	
	if ([self.subviews count] == 1 && [NSStringFromClass([subview class]) isEqualToString:@"UITableViewCellScrollView"]) {
		[subview.subviews enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:enumBlock];
		
		return;
	}
	
	[self.subviews enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:enumBlock];
}

2013年10月31日 星期四

視差效果 (Parallax effect)

注意:以下教學只支援 iOS7 以上的 SDK!!

iOS 7 的特點除了毛玻璃效果之外還有另一個,就是視差效果 (Parallax effect),
這個功能比起毛玻璃效果效果使用起來簡單許多了,因為官方供提供這個 Class 給你使用,
所以可以自由的加在你想要套用這個效果的 View 上面了,以下就是這個效果的教學。

首先在你的 UIViewController 裡面建立一個 UIView,這個 UIView 的大小可以隨你喜歡,只要將它 addsubView: 上去就好了,
假設這個 UIView 叫做 viewA 好了,以下教學就用它做範例:
- (void)viewDidLoad
{
	[super viewDidLoad];
	
	// 首先先建立一個 X 軸的可偏移範圍,本教學就用 +30 到 -30 之間
	UIInterpolatingMotionEffect *xAxis = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x" type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];
	[xAxis setMinimumRelativeValue:@(-30.0f)];
	[xAxis setMaximumRelativeValue:@(30.0f)];
	
	// 同樣,也建立一個 Y 軸的可偏移範圍,也是用 +30 到 -30 之間
	UIInterpolatingMotionEffect *yAxis = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.y" type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis];
	[yAxis setMinimumRelativeValue:@(-30.0f)];
	[yAxis setMaximumRelativeValue:@(30.0f)];
	
	// 建立一個群組將 X 軸與 Y 軸的可偏移範圍包起來
	UIMotionEffectGroup *motionEffect = [UIMotionEffectGroup new];
	[motionEffect setMotionEffects:@[xAxis, yAxis]];
	
	// 把 viewA 建立起來,並且加到 viewController 中
	UIView *viewA = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 200.0f, 200.0f)];
	[viewA setBackgroundColor:[UIColor whiteColor]];
	[viewA setCenter:self.view.center];
	
	[self.view addSubview:viewA];
	
	// 之後將這個視差效果加入到 viewA 中
	[viewA setMotionEffects:@[motionEffect]];
	
	// 用完後將它們釋放掉
	[xAxis release];
	[yAxis release];
	
	[motionEffect release];
	[viewA release];
}

這樣子執行就可以用了,只不過這在模擬器視沒有效果的,所以只能在實機上面使用,
所以這次就沒有畫面了。

本次的教學就到這邊,大家下次再見了。

2013年9月26日 星期四

增加毛玻璃特效到你的 UIView 中

注意:以下教學只支援 iOS7 以上的 SDK!!

這次 iOS7 的特點就是毛玻璃效果,不過只有特定的 View 可以使用,像是 navagation bar 與 tool bar 以及 alert view 等等。
但是可以透過作弊的方式將這個效果加到你要顯示的 View 裡面,下面就是教學。

首先先建立一個 toolbar 的全域變數
@interface DTBlurView ()
 {
  UIToolbar *_blurToolbar;
 }

 @end

之後在 initial 的時候將 toolbar 的 layer 加到自己身上
- (id)initWithFrame:(CGRect)frame
 {
  self = [super initWithFrame:frame];
  if (self) {
   [self setClipsToBounds:YES];
        
   _blurToolbar = [[UIToolbar alloc] initWithFrame:self.bounds];
        
   [self.layer insertSublayer:_blurToolbar.layer atIndex:0];
  }
  return self;
 }

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

這樣子就可以了,最後只要將它加到 ViewController 裡面就好了。
結果如下:


另外,本教學不能保證符合 Apple 的 iOS Human Interface Guidelines 的規定,
所以當你被退件的時候,請自行處理。