2012年12月1日 星期六

Core Animation的基本使用(五)

CABasicAnimation的測試


当你创建一个CABasicAnimation时,你需要通过-setFromValue-setToValue来指定一个开始和结束的值。当你增加基础动画到层中的时候,它开始运行。当用属性做动画完成时,例如用位置属性做动画,,层就会立刻返回到它的初始位置。


一個最基本的測試,在使用CABasicAnimation來做動畫,此處修改前一篇的例子來做實作

1.先加一個圖片進來,作為動畫的基礎。


2.在mainViewController.m加入程式碼,在這之前要先加一個layer2的的變數。

@synthesize layer2;

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
   
    layer = [CALayer layer];
    layer.bounds = CGRectMake(0, 0, 200, 200);
    layer.position =  ORGINAL_POSITION;   ///CGPointMake(500, 300);
    layer.backgroundColor = [UIColor redColor].CGColor;
    layer.borderColor = [UIColor blackColor].CGColor;
    layer.opacity = 1.0f;
    [self.view.layer addSublayer:layer];
   
    actionsSwitch.on = NO;
   
    UIImage *image = [UIImage imageNamed:@"TaiwanMap.jpg"];
    layer2 = [CALayer layer];
    layer2.contents = (id)image.CGImage;
    layer2.bounds = CGRectMake(0, 0, 200, 200);
    layer2.position = CGPointMake(500, 500);
    [self.view.layer addSublayer:layer2];
   
    UIGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(fadeIt)];
    [self.view addGestureRecognizer:recognizer];


}

- (void)fadeIt {
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
    animation.toValue = [NSNumber numberWithFloat:0.0];  //最後的透明度為0

    animation.fromValue = [NSNumber numberWithFloat:layer.opacity]; //從現在的透明度
    animation.duration = 5.0; //運作秒數
    layer2.opacity = 0.0;  // 動畫結束後,透明度為0
    [layer2 addAnimation:animation forKey:@"animateOpacity"];
}


3. 執行結果,當觸擊圖片,則圖片就會動態消失。



2012年11月30日 星期五

Core Animation的基本使用(四)

Class CALayer的附加新的API的方法

使用前一個專案來作修改

1. 先加上一個class檔案,來作為CALayer的Additions


2. 這時會有兩個檔案


3.在CALayerAdditions.h加上Additions所需要部分

#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>

@interface CALayer  (Additions)

- (void)adjustWidthBy:(CGFloat)value;

@end

4. 在CALayerAdditions.m加上Additions所需要的程式碼

#import "CALayerAdditions.h"

@implementation CALayer (Additions)

- (void)adjustWidthBy:(CGFloat)value {
    self.bounds = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, self.bounds.size.width + value, self.bounds.size.height);
}

@end

5. 在mainViewController.m加上所需要的程式碼

#import "CALayerAdditions.h"

- (IBAction)toggleBounds:(id)sender { // 縮放
    [CATransaction setDisableActions:actionsSwitch.on];
 
   // 呼叫Additions的Function
    [layer adjustWidthBy:layer.bounds.size.width == layer.bounds.size.height ? 100 : -100];

   
    /*  原來的寫法
    if (layer.bounds.size.width == layer.bounds.size.height)
        layer.bounds = CGRectMake(layer.bounds.origin.x, layer.bounds.origin.y, layer.bounds.size.width + 100, layer.bounds.size.height);
    else
        layer.bounds = CGRectMake(layer.bounds.origin.x, layer.bounds.origin.y, layer.bounds.size.width - 100, layer.bounds.size.height);
    */

}

@end

6. 執行結果

與前一個相同,只是使用了Additions的方式來實作。

2012年11月29日 星期四

Core Animation的基本使用(三)

實驗Layer基本的動畫效果,利用CATransaction 的setDisableActions來做動畫的開關。

以下是實作

1. 首先開啓一個專案


2. 在StoryBoard加入六個Button及一個Switch,來顯示動畫的效果


3. 先加入 QuartzCore Framework



4. 在mainViewController.h註冊一個Layer,另外還有Switch作為開關

#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>

@interface mainViewController : UIViewController

@property (weak)   CALayer *layer;
@property (weak, nonatomic) IBOutlet UISwitch *actionsSwitch;

@end

5. 在mainViewController.m加上Layer的程式碼

#import "mainViewController.h"

@interface mainViewController ()

@end

#define ORGINAL_POSITION CGPointMake(500, 300)
#define MOVED_POSITON CGPointMake(300, 500)


@implementation mainViewController

@synthesize layer, actionsSwitch;

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
   
    layer = [CALayer layer];
    layer.bounds = CGRectMake(0, 0, 200, 200);
    layer.position =  ORGINAL_POSITION;   ///CGPointMake(500, 300);
    layer.backgroundColor = [UIColor redColor].CGColor;
    layer.borderColor = [UIColor blackColor].CGColor;
    layer.opacity = 1.0f;
    [self.view.layer addSublayer:layer];
   
    actionsSwitch.on = NO;


}

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

- (IBAction)toggleCorner:(id)sender {
    [CATransaction setDisableActions:actionsSwitch.on];
    layer.cornerRadius = (layer.cornerRadius == 0.0f) ? 30.0f : 0.0f;
}
- (IBAction)toggleColor:(id)sender {
    [CATransaction setDisableActions:actionsSwitch.on];
    CGColorRef redColor = [UIColor redColor].CGColor, blueColor = [UIColor blueColor].CGColor;
    layer.backgroundColor = (layer.backgroundColor == redColor) ? blueColor : redColor;
}
- (IBAction)toggleOpacity:(id)sender {
    [CATransaction setDisableActions:actionsSwitch.on];
    layer.opacity = (layer.opacity == 1.0f) ? 0.5f : 1.0f;
}
- (IBAction)togglePosition:(id)sender {
    [CATransaction setDisableActions:actionsSwitch.on];
    layer.position = layer.position.x == 500 ? MOVED_POSITON : ORGINAL_POSITION;
}
- (IBAction)toggleBorders:(id)sender {
    [CATransaction setDisableActions:actionsSwitch.on];
    layer.borderWidth = (layer.borderWidth == 0.0f) ? 10.0f : 0.0f;
}
- (IBAction)toggleBounds:(id)sender {
    [CATransaction setDisableActions:actionsSwitch.on];
   
    if (layer.bounds.size.width == layer.bounds.size.height)
        layer.bounds = CGRectMake(layer.bounds.origin.x, layer.bounds.origin.y, layer.bounds.size.width + 100, layer.bounds.size.height);
    else
        layer.bounds = CGRectMake(layer.bounds.origin.x, layer.bounds.origin.y, layer.bounds.size.width - 100, layer.bounds.size.height);
}

@end



6. 執行結果






 

2012年11月28日 星期三

Core Animation的基本使用(二)

Core Animation绘图的基础是“层”,叫做CALayer。你可以在View中设置层,层中可以放置更多的层。每个层都可以设定单独的动作,还可以给上 一级的层设置动作,下一级的层就可以跟着上一层进行动作。iPhone官方SDK同样支持CALayer,而在底层的Toolchain中,你需要用的类 叫做LKLayer(Layer Kit),其实是一样的。

1. CALayers 只是一個用來在螢幕上描繪可視內容的矩形之類別, 沒錯這也是 UIViews
      做的事. 但是這只是一個手法: 每一個 UIView 所畫的內容, 都包含了一個 root layer!
      你可以從以下的 code 來存取這個 layer(預設已建好的):
      CALayer *myLayer = myView.layer;

2. CALayer 類別的好處是: 它包含了一大堆可以設定的屬性讓你用來改變可見的外觀,
      例如:
      a. 圖層(layer) 的大小與位置.
      b. 圖層的背景顏色.
      c. 圖層的內容(圖像或用 Core Graphics 繪製的內容).
      d. 圖層的轉角是否使用圓形的.
      e. 為圖層設定陰影.
      f. 為圖層設定邊框.
      g. 其它等等.

官方資料
http://developer.apple.com/library/ios/#documentation/GraphicsImaging/Reference/CALayer_class/Introduction/Introduction.html#//apple_ref/occ/cl/CALayer

因此要針對CALayer來做一下實驗

1. 一個基本的Layer例子,但是上層的圖卻因為圖層的圓角而跑到外面。

    //先使用Layer對UIView,設一個背景
    self.view.layer.backgroundColor =[UIColor orangeColor].CGColor;
    self.view.layer.cornerRadius =20.0;  //四角會是圓形的
    self.view.layer.frame = CGRectInset(self.view.layer.frame, 20, 20);
   
    加上一層Layer來放置圖片
    CALayer *sublayer = [CALayer layer];
    sublayer.backgroundColor = [UIColor blueColor].CGColor;
    sublayer.shadowOffset = CGSizeMake(0, 10);
    sublayer.shadowRadius = 5.0;
    sublayer.shadowColor = [UIColor blackColor].CGColor;
    sublayer.shadowOpacity = 0.8;
    sublayer.frame = CGRectMake(30, 30, 500, 600);
   
    sublayer.contents =(id)[UIImage imageNamed:@"gsy.jpg"].CGImage;
    sublayer.borderColor =[UIColor blackColor].CGColor;
    sublayer.borderWidth =2.0;
   
    sublayer.cornerRadius =20.0; // 圖檔會超過邊界框架
   
    [self.view.layer addSublayer:sublayer];
 
    

2.改良上面的例子,使上層的圖可以塞進圖層內,不會跑出圓角外

    self.view.layer.backgroundColor =[UIColor orangeColor].CGColor;
    self.view.layer.cornerRadius =20.0;  //四角會是圓形的
    self.view.layer.frame = CGRectInset(self.view.layer.frame, 20, 20);

    CALayer *sublayer =[CALayer layer]; //專門顯示外框的Layer
    sublayer.backgroundColor =[UIColor blueColor].CGColor;
    sublayer.shadowOffset = CGSizeMake(0, 20);
    sublayer.shadowRadius =5.0;
    sublayer.shadowColor =[UIColor blackColor].CGColor;
    sublayer.shadowOpacity =0.8;
    sublayer.frame = CGRectMake(30, 30, 500, 600);
    sublayer.borderColor =[UIColor blackColor].CGColor;
    sublayer.borderWidth =2.0;
    sublayer.cornerRadius =20.0;
    [self.view.layer addSublayer:sublayer];
   
    CALayer *imageLayer =[CALayer layer]; //專門放置圖片用的Layer
    imageLayer.frame = sublayer.bounds;
    imageLayer.cornerRadius =20.0;
    imageLayer.contents =(id)[UIImage imageNamed:@"gsy.jpg"].CGImage;
    imageLayer.masksToBounds =YES;
    [sublayer addSublayer:imageLayer];

3. 另一個解決方法,先使用方法一的程式碼,最後一行加上sublayer.masksToBounds =YES;,就可以顯示圓腳效果,但是會失去陰影效果。

    //先使用Layer對UIView,設一個背景
    self.view.layer.backgroundColor =[UIColor orangeColor].CGColor;
    self.view.layer.cornerRadius =20.0;  //四角會是圓形的
    self.view.layer.frame = CGRectInset(self.view.layer.frame, 20, 20);
   
    加上一層Layer來放置圖片
    CALayer *sublayer = [CALayer layer];
    sublayer.backgroundColor = [UIColor blueColor].CGColor;
    sublayer.shadowOffset = CGSizeMake(0, 10);
    sublayer.shadowRadius = 5.0;
    sublayer.shadowColor = [UIColor blackColor].CGColor;
    sublayer.shadowOpacity = 0.8;
    sublayer.frame = CGRectMake(30, 30, 500, 600);
   
    sublayer.contents =(id)[UIImage imageNamed:@"gsy.jpg"].CGImage;
    sublayer.borderColor =[UIColor blackColor].CGColor;
    sublayer.borderWidth =2.0;
   
    sublayer.cornerRadius =20.0; 
    sublayer.masksToBounds =YES;    


    [self.view.layer addSublayer:sublayer];


masksToBounds 的用途
layer的masksToBounds属性决定了sublayer是否被父layer所裁剪,
masksToBounds的默认值是NO,防止sublayer被父layer裁剪。

如图举例:
 

2012年11月27日 星期二

CGRect的運算

在使用CGRect時,我們有時需要瞭解Rect的狀態,或是由目前的Rect來計算出下一個Rect的大小位置等等,Apple提供了基本的運算API

 官方資料
https://developer.apple.com/library/mac/#documentation/graphicsimaging/reference/CGGeometry/Reference/reference.html


1、创建一个几何原始数值
       CGPoint  CGPointMakeCGPoint A,CGPoint B            
             返回一个指定坐标点  
        CGRect   CGRectMakeCGFloat x,CGFloat y,CGFloat width,CGFloat height
 根据指定的坐标和大小创建一个矩形
 CGSize   CGSizeMakeCGFloat width,CGFloat height
 根据指定长宽创建一个CGSize   
2、修改矩形
CGRectDivide
            CGRect  CGRectInsetCGRect rect,CGFloat dx,CGFloat dy
            返回一个比原矩形大或小的矩形,但是中心点是相同的
CGRect CGRectIntegralCGRect A
 将矩形A的值转变成整数,得到一个最小的矩形,
CGRect CGRectIntersection:CGRect A,CGRect B
     获取两个矩形相交处所的矩形,没有相交返回NULL,用CGRectIsNull来检测
CGRectOffset
CGRectStandardize
CGRectUnion
3、比较数值
bool  CGPointEqualToPointCGPoint A,CGPoint B     
     返回两个点是否相等
bool  CGSizeEqualToSizeCGSize A,CGSize B
 CGSizeAB是否相等
bool  CGRectEqualToRectCGRect A,CGRect B       
     矩形AB的位置大小是否相等
bool  CGRectIntersectsRectCGRect A,CGRect B
     矩形AB是否相交,可用来判断精灵是否离开了屏幕
4、检查
       bool  CGRectContainsPointCGRect A, CGPoint B      
            检测矩形A是否包含指定的点B
bool  CGRectContainsRectCGRect A,CGRect B  
     检测矩形A是否包含矩形B
5、获取最大值、中等职和最小值
        CGFloat   CGRectGetMinXCGRect A) 
获取矩形x坐标的最小值
 CGFloat   CGRectGetMinYCGRect A)
 获取矩形y坐标的最小值 
CGFloat   CGRectGetMidXCGRect A) 
 获取矩形x坐标的中间值 
CGFloat   CGRectGetMidYCGRect A) 
 获取矩形y坐标的中间值 
CGFloat   CGRectGetMaxXCGRect A) 
 获取矩形x坐标的最大值 
CGFloat   CGRectGetMaxYCGRect A)
 获取矩形y坐标的最大值  
6、获取高和宽
CGFloat  CGRectGetHeightCGRect A)               
       获取矩形A的高
CGFloat  CGRectGetWidthCGRect A)            
       获取矩形A的宽
7、检测矩形是否存在或是无穷大
bool  CGRectIsEmptyCGRect A)
      矩形A是否长和宽都是0,或者是个NULL
bool  CGRectIsNullCGRect A)
   矩形A是否为NULL
bool  CGRectIsInfiniteCGRect A)
             矩形A是否无穷大,没有边界
 

一個測試的範例

    CGRect rect1 = CGRectMake(0, 0, 1024,768);
   
    CGRect rect3 = CGRectMake(500, 500, 900,768);
   
    CGRect rect4 = CGRectIntersection(rect1, rect3);
   
    Image1= [[UIImageView alloc]initWithFrame:rect4];
   
    CGRect rect2 = CGRectInset(rect1, 200.0f, 50.0f);
    Image2= [[UIImageView alloc]initWithFrame:rect2];
   
    [Image1 setImage:[UIImage imageNamed:@"mount1.jpg"]];
    [Image2 setImage:[UIImage imageNamed:@"mount2.jpg"]];
   
    [self.view  addSubview:Image1];
    [self.view  addSubview:Image2];
   
    [self.view sendSubviewToBack:Image1];
    [self.view sendSubviewToBack:Image2];







2012年11月26日 星期一

UIView的Animation(十二)

使用UIView的Animation來實做一個下雪的動畫

1. 開啓一個專案

2. 加入一個雪花的圖片,需要一個背景為透明的雪花圖

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

#define snowSize  25

@interface mainViewController ()
{
    UIImage* flakeImage;
}

@end

@implementation mainViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
   
    self.view.backgroundColor = [UIColor colorWithRed:0.5 green:0.5 blue:1.0 alpha:1.0];
   
    // load our flake image we will use the same image over and over
    flakeImage = [UIImage imageNamed:@"flake.png"];
   
    // start a timet that will fire 20 times per second
    [NSTimer scheduledTimerWithTimeInterval:(0.05) target:self selector:@selector(onTimer) userInfo:nil repeats:YES];


}


// Timer event is called whenever the timer fires
- (void)onTimer
{
    // build a view from our flake image
    UIImageView* flakeImageView = [[UIImageView alloc] initWithImage:flakeImage];
   
    // use the random() function to randomize up our flake attributes
    int startX = round(random() % 734);
    int endX = round(random() % 734);
    double scale = 1 / round(random() % 100) + 1.0;
    double speed = 1 / round(random() % 100) + 1.0;
   
    // set the flake start position
    flakeImageView.frame = CGRectMake(startX, -100.0, snowSize * scale, snowSize * scale);
    flakeImageView.alpha = 0.25;
   
    // put the flake in our main view
    [self.view addSubview:flakeImageView];
   
    [UIView beginAnimations:nil context:(void *)flakeImageView]; //針對雪花的動畫
   
    // set up how fast the flake will fall
    [UIView setAnimationDuration:10 * speed];
   
    // set the postion where flake will move to
    flakeImageView.frame = CGRectMake(endX, 880, snowSize * scale, snowSize * scale);
   
    // set a stop callback so we can cleanup the flake when it reaches the
    // end of its animation
    [UIView setAnimationDidStopSelector:@selector(onAnimationComplete:finished:context:)];
    [UIView setAnimationDelegate:self];
    [UIView commitAnimations];
   
}
- (void)onAnimationComplete:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
   
    UIImageView *flakeImageView = (__bridge UIImageView *)(context);
    [flakeImageView removeFromSuperview];   
    // open the debug log and you will see that all flakes have a retain count
    // of 1 at this point so we know the release below will keep our memory
    // usage in check
    //NSLog([NSString stringWithFormat:@"[flakeView retainCount] = %d", [flakeImageView i ]]);
   
    //NSLog([NSString stringWithFormat:@"[flakeView retainCount] = %d", [flakeImageView re]]);
   
    //[flakeImageView release];
    flakeImageView = nil;
   
}



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

@end
 
4.顯示結果

2012年11月25日 星期日

iOS上的目錄(五)

實作一個範例,利用 NSFileManager 查看本地所有文件。
本範例使用NavigationController 及TableViewController來做UIView的切換


1. 開啓新的專案採用 empty Template


2. 因為是空的Template,因此需要手動加入兩個TableViewController的檔案及storyboard





3. 在storyboard上加入兩個TableViewController,並分別設定Class及ID。



4. 從mainAppDelegate.h開始加入程式碼
#import <UIKit/UIKit.h>

#import "mainViewController.h"

@interface mainAppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;



@property (strong, nonatomic) mainViewController *rootView;  // 這兩個ViewController,一起動就要顯
@property (strong, nonatomic) UINavigationController *navController;


@end

5. 在mainAppDelegate.m加入起動程式碼,紅色部分要注意設定。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.window.backgroundColor = [UIColor whiteColor];
   
    UIStoryboard*  sb = [UIStoryboard storyboardWithName:@"ipadApp"  bundle:nil];
    self.rootView = [sb instantiateViewControllerWithIdentifier:@"mainView"];
   
    //self.rootView= [self.storyboard instantiateViewControllerWithIdentifier:@"IDENTIFIER"];
   
    self.navController = [[UINavigationController alloc] initWithRootViewController: self.rootView];
    self.rootView.fm = [NSFileManager defaultManager];
    self.rootView.title = @"/";
       
    self.rootView.isPoped = NO;
    self.window.rootViewController = self.navController;


     
    [self.window makeKeyAndVisible];
   
   
    return YES;
}


6. mainViewController.h,設定目錄控制變數
#import <UIKit/UIKit.h>

#import "FileViewController.h"
@interface mainViewController : UITableViewController

@property (strong, nonatomic) NSFileManager *fm;
@property (strong, nonatomic) NSString *previousPath;
@property BOOL isPoped;

@end

7. mainViewController.m 顯示目錄資料的程式碼
#import "mainViewController.h"

@interface mainViewController ()
{
    NSString *creationDate;
    NSString *modificationDate;
    NSArray *contentsDirectory;
}
@end


@implementation mainViewController

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
   
    NSString *currentPath = [self.fm currentDirectoryPath];
      
    NSDictionary *currentDitionary = [self.fm attributesOfItemAtPath: currentPath error: nil];
    creationDate = [[currentDitionary valueForKey: NSFileCreationDate] description];
    modificationDate = [[currentDitionary valueForKey: NSFileModificationDate] description];
    contentsDirectory = [self.fm contentsOfDirectoryAtPath: currentPath error: nil];

}

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

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear: animated];
   
    if (self.isPoped)
    {
        [self.fm changeCurrentDirectoryPath: self.previousPath];
        self.isPoped = NO;
    }

}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 3;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (section == 0 || section == 1)
    {
        return 1;
    }
    else
    {
        return [contentsDirectory count];
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *ContentsCellIdentifier = @"ContentsCell";
    static NSString *DateCellIdentifier = @"DateCell";
    UITableViewCell *contentsCell = [tableView dequeueReusableCellWithIdentifier:ContentsCellIdentifier];
    UITableViewCell *dateCell = [tableView dequeueReusableCellWithIdentifier: DateCellIdentifier];
    if (contentsCell == nil)
    {
        contentsCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ContentsCellIdentifier];
    }
    if (dateCell == nil)
    {
        dateCell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: DateCellIdentifier];
    }
   
    int section = [indexPath section];
    int row = [indexPath row];
   
    if (section == 0)
    {
        dateCell.textLabel.text = creationDate;
        return dateCell;
    }
    else if (section == 1)
    {
        dateCell.textLabel.text = modificationDate;
        return dateCell;
    }
    else
    {
        contentsCell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
        contentsCell.textLabel.text = [contentsDirectory objectAtIndex: row];
        return contentsCell;
    }
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    if (section == 0)
    {
        return @"Creation Date";
    }
    else if (section == 1)
    {
        return @"Modification Date";
    }
    else
    {
        return @"Contents";
    }
}

#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([indexPath section] != 0 && [indexPath section] != 1)
    {
        // Check whether it is a directory or a folder
        NSString *selectedPath = [contentsDirectory objectAtIndex: [indexPath row]];
        NSString *prePath = [self.fm currentDirectoryPath];
        BOOL flag = [self.fm changeCurrentDirectoryPath: selectedPath];
       
        // It is a directory
        if (flag)
        {
            //mainViewController *rootView = [[mainViewController alloc] initWithNibName: @"RootViewController" bundle: nil];
           
            UIStoryboard*  sb = [UIStoryboard storyboardWithName:@"ipadApp"  bundle:nil];
            mainViewController *rootView = [sb instantiateViewControllerWithIdentifier:@"mainView"];
           
            rootView.fm = self.fm;
            rootView.title = selectedPath;
           
            self.previousPath = prePath;
            self.isPoped = YES;
            [self.navigationController pushViewController: rootView animated: YES];
        }
        // It is a file
        else
        {
            //FileViewController *fileViewController = [[FileViewController alloc] initWithNibName: @"FileViewController" bundle: nil];
           
            UIStoryboard*  sb = [UIStoryboard storyboardWithName:@"ipadApp"  bundle:nil];
            FileViewController *fileView = [sb instantiateViewControllerWithIdentifier:@"fileView"];
           
            NSString *path = selectedPath;
            NSDictionary *file = [self.fm attributesOfItemAtPath: path error: nil];
           
            fileView.creationDate = [[file valueForKey: NSFileCreationDate] description];
            fileView.modificationDate = [[file valueForKey: NSFileModificationDate] description];
            fileView.fileSize = [NSString stringWithFormat: @"%@", [file valueForKey: NSFileSize]];
            fileView.title = selectedPath;
           
            [self.navigationController pushViewController:fileView animated: YES];
        }
    }
   
    [tableView deselectRowAtIndexPath: indexPath animated: YES];
}


@end

8. FileViewController.h顯示檔案的資料變數
#import <UIKit/UIKit.h>

@interface FileViewController : UITableViewController

@property (retain, nonatomic) NSString *creationDate;
@property (retain, nonatomic) NSString *modificationDate;
@property (retain, nonatomic) NSString *fileSize;

@end

9. FileViewController.h顯示檔案的資料程式碼
#import "FileViewController.h"

@implementation FileViewController

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
    }
    return self;
}

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

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

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 3;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 1;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }
   
    int section = [indexPath section];
   
    if (section == 0)
    {
        cell.textLabel.text = self.creationDate;
    }
    else if (section == 1)
    {
        cell.textLabel.text = self.modificationDate;
    }
    else
    {
        cell.textLabel.text = self.fileSize;
    }
   
    return cell;
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    if (section == 0)
    {
        return @"Creation Date";
    }
    else if (section == 1)
    {
        return @"Modification Date";
    }
    else
    {
        return @"Size";
    }
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath: indexPath animated: YES];
}


@end

9. 執行結果,因為使用模擬器,而模擬器的根目錄是掛在Mac上,因此所顯示的目錄為mac上的根目錄。依序點選下去,最後到一個檔案,然後顯示檔案的size大小。