2012/3/27

CFRunLoop

CFRunLoop
還不知道幹麻
待研究

2012/3/20

GCD Test

GCD,grand-central-dispatch
GCD是作業系統處理多執行緒一種方式
我們可以想像成和一般的多執行緒一樣
至於iOS的作業系統如何實現他,就先不考慮他
參考文章 http://jackiexie.blogspot.com/2010/09/grand-central-dispatch.html 

iOS預設的多執行緒NSOperation,其實也是透實作GCD來實現,但我覺得直接使用block來寫,比寫NSOperation還要簡單...  XD

以下為簡單範例

NSLog(@"ready");
 
 dispatch_async(dispatch_get_global_queue(0, 0), ^{
  NSLog(@"GCD on global Queue");
  NSLog(@"start sleep....");
  for(int i=0;i<5;i++)
  {
   NSLog(@"sleep.....%u",i);
   sleep(1);
  }
  NSLog(@"complete");
  dispatch_async(dispatch_get_main_queue(),^{
   NSLog(@"CGD on Main Queue");
  });
 });

 
 NSLog(@"weak up");
  [super viewDidLoad];
而執行結果為:
2012-03-20 17:41:18.181 GCDTest[12292:207] ready
2012-03-20 17:41:18.182 GCDTest[12292:207] weak up
2012-03-20 17:41:18.183 GCDTest[12292:3603] GCD on global Queue
2012-03-20 17:41:18.184 GCDTest[12292:3603] start sleep....
2012-03-20 17:41:18.185 GCDTest[12292:3603] sleep.....0
2012-03-20 17:41:19.188 GCDTest[12292:3603] sleep.....1
2012-03-20 17:41:20.190 GCDTest[12292:3603] sleep.....2
2012-03-20 17:41:21.191 GCDTest[12292:3603] sleep.....3
2012-03-20 17:41:22.192 GCDTest[12292:3603] sleep.....4
2012-03-20 17:41:23.193 GCDTest[12292:3603] complete
2012-03-20 17:41:23.194 GCDTest[12292:207] CGD on Main Queue
非常有趣的GCD實驗 雖然還搞不清楚和multi thread的差異在那 不過有這個撰寫非同步程式,就簡單的多了

AvFundaction Capture Note




  1. AVCaptureInput:AVCaptrueDeviceInput
  2. 立AVCaptureOutput:AVCaptureStillImageOutputAVCaptureMovieFileOutput
  3. 建立session:AVCaptrueSessuon
  4. 連inputoutput與session
  5. AVCaptureVideoPreviewLayer與session
  6. 將AVCaptureVideoPreviewLayer的view的layer
  7. 透過[session startRunning],將預覽畫面顯示到previewLayer上



  1. connection是input、output與session之間的橋梁,先取得介於output與session之間的connection,並設定錄影水平方向
  2. 執行AVCaptureOutput的startRecordingToOutputFileURL:recordingDelegate:
  3. AVCaptureOutput 的isRecording會變成YES
三、影結束
  1. AVCaptureOutputinstance的AVCaptureOutput


其他附註
取得所有裝置
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];

過濾出所要的裝置
    
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
for (AVCaptureDevice *device in devices) {
    if ([device position] == position) {
    return device;
    }
}
return nil;






取得裝置清單
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
- (AVCaptureDevice *) cameraWithPosition:(AVCaptureDevicePosition) position
{
    NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
    for (AVCaptureDevice *device in devices) {
        if ([device position] == position) {
            return device;
        }
    }
    return nil;
}






Torch mode

Torch mode is where a camera uses the flash continuously at a low power to illuminate a video capture. There are three torch modes:
You use hasTorch to determine whether a device has a flash. You use the isTorchModeSupported: method to determine whether a device supports a given flash mode, then set the mode using the torchMode property.
For devices with a torch, the torch only turns on if the device is associated with a running capture session.


取得音源裝置
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio];


UIGestureRecognizer 手勢與觸控動作


如果我們的class並非繼承至UIRespondser、UIView、UIViewController,但又想直接幫view增加觸控等事件,可以用UITapGestureRecognizer,來加入事件監聽

為View增加一個tap監聽事件
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(onSingleTap:)];
singleTap.numberOfTapsRequired=2;
[self.view addGestureRecognizer:singleTap];


如果我們想寫一個手勢動作判斷

我們可以寫一個UIGestureRecognizer的子類,並實作UIGestureRecognizerDelegate來完成
@optional
//收到一個Touch的動作,通常是判斷手勢的第一個動作,會比view本身的touchesBegan:withEvent:還早發生,return NO表示不繼續識別
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;

//手勢動作開始
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;

//
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;

orientation 水平偵測

參考code如下
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; [notificationCenter addObserver:self selector:@selector(deviceOrientationDidChange) name:UIDeviceOrientationDidChangeNotification object:nil]; - (void)deviceOrientationDidChange { NSLog(@"deviceOrientationDidChange"); NSLog(@"orientation:%i",[UIDevice currentDevice].orientation); }
在 PHP 裡如果要傳遞參考 (call by address) 的話,有 2 種做法:
1. 呼叫函數時在變數前加上 &,例如:
add(&$x, $y);
此時 add() 的寫法沒有什麼不同:
function add($x, $y) { $x += $y; }
2. 在函數的參數加上 &,例如:
function add(&$x, $y) { $x += $y; }
呼叫時的寫法:
add($x, $y);
這裡有 3 個範例,注意每個範例最後輸出的 $x 與 $y 值:
1.
function add($x, $y) { $x += $y; } $x = 1; $y = 2; add($x, $y); echo "x = " . $x . " " . "y = " . $y;
輸出:
x = 1 y = 2
2.
function add($x, $y) { $x += $y; } $x = 1; $y = 2; add(&$x, $y); echo "x = " . $x . " " . "y = " . $y;
輸出:
x = 3 y = 2
3.
function add(&$x, $y) { $x += $y; } $x = 1; $y = 2; add($x, $y); echo "x = " . $x . " " . "y = " . $y;
輸出:
x = 3 y = 2
那麼,可不可以函數與呼叫函數時都加 & 呢?在 PHP 裡是可以的,並不會出錯,例如:
function add(&$x, $y) { $x += $y; } $x = 1; $y = 2; add(&$x, $y); echo "x = " . $x . " " . "y = " . $y; ?>
最後的結果一樣是:
x = 3 y = 2
--jollen

2012/3/8

三角函數必備,角度轉孤度、孤度轉角度

/** Degrees to Radian **/
#define DEGREES_TO_RADIANS( degrees ) ( ( degrees ) / 180.0 * M_PI )

/** Radians to Degrees **/
#define RADIANS_TO_DEGREES( radians ) ( ( radians ) * ( 180.0 / M_PI ) )

2012/3/6

objectiveC 上的urlEncode

NSString *outStr=CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)inStr, nil,  (CFStringRef)@":/?#[]@!$ &'()*+,;=\"<>%{}|\\^~`", kCFStringEncodingUTF8);

iOS的GPS,

取得座標
locationMgr = [[CLLocationManager alloc] init];

locationMgr.delegate = self;
locationMgr.desiredAccuracy=kCLLocationAccuracyBest;
locationMgr.distanceFilter=0;

並於delegate實作
- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation

-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error

透過google的geo將地址轉為address
http://maps.google.com/maps/geo?q=地址&output=格式&key=金鑰

地址:如台北市民生東路XX段XX號
格式:xml or csv
金鑰:google api金鑰

有趣的實驗respondsToSelector

原本想確認AppDelegate起動時,以下兩個method有什麼不同
application:didFinishLaunchingWithOptions:
applicationDidFinishLaunching:


透過覆寫UIResponder的respondsToSelector
意外發現了,app的起動方式,
那一天有特別需要時,就可以覆寫這些方法


2012-03-06 17:18:43.048 BlockTest[2766:207] [AppDelegate]application:handleOpenURL:
2012-03-06 17:18:43.052 BlockTest[2766:207] [AppDelegate]application:openURL:sourceApplication:annotation:
2012-03-06 17:18:43.052 BlockTest[2766:207] [AppDelegate]applicationDidReceiveMemoryWarning:
2012-03-06 17:18:43.053 BlockTest[2766:207] [AppDelegate]applicationWillTerminate:
2012-03-06 17:18:43.053 BlockTest[2766:207] [AppDelegate]applicationSignificantTimeChange:
2012-03-06 17:18:43.054 BlockTest[2766:207] [AppDelegate]application:willChangeStatusBarOrientation:duration:
2012-03-06 17:18:43.054 BlockTest[2766:207] [AppDelegate]application:didChangeStatusBarOrientation:
2012-03-06 17:18:43.055 BlockTest[2766:207] [AppDelegate]application:willChangeStatusBarFrame:
2012-03-06 17:18:43.055 BlockTest[2766:207] [AppDelegate]application:didChangeStatusBarFrame:
2012-03-06 17:18:43.056 BlockTest[2766:207] [AppDelegate]application:deviceAccelerated:
2012-03-06 17:18:43.057 BlockTest[2766:207] [AppDelegate]application:deviceChangedOrientation:
2012-03-06 17:18:43.057 BlockTest[2766:207] [AppDelegate]applicationDidBecomeActive:
2012-03-06 17:18:43.103 BlockTest[2766:207] [AppDelegate]applicationWillResignActive:
2012-03-06 17:18:43.104 BlockTest[2766:207] [AppDelegate]applicationDidEnterBackground:
2012-03-06 17:18:43.104 BlockTest[2766:207] [AppDelegate]applicationWillEnterForeground:
2012-03-06 17:18:43.105 BlockTest[2766:207] [AppDelegate]applicationWillSuspend:
2012-03-06 17:18:43.106 BlockTest[2766:207] [AppDelegate]application:didResumeWithOptions:
2012-03-06 17:18:43.764 BlockTest[2766:207] [UIApplication]accessibilityInitialize
2012-03-06 17:18:43.772 BlockTest[2766:207] [UIStatusBar]actionForLayer:forKey:
2012-03-06 17:18:43.773 BlockTest[2766:207] [UIStatusBar]displayLayer:
2012-03-06 17:18:43.773 BlockTest[2766:207] [UIStatusBar]drawLayer:inContext:
2012-03-06 17:18:43.774 BlockTest[2766:207] [UIStatusBar]layoutSublayersOfLayer:
2012-03-06 17:18:43.775 BlockTest[2766:207] [UIStatusBar]_layoutSublayersOfLayer:
2012-03-06 17:18:43.775 BlockTest[2766:207] [UIStatusBar]animationDidStart:
2012-03-06 17:18:43.776 BlockTest[2766:207] [UIStatusBar]animationDidStop:finished:
2012-03-06 17:18:43.777 BlockTest[2766:207] [UIStatusBarWindow]actionForLayer:forKey:
2012-03-06 17:18:43.778 BlockTest[2766:207] [UIStatusBarWindow]displayLayer:
2012-03-06 17:18:43.779 BlockTest[2766:207] [UIStatusBarWindow]drawLayer:inContext:
2012-03-06 17:18:43.779 BlockTest[2766:207] [UIStatusBarWindow]layoutSublayersOfLayer:
2012-03-06 17:18:43.780 BlockTest[2766:207] [UIStatusBarWindow]_layoutSublayersOfLayer:
2012-03-06 17:18:43.780 BlockTest[2766:207] [UIStatusBarWindow]animationDidStart:
2012-03-06 17:18:43.781 BlockTest[2766:207] [UIStatusBarWindow]animationDidStop:finished:
2012-03-06 17:18:43.783 BlockTest[2766:207] [UIStatusBarCorners]actionForLayer:forKey:
2012-03-06 17:18:43.784 BlockTest[2766:207] [UIStatusBarCorners]displayLayer:
2012-03-06 17:18:43.785 BlockTest[2766:207] [UIStatusBarCorners]drawLayer:inContext:
2012-03-06 17:18:43.786 BlockTest[2766:207] [UIStatusBarCorners]layoutSublayersOfLayer:
2012-03-06 17:18:43.787 BlockTest[2766:207] [UIStatusBarCorners]_layoutSublayersOfLayer:
2012-03-06 17:18:43.787 BlockTest[2766:207] [UIStatusBarCorners]animationDidStart:
2012-03-06 17:18:43.788 BlockTest[2766:207] [UIStatusBarCorners]animationDidStop:finished:
2012-03-06 17:18:43.789 BlockTest[2766:207] [UIImageView]actionForLayer:forKey:
2012-03-06 17:18:43.790 BlockTest[2766:207] [UIImageView]displayLayer:
2012-03-06 17:18:43.790 BlockTest[2766:207] [UIImageView]drawLayer:inContext:
2012-03-06 17:18:43.791 BlockTest[2766:207] [UIImageView]layoutSublayersOfLayer:
2012-03-06 17:18:43.792 BlockTest[2766:207] [UIImageView]_layoutSublayersOfLayer:
2012-03-06 17:18:43.792 BlockTest[2766:207] [UIImageView]animationDidStart:
2012-03-06 17:18:43.793 BlockTest[2766:207] [UIImageView]animationDidStop:finished:
2012-03-06 17:18:43.794 BlockTest[2766:207] [UIStatusBarBackgroundView]actionForLayer:forKey:
2012-03-06 17:18:43.795 BlockTest[2766:207] [UIStatusBarBackgroundView]displayLayer:
2012-03-06 17:18:43.796 BlockTest[2766:207] [UIStatusBarBackgroundView]drawLayer:inContext:
2012-03-06 17:18:43.796 BlockTest[2766:207] [UIStatusBarBackgroundView]layoutSublayersOfLayer:
2012-03-06 17:18:43.797 BlockTest[2766:207] [UIStatusBarBackgroundView]_layoutSublayersOfLayer:
2012-03-06 17:18:43.797 BlockTest[2766:207] [UIStatusBarBackgroundView]animationDidStart:
2012-03-06 17:18:43.798 BlockTest[2766:207] [UIStatusBarBackgroundView]animationDidStop:finished:
2012-03-06 17:18:43.800 BlockTest[2766:207] [UIStatusBarForegroundView]actionForLayer:forKey:
2012-03-06 17:18:43.801 BlockTest[2766:207] [UIStatusBarForegroundView]displayLayer:
2012-03-06 17:18:43.802 BlockTest[2766:207] [UIStatusBarForegroundView]drawLayer:inContext:
2012-03-06 17:18:43.803 BlockTest[2766:207] [UIStatusBarForegroundView]layoutSublayersOfLayer:
2012-03-06 17:18:43.804 BlockTest[2766:207] [UIStatusBarForegroundView]_layoutSublayersOfLayer:
2012-03-06 17:18:43.805 BlockTest[2766:207] [UIStatusBarForegroundView]animationDidStart:
2012-03-06 17:18:43.805 BlockTest[2766:207] [UIStatusBarForegroundView]animationDidStop:finished:
2012-03-06 17:18:43.806 BlockTest[2766:207] [UIStatusBarServiceItemView]actionForLayer:forKey:
2012-03-06 17:18:43.807 BlockTest[2766:207] [UIStatusBarServiceItemView]displayLayer:
2012-03-06 17:18:43.807 BlockTest[2766:207] [UIStatusBarServiceItemView]drawLayer:inContext:
2012-03-06 17:18:43.808 BlockTest[2766:207] [UIStatusBarServiceItemView]layoutSublayersOfLayer:
2012-03-06 17:18:43.808 BlockTest[2766:207] [UIStatusBarServiceItemView]_layoutSublayersOfLayer:
2012-03-06 17:18:43.809 BlockTest[2766:207] [UIStatusBarServiceItemView]animationDidStart:
2012-03-06 17:18:43.809 BlockTest[2766:207] [UIStatusBarServiceItemView]animationDidStop:finished:
2012-03-06 17:18:43.819 BlockTest[2766:207] [UIStatusBarDataNetworkItemView]actionForLayer:forKey:
2012-03-06 17:18:43.819 BlockTest[2766:207] [UIStatusBarDataNetworkItemView]displayLayer:
2012-03-06 17:18:43.820 BlockTest[2766:207] [UIStatusBarDataNetworkItemView]drawLayer:inContext:
2012-03-06 17:18:43.820 BlockTest[2766:207] [UIStatusBarDataNetworkItemView]layoutSublayersOfLayer:
2012-03-06 17:18:43.821 BlockTest[2766:207] [UIStatusBarDataNetworkItemView]_layoutSublayersOfLayer:
2012-03-06 17:18:43.821 BlockTest[2766:207] [UIStatusBarDataNetworkItemView]animationDidStart:
2012-03-06 17:18:43.834 BlockTest[2766:207] [UIStatusBarDataNetworkItemView]animationDidStop:finished:
2012-03-06 17:18:43.835 BlockTest[2766:207] [UIStatusBarBatteryItemView]actionForLayer:forKey:
2012-03-06 17:18:43.836 BlockTest[2766:207] [UIStatusBarBatteryItemView]displayLayer:
2012-03-06 17:18:43.836 BlockTest[2766:207] [UIStatusBarBatteryItemView]drawLayer:inContext:
2012-03-06 17:18:43.837 BlockTest[2766:207] [UIStatusBarBatteryItemView]layoutSublayersOfLayer:
2012-03-06 17:18:43.838 BlockTest[2766:207] [UIStatusBarBatteryItemView]_layoutSublayersOfLayer:
2012-03-06 17:18:43.851 BlockTest[2766:207] [UIStatusBarBatteryItemView]animationDidStart:
2012-03-06 17:18:43.853 BlockTest[2766:207] [UIStatusBarBatteryItemView]animationDidStop:finished:
2012-03-06 17:18:43.854 BlockTest[2766:207] [UIStatusBarTimeItemView]actionForLayer:forKey:
2012-03-06 17:18:43.855 BlockTest[2766:207] [UIStatusBarTimeItemView]displayLayer:
2012-03-06 17:18:43.856 BlockTest[2766:207] [UIStatusBarTimeItemView]drawLayer:inContext:
2012-03-06 17:18:43.857 BlockTest[2766:207] [UIStatusBarTimeItemView]layoutSublayersOfLayer:
2012-03-06 17:18:43.858 BlockTest[2766:207] [UIStatusBarTimeItemView]_layoutSublayersOfLayer:
2012-03-06 17:18:43.858 BlockTest[2766:207] [UIStatusBarTimeItemView]animationDidStart:
2012-03-06 17:18:43.859 BlockTest[2766:207] [UIStatusBarTimeItemView]animationDidStop:finished:
2012-03-06 17:18:43.863 BlockTest[2766:207] [AppDelegate]application:didFinishLaunchingWithOptions:
2012-03-06 17:18:43.863 BlockTest[2766:207] [AppDelegate]applicationDidFinishLaunching:
2012-03-06 17:18:43.864 BlockTest[2766:207] [AAA]
2012-03-06 17:18:43.865 BlockTest[2766:207] [UIWindow]actionForLayer:forKey:
2012-03-06 17:18:43.865 BlockTest[2766:207] [UIWindow]displayLayer:
2012-03-06 17:18:43.866 BlockTest[2766:207] [UIWindow]drawLayer:inContext:
2012-03-06 17:18:43.867 BlockTest[2766:207] [UIWindow]layoutSublayersOfLayer:
2012-03-06 17:18:43.867 BlockTest[2766:207] [UIWindow]_layoutSublayersOfLayer:
2012-03-06 17:18:43.867 BlockTest[2766:207] [UIWindow]animationDidStart:
2012-03-06 17:18:43.868 BlockTest[2766:207] [UIWindow]animationDidStop:finished:
2012-03-06 17:18:43.870 BlockTest[2766:207] [UIView]actionForLayer:forKey:
2012-03-06 17:18:43.871 BlockTest[2766:207] [UIView]displayLayer:
2012-03-06 17:18:43.872 BlockTest[2766:207] [UIView]drawLayer:inContext:
2012-03-06 17:18:43.872 BlockTest[2766:207] [UIView]layoutSublayersOfLayer:
2012-03-06 17:18:43.873 BlockTest[2766:207] [UIView]_layoutSublayersOfLayer:
2012-03-06 17:18:43.873 BlockTest[2766:207] [UIView]animationDidStart:
2012-03-06 17:18:43.874 BlockTest[2766:207] [UIView]animationDidStop:finished:
2012-03-06 17:18:43.875 BlockTest[2766:207] [ViewController]isInWillRotateCallback
2012-03-06 17:18:43.876 BlockTest[2766:207] [ViewController]rotatingContentViewForWindow:
2012-03-06 17:18:43.877 BlockTest[2766:207] [ViewController]shouldWindowUseOnePartInterfaceRotationAnimation:
2012-03-06 17:18:43.878 BlockTest[2766:207] [ViewController]viewControllerForRotation
2012-03-06 17:18:43.879 BlockTest[2766:207] [ViewController]window:shouldAutorotateToInterfaceOrientation:
2012-03-06 17:18:43.879 BlockTest[2766:207] [ViewController]_isViewControllerInWindowHierarchy
2012-03-06 17:18:43.880 BlockTest[2766:207] [ViewController]_isViewControllerInWindowHierarchy
2012-03-06 17:18:43.883 BlockTest[2766:207] [AppDelegate]accessibilityInitialize

2012/3/5

BLOCK 的運用

C++有BLOCK的功能
Objective C 在iOS4之後也支援了此功能
簡單來說
block類似Anonymous function


EX1
int (^square) (int);//block 指標(回傳型傳,無則用void) 
square = ^(int a ) {
return a*a ;
};
int result=square(5);
NSLog(@"num:%u",result);//25
EX2
int outA=3;
int (^square2) (int);
square2 = ^(int a ) {
return outA*a ;
};
result=square2(5);
NSLog(@"num:%u",result);//15
EX3
outA=3;
int (^square3) (int);
square3 = ^(int a ) {
return outA*a ;//outA is a copy
};
outA=7;
result=square3(5);
NSLog(@"num:%u",result);//15
EX4
NSMutableArray *arr=[NSMutableArray arrayWithObjects:
[NSNumber numberWithInt:1],
[NSNumber numberWithInt:3],
[NSNumber numberWithInt:5],
[NSNumber numberWithInt:7],nil];
NSLog(@"arr:%@",arr);//1,3,5,7
int (^square4) (int);
square4 = ^(int a) {
int v=[(NSNumber *)[arr objectAtIndex:[arr count]-1]intValue];//arr is Pointer
[arr removeLastObject];
return v*a;
};
outA=7;
result=square4(5);
NSLog(@"num:%u",result);//35
NSLog(@"arr:%@",arr);//1,3,5,nil
用法 __block 變數名稱;
通用使用block時,變數是以copy value的方式傳入
如果變數是一般的資料形態(int、bool、float…)
會以傳值的方式丟到block中運算


也就是在block 的過程鐘
變數的值改變了
外面的變數將不受影響 這時
如果在變數前加上_block
這可以讓變數在block中的改變
套用到外block的變數  
void (^myBlock)(int) = ^(int v) {
  v=v+1;
  NSLog(@"%i",v);
  v=v+1;
  NSLog(@"%i",v);
  v=v+1;
  NSLog(@"%i",v);
 };
 
 int a=3;
 NSLog(@"a:%i",a);
 myBlock(a);
 NSLog(@"%i",a);
 
 __block int b=4;
 NSLog(@"b:%i",b);
 myBlock(b);
 NSLog(@"%i",b);
執行結果
2012-03-20 15:04:45.911 BlockTest2[10412:207] a:3
2012-03-20 15:04:45.912 BlockTest2[10412:207] 4
2012-03-20 15:04:45.913 BlockTest2[10412:207] 5
2012-03-20 15:04:45.914 BlockTest2[10412:207] 6
2012-03-20 15:04:45.914 BlockTest2[10412:207] 3
2012-03-20 15:04:45.915 BlockTest2[10412:207] b:4
2012-03-20 15:04:45.915 BlockTest2[10412:207] 5
2012-03-20 15:04:45.916 BlockTest2[10412:207] 6
2012-03-20 15:04:45.917 BlockTest2[10412:207] 7
2012-03-20 15:04:45.917 BlockTest2[10412:207] 4

2012/3/1

iOS的動畫控製

iOS的動畫
如果要在iOS系統上做動化,有幾個方法可以來做
1、用CATranscation
2、用CATransition,幾個常用的CAAnimation就是透過這種方式
3、用UIView的




幾個常用的類別
  1. CALayer
  2. CATranscation
  3. CATransition:CAAnimation
CALayer,類似View,嚴格來講,view是由layer組成,簡單來說 ,CALayer是負責將畫面 show出來,另外,rootLayer是不能跑動畫的,
CATranscation,負責控制layer的移動,變型,...可透過CATranscation來寫自已要的動畫腳本

CAAnimation,子類別有CABasicAnimation、CATransition…等已經寫好的動畫,直接設定參數就可以使用
CATransition,繼承至CAAnimation,動畫效果,如淡入淡出


----------------------------------------------------------------------------------------------------
1、用CATranscation做動畫
用CATranscation實作動化,只能對第二層的layer作用,也就是view.layer是第一層,只能對這個layer底下的sublayer產生動畫效果,請注意

[CATransaction begin];
[CATransaction setValue:[NSNumber numberWithDouble:5.0] forKey:kCATransactionAnimationDuration];
// Position and rotate the listener
myLayer.position = touchPoint;
//_listenerLayer.transform = CATransform3DMakeRotation(playback.listenerRotation, 0., 0., 1.);
//m = CATransform3DMakeRotation(rot, 0., 0., 1.);
[CATransaction commit]; 

2、用CATransition做動畫

CATransition的主要type有四
kCATransitionMoveIn, 淡出,淡入+動畫
kCATransitionPush,淡出+移動,淡入+移動
kCATransitionReveal, 淡出+動畫,淡入
kCATransitionFade,淡入,淡出

subtype決定動畫的移動方向

kCATransitionFromLeft,
kCATransitionFromRight,
kCATransitionFromTop,
kCATransitionFromBottom

kCATransitionFade是不需要subtype的

ex
CATransition *transition = [CATransition animation];
transition.duration = 0.75;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
NSString *types[4] = {kCATransitionMoveIn, kCATransitionPush, kCATransitionReveal, kCATransitionFade};
NSString *subtypes[4] = {kCATransitionFromLeft, kCATransitionFromRight, kCATransitionFromTop, kCATransitionFromBottom};
int rnd = random() % 4;
transition.type=kCATransitionMoveIn;
transition.delegate = self;
[imgView.layer addAnimation:transition forKey:nil];
CGPoint touchPoint = [touch locationInView:self];
[imgView setCenter:touchPoint];
用CABaiscAnimation做動畫
//同時對不同軸做旋轉
CABasicAnimation *animation;
animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
animation.duration = 3;
animation.repeatCount = 1;
animation.fromValue=[NSNumber numberWithFloat:0];
animation.toValue = [NSNumber numberWithFloat:M_PI*2];
//[imgView.layer addAnimation:animation forKey:@"transform.rotation.y"];
[imgView.layer addAnimation:animation forKey:kCATransition];

3、用UIView的beginAnimation來製作動畫

在執行動畫的時候,可以用以下method來讓動化的初始狀態為目前的狀態
[UIView setAnimationBeginsFromCurrentState:YES];
如以下範例

移動動畫
[UIView beginAnimations:nil context:NULL];//動畫委配
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDuration:1];//delay 1 sec 
childView.center = [touch locationInView:self];
[UIView commitAnimations];

變型動畫
ex1
childView.transform = CGAffineTransformMakeScale(1.5, 1.5);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelegate:self];//動畫委配
childView.transform = CGAffineTransformMakeScale(1.5, 1.5);
[UIView commitAnimations];
ex2
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:MOVE_ANIMATION_DURATION_SECONDS];
placardView.transform = CGAffineTransformMakeScale(1.1f, 1.1f); 
NSValue *touchPointValue = (NSValue *)context;
placardView.center = [touchPointValue CGPointValue];
[touchPointValue release];
[UIView commitAnimations];
ex3
[UIView beginAnimations:nil context:NULL];//動畫委配
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDuration:0.5];//delay 1 sec 
CATransform3D t;
t=imgView.layer.transform;
t=CATransform3DRotate(t, radians(180), 0, 1, 0);
imgView.layer.transform=t;
[UIView commitAnimations];