SlideShare a Scribd company logo
1 of 60
Class 15
iOS 應⽤用軟體設計
課程⼤大綱
•   觸控 Touch
    •   QV015:Touch
    •   QV071:BMI 的計算
•   ⼿手勢 Gesture
    •   QV016:Gesture
    •   Samples:Touches
•   三軸加速器 Accelerometer
    •   QV023:Accelerometer
    •   QV024:延伸上述應⽤用 (球的平衡感)
    •   QV025:偵測⼿手機的搖動
•   陀螺儀 Gyroscope
    •   Samples:Erica_Gyro
•   相機
    •   QV173:相機擷取影像及存檔
Event handling
觸控
Touch
• 觸控點⾯面積不要⼩小於 50x50
• 兩個觸控點間的距離不要太近
觸控事件的狀態 •   UITouchPhaseBegan

        •   UITouchPhaseMoved

        •   UITouchPhaseStationary

        •   UITouchPhaseEnded

        •   UITouchPhaseCancelled
• touchesBegan: withEvent:
• touchesMoved: withEvent:
• touchesEnded: withEvent:
• touchesCancelled: withEvent:


                      建議四種⽅方法都要寫
• 取得觸控資訊
 • locationInView (傳回 CGPoint)
 • topCount
 • ......
• 多點觸控時
 • setMultipleTouchEnabled (YES)
Project QV015

觸控 Touch
觸控點的位置
計算位置移動,判斷滑動
的⽅方向
#import <UIKit/UIKit.h>
                                               ViewController.h
#define   X_SWIPE_DRAG_MIN   15
#define   X_SWIPE_DRAG_MAX   4
#define   Y_SWIPE_DRAG_MIN   15
#define   Y_SWIPE_DRAG_MAX   4

@interface ViewController : UIViewController
{
    IBOutlet UILabel *touchLabel;
    IBOutlet UILabel *countLabel;
    IBOutlet UILabel *slideLabel;
    CGPoint pointStart, pointCurrent;
}

@property(retain, nonatomic) IBOutlet UILabel *touchLabel;
@property(retain, nonatomic) IBOutlet UILabel *countLabel;

-(void)handleTouch:(NSSet *) touches : (int) type;

-(void)slideUp:(NSSet *)touches;
-(void)slideDown:(NSSet *)touches;
-(void)slideLeft:(NSSet *)touches;
-(void)slideRight:(NSSet *)touches;

@end
四個與Touch有關之method



-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
ViewController.m (1/4)

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    touchLabel.text = @"觸控開始 (touchBegin)";
    [self handleTouch:touches :1];
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    touchLabel.text = @"觸控移動 (touchMoved)";
    [self handleTouch:touches :2];
    // 省略部分程式
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    touchLabel.text = @"觸控結束 (touchEnd)";
    [self handleTouch:touches :3];
}

-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    touchLabel.text = @"觸控取消 (touchCancelled)";
    [self handleTouch:touches :4];
}
ViewController.m (2/4)

-(void)handleTouch:(NSSet *) touches : (int) type
{
    UITouch *myTouch = [touches anyObject];
    NSUInteger numTaps = [myTouch tapCount];
    switch (type)
    {
        case 1:
            countLabel.text = [[NSString alloc]
                               initWithFormat:@"觸控 %d 次", numTaps];
            pointStart = [myTouch locationInView:self.view];
            break;
        case 2:
            pointCurrent = [myTouch locationInView:self.view];
            countLabel.text = [[NSString alloc]
       initWithFormat:@"(%3.0f, %3.0f)", pointCurrent.x, pointCurrent.y];
            break;
        case 3:
            // 省略
            break;
        case 4:
            // 省略
            break;
        default:
            break;
    }
}
ViewController.m (3/4)

// 增加⽅方向的判斷
if(fabsf(pointCurrent.x-pointStart.x)>=X_SWIPE_DRAG_MIN &&
   fabsf(pointCurrent.y-pointStart.y)<=X_SWIPE_DRAG_MAX)
{
    if(pointCurrent.x > pointStart.x)
    {
         [self slideRight:touches];
    }
    else
    {
         [self slideLeft:touches];
    }
}

if(fabsf(pointCurrent.y-pointStart.y)>=Y_SWIPE_DRAG_MIN &&
   fabsf(pointCurrent.x-pointStart.x)<=X_SWIPE_DRAG_MAX)
{
    if(pointCurrent.y > pointStart.y)
    {
         [self slideDown:touches];
    }
    else
    {
         [self slideUp:touches];
    }
}
ViewController.m (4/4)



-(void)slideUp:(NSSet *)touches
{
    slideLabel.text = @"UP";
}

-(void)slideDown:(NSSet *)touches
{
    slideLabel.text = @"DOWN";
}

-(void)slideLeft:(NSSet *)touches
{
    slideLabel.text = @"LEFT";
}

-(void)slideRight:(NSSet *)touches
{
    slideLabel.text = @"RIGHT";
}
範例:
        BMI 計算
(利⽤用觸控取得座標位置,同時輸⼊入 x,y 兩值)
Project QV071

 BMI 計算
 以觸控⽅方式同時輸⼊入⾝身⾼高
 及體重,並⽴立即顯⽰示 BMI
 除⽂文字外,圖⽚片寬度及⾼高
 度也同時反映⾝身⾼高及體重
ViewController.h




#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
{
    IBOutlet UILabel *heightLabel;
    IBOutlet UILabel *weightLabel;
    IBOutlet UILabel *bmiLabel;
    IBOutlet UIImageView *personImageView;
}

@end
ViewController.xib
ViewController.m (1/2)

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    CGPoint pointTouch;
    UITouch *myTouch = [touches anyObject];
    pointTouch = [myTouch locationInView:self.view];

    float   hMin   =   100;   //   ⾝身⾼高最⼩小值
    float   hMax   =   220;   //   ⾝身⾼高最⼤大值       重要的參數設定
    float   wMin   =   20;    //   體重最⼩小值
    float   wMax   =   120;   //   體重最⼤大值

    float h = (pointTouch.y * (hMin-hMax) / 480) + hMax;
    float w = (pointTouch.x * (wMax-wMin) / 320) + wMin;
    float bmi = w / ((h/100)*(h/100));

    // 處理顯⽰示的⽂文字
    heightLabel.text = [NSString stringWithFormat:@"%3.0f", h];
    weightLabel.text = [NSString stringWithFormat:@"%3.0f", w];
    bmiLabel.text = [NSString stringWithFormat:@"%4.2f", bmi];


    ***** 此處省略部份程式碼 *****
}
ViewController.m (2/2)


- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    ***** 此處省略部份程式碼 *****

    // 處理圖檔⼤大⼩小
    float iwMin =   128;   //   體重最⼩小時的圖檔寬度
    float iwMax =   460;   //   體重最⼤大時的圖檔寬度
    float ihMin =   80;    //   ⾝身⾼高最⼩小時的圖檔⾼高度
    float ihMax =   400;   //   ⾝身⾼高最⼤大時的圖檔⾼高度

    float iw = iwMin + ((w-wMin) * (iwMax-iwMin) / (wMax-wMin));
    float ih = ihMin + ((h-hMin) * (ihMax-ihMin) / (hMax-hMin));

    personImageView.bounds = CGRectMake(0, 0, iw, ih);
    personImageView.center = CGPointMake(160, 260);

}


                                            調整圖⽚片的尺⼨寸
⼿手勢
Gesture
六種⼿手勢

• tap 點擊 (多少根指頭及按幾下)
• pan 拖曳 (位置?)
• swipe 滑過 (向上、向下、向左、向右)
• pinch 兩指撥動 (往內捏縮、往外擴展)
• rotation 旋轉 (順時針、逆時針)
• long press ⻑⾧長按
Gesture Recognizers Simplify
      Event Handling
Project QV016
⼿手勢 Gesture
  指頭數,按的次數
  拖曳
  滑動
  捏縮
  旋轉
  ⻑⾧長按
ViewController.h
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
{
    IBOutlet UILabel *myLabel;
}

@property (retain, nonatomic) IBOutlet UILabel *myLabel;

-(void)handleTap1;
-(void)handleTap2;
-(void)handleTap3;
-(void)handleTap4;
-(void)handleTap5;
-(void)handlePinch: (UIPinchGestureRecognizer *)recognizer;
-(void)handleSwipeRight: (UISwipeGestureRecognizer *)recognizer;
-(void)handleSwipeLeft: (UISwipeGestureRecognizer *)recognizer;
-(void)handleSwipeUp: (UISwipeGestureRecognizer *)recognizer;
-(void)handleSwipeDown: (UISwipeGestureRecognizer *)recognizer;
-(void)handleRotate: (UIRotationGestureRecognizer *)recognizer;
-(void)handleLongPress: (UIRotationGestureRecognizer *)recognizer;

@end
ViewController.m (1/6)

// 設定按⼀一下的⼿手勢
UITapGestureRecognizer *tapGesture1 = [[UITapGestureRecognizer alloc]
                                       initWithTarget:self
                                       action:@selector(handleTap1)];
[self.view addGestureRecognizer:tapGesture1];


// 設定要按兩下的⼿手勢
UITapGestureRecognizer *tapGesture2 = [[UITapGestureRecognizer alloc]
                                       initWithTarget:self
                                       action:@selector(handleTap2)];
tapGesture2.numberOfTapsRequired = 2;
[self.view addGestureRecognizer:tapGesture2];


// 設定要兩根⼿手指的⼿手勢
UITapGestureRecognizer *tapGesture3 = [[UITapGestureRecognizer alloc]
                                       initWithTarget:self
                                       action:@selector(handleTap3)];
tapGesture3.numberOfTouchesRequired = 2;
[self.view addGestureRecognizer:tapGesture3];



                                設定按下的次數及有幾根⼿手指
ViewController.m (2/6)

   // 設定要兩根⼿手指、按兩下的⼿手勢
   UITapGestureRecognizer *tapGesture4 = [[UITapGestureRecognizer alloc]
                                          initWithTarget:self
                                          action:@selector(handleTap4)];
   tapGesture4.numberOfTapsRequired = 2;
   tapGesture4.numberOfTouchesRequired = 2;
   [self.view addGestureRecognizer:tapGesture4];


   // 設定要三根⼿手指、按兩下的⼿手勢
   UITapGestureRecognizer *tapGesture5 = [[UITapGestureRecognizer alloc]
                                          initWithTarget:self
                                          action:@selector(handleTap5)];
   tapGesture5.numberOfTapsRequired = 3;
   tapGesture5.numberOfTouchesRequired = 3;
   [self.view addGestureRecognizer:tapGesture5];


-(void)handleTap1
{
    NSString *myString = [[NSString alloc] initWithFormat:@"按⼀一下⼿手勢"];
    myLabel.text = myString;
}
ViewController.m (3/6)
// 設定滑動⼿手勢 (Swipe Right)
   UISwipeGestureRecognizer *swipeRightGesture =
          [[UISwipeGestureRecognizer alloc]
            initWithTarget:self action:@selector(handleSwipeRight:)];
   [self.view addGestureRecognizer:swipeRightGesture];

// 設定滑動⼿手勢 (Swipe Left)
   UISwipeGestureRecognizer *swipeLeftGesture =
          [[UISwipeGestureRecognizer alloc]
            initWithTarget:self action:@selector(handleSwipeLeft:)];
   [swipeLeftGesture setDirection:UISwipeGestureRecognizerDirectionLeft];
   [self.view addGestureRecognizer:swipeLeftGesture];

// 設定滑動⼿手勢 (Swipe Up)
   UISwipeGestureRecognizer *swipeUpGesture =
          [[UISwipeGestureRecognizer alloc]
            initWithTarget:self action:@selector(handleSwipeUp:)];
   [swipeUpGesture setDirection:UISwipeGestureRecognizerDirectionUp];
   [self.view addGestureRecognizer:swipeUpGesture];

// 設定滑動⼿手勢 (Swipe Down)
   UISwipeGestureRecognizer *swipeDownGesture =
          [[UISwipeGestureRecognizer alloc]
            initWithTarget:self action:@selector(handleSwipeDown:)];
   [swipeDownGesture setDirection: UISwipeGestureRecognizerDirectionDown];
   [self.view addGestureRecognizer:swipeDownGesture];
ViewController.m (4/6)



// 設定捏縮⼿手勢 (Pinch)
   UIPinchGestureRecognizer *pinchGesture =
          [[UIPinchGestureRecognizer alloc]
            initWithTarget:self
                    action:@selector(handlePinch:)];
   [self.view addGestureRecognizer:pinchGesture];




-(void)handlePinch: (UIPinchGestureRecognizer *)recognizer
{
    NSString *myString = [[NSString alloc] initWithFormat:
                @"執⾏行捏縮⼿手勢 (Pinch scale: %f)", recognizer.scale];
    myLabel.text = myString;
}



                                         注意 scale 值...
                                          ⼤大於1表⽰示向外捏
                                          ⼩小於1表⽰示向內捏
ViewController.m (5/6)



   // 設定旋轉⼿手勢
      UIRotationGestureRecognizer *rotateGesture =
                [[UIRotationGestureRecognizer alloc]
                  initWithTarget:self
                          action:@selector(handleRotate:)];
      [self.view addGestureRecognizer:rotateGesture];




-(void)handleRotate:(UIRotationGestureRecognizer *)recognizer
{
    NSString *myString = [[NSString alloc] initWithFormat:
               @"執⾏行旋轉⼿手勢。⾓角度 %f", [recognizer rotation]*180/M_PI];
    myLabel.text = myString;
}
ViewController.m (6/6)



   // 設定⻑⾧長按⼿手勢
      UILongPressGestureRecognizer *longPressGesture =
                  [[UILongPressGestureRecognizer alloc]
                    initWithTarget:self
                            action:@selector(handleLongPress:)];
      [self.view addGestureRecognizer:longPressGesture];



-(void)handleLongPress:(UIRotationGestureRecognizer *)recognizer
{
    NSString *myString = [[NSString alloc]
                           initWithFormat:@"你執⾏行了⻑⾧長按⼿手勢。"];
    CGPoint location = [recognizer locationInView:[recognizer view]];
    NSLog(@"%f , %f", location.x, location.y);
    myLabel.text = myString;
}
補充說明

另有拖曳 (pan) ⼿手勢,請⾒見程式原始碼
⼿手勢 (iOS 3.2) 是在觸控 (iOS 2.x) 之後
推出,如為單純判斷⼿手勢類型,則直接
使⽤用⼿手勢⽅方式。
範例觀摩:Touches
The Touches sample application
demonstrates how to handle touches,
including multiple touches that move
multiple objects. After the application
launches, three colored pieces appear
onscreen that the user can move
independently.
"Touches_Classic" demonstrates how
to handle touches using
UIResponder's: touches began,
touches moved, and touches ended.
"Touches_GestureRecognizers"
demonstrates how to use
UIGestureRecognizers to handle
touch events.
三軸加速器
Accelerometer
Project QV023



加速度感測器
          本範例需在實機
           上才能執⾏行
ViewController.h



#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UIAccelerometerDelegate>
{
    UILabel *display;
    UIAccelerationValue gx, gy, gz;
}

@end

                                          使⽤用代理的協定
ViewController.m (1/2)
- (void)loadView
{
    // 設定主視圖
    self.view = [[UIView alloc]
                initWithFrame:[[UIScreen mainScreen] applicationFrame]];
    self.view.backgroundColor = [UIColor whiteColor];

    // 產⽣生顯⽰示區
    display = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 380)];
    display.font = [UIFont fontWithName:@"Helvetica" size:36.0f];
    display.textColor = [UIColor blackColor];
    display.backgroundColor = [UIColor clearColor];
    display.lineBreakMode = UILineBreakModeWordWrap;
    display.numberOfLines = 0;
    display.text = @"";

    [self.view addSubview:display];

    // 取得加速度感應器的實體
    UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];
    accelerometer.updateInterval = 0.1;
    accelerometer.delegate = self;

}
ViewController.m (2/2)



- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:
(UIAcceleration *)acceleration
{
    // 低階篩選程序 Low-pass Filter (重⼒力加速度)
    gx = acceleration.x * 0.1 + gx * (1.0-0.1);
    gy = acceleration.y * 0.1 + gy * (1.0-0.1);
    gz = acceleration.z * 0.1 + gz * (1.0-0.1);

    // ⾼高階篩選程序 High-pass Filter(瞬間加速度)
    UIAccelerationValue ax, ay, az;
    ax = acceleration.x - gx;
    ay = acceleration.y - gy;
    az = acceleration.z - gz;

    // 顯⽰示
    display.text = [NSString stringWithFormat:
             @"X:%fnY:%fnZ:%fnnnX:%fnY:%fnZ:%fn",
             gx, gy, gz, ax, ay, az];
}
Project QV024


延伸QV023的應⽤用
加速度感測器
              本範例需在實機
球的移動平衡         上才能執⾏行
ViewController.h



#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
<UIAccelerometerDelegate>
{
    UILabel *display;
    UIImageView *imageView;
    UIAccelerationValue gx, gy, gz;
    float ballDX, ballDY; // 球的移動速度
}

@end
ViewController.m (1/2)
- (void)loadView
{
    [super loadView];

    // 設定主視圖
    self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
    self.view.backgroundColor = [UIColor whiteColor];

    // 產⽣生顯⽰示區
    display = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 380)];
    display.font = [UIFont fontWithName:@"Helvetica" size:14.0f];
    display.textColor = [UIColor blackColor];
    display.backgroundColor = [UIColor clearColor];
    display.lineBreakMode = UILineBreakModeWordWrap;
    display.numberOfLines = 0;
    display.text = @"";

    [self.view addSubview:display];

    // 產⽣生球的圖
    imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100f,200f,BALL_SIZE, BALL_SIZE)];
    imageView.image = [UIImage imageNamed:@"ball.png"];
    [self.view addSubview:imageView];

    // 取得加速度感應器的實體
    UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];
    accelerometer.updateInterval = 1.0 / 30;
    accelerometer.delegate = self;

    // 球的移動速度
    ballDX = 0.0f;
    ballDY = 0.0f;
}
- (void)accelerometer:(UIAccelerometer   *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
    // 低階篩選程序
    gx = acceleration.x * RATIO + gx *   (1.0-RATIO);
    gy = acceleration.y * RATIO + gy *   (1.0-RATIO);
    gz = acceleration.z * RATIO + gz *   (1.0-RATIO);

    // ⾼高階篩選程序                                                       ViewController.m (2/2)
    UIAccelerationValue   ax, ay, az;
    ax = acceleration.x   - gx;
    ay = acceleration.y   - gy;
    az = acceleration.z   - gz;

    // 速度更新
    ballDX += gx;
    ballDY -= gy;
    if(ballDX > MAX_SPEED) ballDX = MAX_SPEED;
    if(ballDX < -MAX_SPEED) ballDX = -MAX_SPEED;
    if(ballDY > MAX_SPEED) ballDY = MAX_SPEED;
    if(ballDY < -MAX_SPEED) ballDY = -MAX_SPEED;

    // 更新座標
    float newX = imageView.center.x + ballDX;
    float newY = imageView.center.y + ballDY;
    imageView.center = CGPointMake(newX, newY);

    // 若超出畫⾯面外,返回初始位置
    if(newX<-BALL_SIZE/2 || newX>320+BALL_SIZE/2 || newY<-BALL_SIZE/2 || newY>480+BALL_SIZE/2)
    {
        imageView.center = CGPointMake(160, 240);
        ballDX = 0.0f;
        ballDY = 0.0f;
    }

    // 顯⽰示
    display.text = [NSString stringWithFormat:@"X:%fnY:%fnZ:%fnnnX:%fnY:%fnZ:%fn",
                                                gx, gy, gz, ax, ay, az];
}
Project QV025


加速度感測器
偵測⼿手機的搖動   本範例需在實機
            上才能執⾏行
ViewController.h



#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
<UIAccelerometerDelegate>
{
    IBOutlet UILabel *display;
    UIAccelerationValue gx, gy, gz;
    BOOL shaking;
}

@end
ViewController.m (1/2)

#import "ViewController.h"

#define SHAKE_AX 1.5

@implementation ViewController

- (void)loadView
{
    [super loadView];

    UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];
    accelerometer.updateInterval = 0.1;
    accelerometer.delegate = self;
}

// 省略部分程式

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    shaking = NO;
    display.text = @"搖";
}

@end
ViewController.m (2/2)


- (void)accelerometer:(UIAccelerometer *)accelerometer
didAccelerate:(UIAcceleration *)acceleration
{
    // 低階篩選程序 (重⼒力加速度)
    gx = acceleration.x * 0.1 + gx * (1.0-0.1);
    gy = acceleration.y * 0.1 + gy * (1.0-0.1);
    gz = acceleration.z * 0.1 + gz * (1.0-0.1);

    // ⾼高階篩選程序 (瞬間重⼒力加速度)
    UIAccelerationValue ax, ay, az;
    ax = acceleration.x - gx;
    ay = acceleration.y - gy;
    az = acceleration.z - gz;

    // 只要瞬間加速度超過預設⾨門檻值就搖晃
    if(!shaking && (ax>SHAKE_AX || ax<-SHAKE_AX))
    {
        shaking = YES;
        display.text = @"!!!爆炸!!!";
    }
}
陀螺儀 (旋轉)
 Gyroscope
範例觀摩:Erica_Gyro


      - 須在實機上執⾏行
      - CoreMotion framework
相機的影像擷取及存檔
Project QV173

相機擷取
相⽚片存檔

        此程式需於實機上執⾏行
ViewController.h
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
<UIImagePickerControllerDelegate, UINavigationControllerDelegate>
{

}                               影像擷取代理協定
// 顯⽰示拍攝後影像 view
@property (nonatomic, retain) IBOutlet UIImageView *imageView;

// 儲存按鈕
@property (nonatomic, retain) IBOutlet UIBarButtonItem *saveImageButton;

// 在相機上顯⽰示拍攝畫⾯面
- (IBAction) showCameraAction:(id)sender;

// 把拍攝後影像儲存到 iPhone 相簿
- (IBAction) saveImageAction:(id)sender;

@end
ViewController.xib
ViewController.m (1/2)

- (IBAction) showCameraAction:(id)sender
{
    UIImagePickerController *imagePickerController =
                         [[UIImagePickerController alloc] init];
    imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
    imagePickerController.delegate = self;
    imagePickerController.allowsEditing = YES;
    [self presentModalViewController:imagePickerController animated:YES];
}


- (void) imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    UIImage *image = [info objectForKey:UIImagePickerControllerEditedImage];
    imageView.image = image;

    saveImageButton.enabled = YES;
    [self dismissModalViewControllerAnimated:YES];
}
ViewController.m (2/2)




- (IBAction) saveImageAction:(id)sender
{
    UIImage *image = imageView.image;
    UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
    saveImageButton.enabled = NO;
}
............

More Related Content

Viewers also liked (14)

I os 14
I os 14I os 14
I os 14
 
I os 07
I os 07I os 07
I os 07
 
I os 02
I os 02I os 02
I os 02
 
I os 06
I os 06I os 06
I os 06
 
I os 03
I os 03I os 03
I os 03
 
I os 16
I os 16I os 16
I os 16
 
I os 04
I os 04I os 04
I os 04
 
課程規畫
課程規畫課程規畫
課程規畫
 
I os 05
I os 05I os 05
I os 05
 
I os 08
I os 08I os 08
I os 08
 
I os 09
I os 09I os 09
I os 09
 
I os 11
I os 11I os 11
I os 11
 
I os 10
I os 10I os 10
I os 10
 
I os 13
I os 13I os 13
I os 13
 

Similar to I os 15

Our Choice:电子书的新交互方式探讨
Our Choice:电子书的新交互方式探讨Our Choice:电子书的新交互方式探讨
Our Choice:电子书的新交互方式探讨foxgem
 
Anyone can play iPhone-Tuzhiwu
Anyone can play iPhone-TuzhiwuAnyone can play iPhone-Tuzhiwu
Anyone can play iPhone-TuzhiwuXiaochun Shen
 
CocoaHeads Toulouse - Guillaume Cerquant - UIView
CocoaHeads Toulouse - Guillaume Cerquant - UIViewCocoaHeads Toulouse - Guillaume Cerquant - UIView
CocoaHeads Toulouse - Guillaume Cerquant - UIViewCocoaHeads France
 
Константин Чернухо_Popups, alerts and windows
Константин Чернухо_Popups, alerts and windowsКонстантин Чернухо_Popups, alerts and windows
Константин Чернухо_Popups, alerts and windowsGeeksLab Odessa
 
iPhoneOS3.1でのカメラAPIについて
iPhoneOS3.1でのカメラAPIについてiPhoneOS3.1でのカメラAPIについて
iPhoneOS3.1でのカメラAPIについてKyosuke Takayama
 
Android Event and IntentAndroid Event and Intent
Android Event and IntentAndroid Event and IntentAndroid Event and IntentAndroid Event and Intent
Android Event and IntentAndroid Event and Intentadmin220812
 
Leaving Interface Builder Behind
Leaving Interface Builder BehindLeaving Interface Builder Behind
Leaving Interface Builder BehindJohn Wilker
 
ReactiveCocoa in Practice
ReactiveCocoa in PracticeReactiveCocoa in Practice
ReactiveCocoa in PracticeOutware Mobile
 
Курсы по мобильной разработке. 3 лекция. Сложные интерфейсы.
Курсы по мобильной разработке. 3 лекция. Сложные интерфейсы.Курсы по мобильной разработке. 3 лекция. Сложные интерфейсы.
Курсы по мобильной разработке. 3 лекция. Сложные интерфейсы.Глеб Тарасов
 
cocos2d 事例編 HungryMasterの実装から
cocos2d 事例編 HungryMasterの実装からcocos2d 事例編 HungryMasterの実装から
cocos2d 事例編 HungryMasterの実装からYuichi Higuchi
 
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...DroidConTLV
 
Swift ui userinput
Swift ui userinputSwift ui userinput
Swift ui userinputjoonjhokil
 
Курсы по мобильной разработке под iOS. 4 лекция. Возможности телефона
Курсы по мобильной разработке под iOS. 4 лекция. Возможности телефонаКурсы по мобильной разработке под iOS. 4 лекция. Возможности телефона
Курсы по мобильной разработке под iOS. 4 лекция. Возможности телефонаГлеб Тарасов
 
Getting touchy - an introduction to touch and pointer events / Future of Web ...
Getting touchy - an introduction to touch and pointer events / Future of Web ...Getting touchy - an introduction to touch and pointer events / Future of Web ...
Getting touchy - an introduction to touch and pointer events / Future of Web ...Patrick Lauke
 
Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs
Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCsStandford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs
Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs彼得潘 Pan
 
Advancing the UI — Part 1: Look, Motion, and Gestures
Advancing the UI — Part 1: Look, Motion, and GesturesAdvancing the UI — Part 1: Look, Motion, and Gestures
Advancing the UI — Part 1: Look, Motion, and GesturesSamsung Developers
 

Similar to I os 15 (20)

Our Choice:电子书的新交互方式探讨
Our Choice:电子书的新交互方式探讨Our Choice:电子书的新交互方式探讨
Our Choice:电子书的新交互方式探讨
 
Anyone can play iPhone-Tuzhiwu
Anyone can play iPhone-TuzhiwuAnyone can play iPhone-Tuzhiwu
Anyone can play iPhone-Tuzhiwu
 
CocoaHeads Toulouse - Guillaume Cerquant - UIView
CocoaHeads Toulouse - Guillaume Cerquant - UIViewCocoaHeads Toulouse - Guillaume Cerquant - UIView
CocoaHeads Toulouse - Guillaume Cerquant - UIView
 
Константин Чернухо_Popups, alerts and windows
Константин Чернухо_Popups, alerts and windowsКонстантин Чернухо_Popups, alerts and windows
Константин Чернухо_Popups, alerts and windows
 
iPhoneOS3.1でのカメラAPIについて
iPhoneOS3.1でのカメラAPIについてiPhoneOS3.1でのカメラAPIについて
iPhoneOS3.1でのカメラAPIについて
 
Android Event and IntentAndroid Event and Intent
Android Event and IntentAndroid Event and IntentAndroid Event and IntentAndroid Event and Intent
Android Event and IntentAndroid Event and Intent
 
Java awt
Java awtJava awt
Java awt
 
Package org dev
Package org devPackage org dev
Package org dev
 
Leaving Interface Builder Behind
Leaving Interface Builder BehindLeaving Interface Builder Behind
Leaving Interface Builder Behind
 
ReactiveCocoa in Practice
ReactiveCocoa in PracticeReactiveCocoa in Practice
ReactiveCocoa in Practice
 
Курсы по мобильной разработке. 3 лекция. Сложные интерфейсы.
Курсы по мобильной разработке. 3 лекция. Сложные интерфейсы.Курсы по мобильной разработке. 3 лекция. Сложные интерфейсы.
Курсы по мобильной разработке. 3 лекция. Сложные интерфейсы.
 
cocos2d 事例編 HungryMasterの実装から
cocos2d 事例編 HungryMasterの実装からcocos2d 事例編 HungryMasterの実装から
cocos2d 事例編 HungryMasterの実装から
 
Working with Callbacks
Working with CallbacksWorking with Callbacks
Working with Callbacks
 
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
 
Swift ui userinput
Swift ui userinputSwift ui userinput
Swift ui userinput
 
Курсы по мобильной разработке под iOS. 4 лекция. Возможности телефона
Курсы по мобильной разработке под iOS. 4 лекция. Возможности телефонаКурсы по мобильной разработке под iOS. 4 лекция. Возможности телефона
Курсы по мобильной разработке под iOS. 4 лекция. Возможности телефона
 
Getting touchy - an introduction to touch and pointer events / Future of Web ...
Getting touchy - an introduction to touch and pointer events / Future of Web ...Getting touchy - an introduction to touch and pointer events / Future of Web ...
Getting touchy - an introduction to touch and pointer events / Future of Web ...
 
Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs
Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCsStandford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs
Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs
 
Mobile Application Development class 005
Mobile Application Development class 005Mobile Application Development class 005
Mobile Application Development class 005
 
Advancing the UI — Part 1: Look, Motion, and Gestures
Advancing the UI — Part 1: Look, Motion, and GesturesAdvancing the UI — Part 1: Look, Motion, and Gestures
Advancing the UI — Part 1: Look, Motion, and Gestures
 

More from 信嘉 陳

More from 信嘉 陳 (13)

Processing 06
Processing 06Processing 06
Processing 06
 
Processing 05
Processing 05Processing 05
Processing 05
 
Processing 04
Processing 04Processing 04
Processing 04
 
Processing 03
Processing 03Processing 03
Processing 03
 
Processing 02
Processing 02Processing 02
Processing 02
 
Processing 01
Processing 01Processing 01
Processing 01
 
Processing 09
Processing 09Processing 09
Processing 09
 
Processing 08
Processing 08Processing 08
Processing 08
 
Processing 07
Processing 07Processing 07
Processing 07
 
I os 01
I os 01I os 01
I os 01
 
Google 街景
Google 街景Google 街景
Google 街景
 
社群網站 Facebook
社群網站 Facebook社群網站 Facebook
社群網站 Facebook
 
網路搜尋
網路搜尋網路搜尋
網路搜尋
 

I os 15

  • 2. 課程⼤大綱 • 觸控 Touch • QV015:Touch • QV071:BMI 的計算 • ⼿手勢 Gesture • QV016:Gesture • Samples:Touches • 三軸加速器 Accelerometer • QV023:Accelerometer • QV024:延伸上述應⽤用 (球的平衡感) • QV025:偵測⼿手機的搖動 • 陀螺儀 Gyroscope • Samples:Erica_Gyro • 相機 • QV173:相機擷取影像及存檔
  • 4.
  • 6. • 觸控點⾯面積不要⼩小於 50x50 • 兩個觸控點間的距離不要太近
  • 7. 觸控事件的狀態 • UITouchPhaseBegan • UITouchPhaseMoved • UITouchPhaseStationary • UITouchPhaseEnded • UITouchPhaseCancelled
  • 8. • touchesBegan: withEvent: • touchesMoved: withEvent: • touchesEnded: withEvent: • touchesCancelled: withEvent: 建議四種⽅方法都要寫
  • 9. • 取得觸控資訊 • locationInView (傳回 CGPoint) • topCount • ...... • 多點觸控時 • setMultipleTouchEnabled (YES)
  • 11. #import <UIKit/UIKit.h> ViewController.h #define X_SWIPE_DRAG_MIN 15 #define X_SWIPE_DRAG_MAX 4 #define Y_SWIPE_DRAG_MIN 15 #define Y_SWIPE_DRAG_MAX 4 @interface ViewController : UIViewController { IBOutlet UILabel *touchLabel; IBOutlet UILabel *countLabel; IBOutlet UILabel *slideLabel; CGPoint pointStart, pointCurrent; } @property(retain, nonatomic) IBOutlet UILabel *touchLabel; @property(retain, nonatomic) IBOutlet UILabel *countLabel; -(void)handleTouch:(NSSet *) touches : (int) type; -(void)slideUp:(NSSet *)touches; -(void)slideDown:(NSSet *)touches; -(void)slideLeft:(NSSet *)touches; -(void)slideRight:(NSSet *)touches; @end
  • 12. 四個與Touch有關之method -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event -(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
  • 13. ViewController.m (1/4) -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { touchLabel.text = @"觸控開始 (touchBegin)"; [self handleTouch:touches :1]; } -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { touchLabel.text = @"觸控移動 (touchMoved)"; [self handleTouch:touches :2]; // 省略部分程式 } -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { touchLabel.text = @"觸控結束 (touchEnd)"; [self handleTouch:touches :3]; } -(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { touchLabel.text = @"觸控取消 (touchCancelled)"; [self handleTouch:touches :4]; }
  • 14. ViewController.m (2/4) -(void)handleTouch:(NSSet *) touches : (int) type { UITouch *myTouch = [touches anyObject]; NSUInteger numTaps = [myTouch tapCount]; switch (type) { case 1: countLabel.text = [[NSString alloc] initWithFormat:@"觸控 %d 次", numTaps]; pointStart = [myTouch locationInView:self.view]; break; case 2: pointCurrent = [myTouch locationInView:self.view]; countLabel.text = [[NSString alloc] initWithFormat:@"(%3.0f, %3.0f)", pointCurrent.x, pointCurrent.y]; break; case 3: // 省略 break; case 4: // 省略 break; default: break; } }
  • 15. ViewController.m (3/4) // 增加⽅方向的判斷 if(fabsf(pointCurrent.x-pointStart.x)>=X_SWIPE_DRAG_MIN && fabsf(pointCurrent.y-pointStart.y)<=X_SWIPE_DRAG_MAX) { if(pointCurrent.x > pointStart.x) { [self slideRight:touches]; } else { [self slideLeft:touches]; } } if(fabsf(pointCurrent.y-pointStart.y)>=Y_SWIPE_DRAG_MIN && fabsf(pointCurrent.x-pointStart.x)<=X_SWIPE_DRAG_MAX) { if(pointCurrent.y > pointStart.y) { [self slideDown:touches]; } else { [self slideUp:touches]; } }
  • 16. ViewController.m (4/4) -(void)slideUp:(NSSet *)touches { slideLabel.text = @"UP"; } -(void)slideDown:(NSSet *)touches { slideLabel.text = @"DOWN"; } -(void)slideLeft:(NSSet *)touches { slideLabel.text = @"LEFT"; } -(void)slideRight:(NSSet *)touches { slideLabel.text = @"RIGHT"; }
  • 17. 範例: BMI 計算 (利⽤用觸控取得座標位置,同時輸⼊入 x,y 兩值)
  • 18. Project QV071 BMI 計算 以觸控⽅方式同時輸⼊入⾝身⾼高 及體重,並⽴立即顯⽰示 BMI 除⽂文字外,圖⽚片寬度及⾼高 度也同時反映⾝身⾼高及體重
  • 19. ViewController.h #import <UIKit/UIKit.h> @interface ViewController : UIViewController { IBOutlet UILabel *heightLabel; IBOutlet UILabel *weightLabel; IBOutlet UILabel *bmiLabel; IBOutlet UIImageView *personImageView; } @end
  • 21. ViewController.m (1/2) - (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { CGPoint pointTouch; UITouch *myTouch = [touches anyObject]; pointTouch = [myTouch locationInView:self.view]; float hMin = 100; // ⾝身⾼高最⼩小值 float hMax = 220; // ⾝身⾼高最⼤大值 重要的參數設定 float wMin = 20; // 體重最⼩小值 float wMax = 120; // 體重最⼤大值 float h = (pointTouch.y * (hMin-hMax) / 480) + hMax; float w = (pointTouch.x * (wMax-wMin) / 320) + wMin; float bmi = w / ((h/100)*(h/100)); // 處理顯⽰示的⽂文字 heightLabel.text = [NSString stringWithFormat:@"%3.0f", h]; weightLabel.text = [NSString stringWithFormat:@"%3.0f", w]; bmiLabel.text = [NSString stringWithFormat:@"%4.2f", bmi]; ***** 此處省略部份程式碼 ***** }
  • 22. ViewController.m (2/2) - (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { ***** 此處省略部份程式碼 ***** // 處理圖檔⼤大⼩小 float iwMin = 128; // 體重最⼩小時的圖檔寬度 float iwMax = 460; // 體重最⼤大時的圖檔寬度 float ihMin = 80; // ⾝身⾼高最⼩小時的圖檔⾼高度 float ihMax = 400; // ⾝身⾼高最⼤大時的圖檔⾼高度 float iw = iwMin + ((w-wMin) * (iwMax-iwMin) / (wMax-wMin)); float ih = ihMin + ((h-hMin) * (ihMax-ihMin) / (hMax-hMin)); personImageView.bounds = CGRectMake(0, 0, iw, ih); personImageView.center = CGPointMake(160, 260); } 調整圖⽚片的尺⼨寸
  • 24. 六種⼿手勢 • tap 點擊 (多少根指頭及按幾下) • pan 拖曳 (位置?) • swipe 滑過 (向上、向下、向左、向右) • pinch 兩指撥動 (往內捏縮、往外擴展) • rotation 旋轉 (順時針、逆時針) • long press ⻑⾧長按
  • 26.
  • 27. Project QV016 ⼿手勢 Gesture 指頭數,按的次數 拖曳 滑動 捏縮 旋轉 ⻑⾧長按
  • 28. ViewController.h #import <UIKit/UIKit.h> @interface ViewController : UIViewController { IBOutlet UILabel *myLabel; } @property (retain, nonatomic) IBOutlet UILabel *myLabel; -(void)handleTap1; -(void)handleTap2; -(void)handleTap3; -(void)handleTap4; -(void)handleTap5; -(void)handlePinch: (UIPinchGestureRecognizer *)recognizer; -(void)handleSwipeRight: (UISwipeGestureRecognizer *)recognizer; -(void)handleSwipeLeft: (UISwipeGestureRecognizer *)recognizer; -(void)handleSwipeUp: (UISwipeGestureRecognizer *)recognizer; -(void)handleSwipeDown: (UISwipeGestureRecognizer *)recognizer; -(void)handleRotate: (UIRotationGestureRecognizer *)recognizer; -(void)handleLongPress: (UIRotationGestureRecognizer *)recognizer; @end
  • 29. ViewController.m (1/6) // 設定按⼀一下的⼿手勢 UITapGestureRecognizer *tapGesture1 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap1)]; [self.view addGestureRecognizer:tapGesture1]; // 設定要按兩下的⼿手勢 UITapGestureRecognizer *tapGesture2 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap2)]; tapGesture2.numberOfTapsRequired = 2; [self.view addGestureRecognizer:tapGesture2]; // 設定要兩根⼿手指的⼿手勢 UITapGestureRecognizer *tapGesture3 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap3)]; tapGesture3.numberOfTouchesRequired = 2; [self.view addGestureRecognizer:tapGesture3]; 設定按下的次數及有幾根⼿手指
  • 30. ViewController.m (2/6) // 設定要兩根⼿手指、按兩下的⼿手勢 UITapGestureRecognizer *tapGesture4 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap4)]; tapGesture4.numberOfTapsRequired = 2; tapGesture4.numberOfTouchesRequired = 2; [self.view addGestureRecognizer:tapGesture4]; // 設定要三根⼿手指、按兩下的⼿手勢 UITapGestureRecognizer *tapGesture5 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap5)]; tapGesture5.numberOfTapsRequired = 3; tapGesture5.numberOfTouchesRequired = 3; [self.view addGestureRecognizer:tapGesture5]; -(void)handleTap1 { NSString *myString = [[NSString alloc] initWithFormat:@"按⼀一下⼿手勢"]; myLabel.text = myString; }
  • 31. ViewController.m (3/6) // 設定滑動⼿手勢 (Swipe Right) UISwipeGestureRecognizer *swipeRightGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeRight:)]; [self.view addGestureRecognizer:swipeRightGesture]; // 設定滑動⼿手勢 (Swipe Left) UISwipeGestureRecognizer *swipeLeftGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeLeft:)]; [swipeLeftGesture setDirection:UISwipeGestureRecognizerDirectionLeft]; [self.view addGestureRecognizer:swipeLeftGesture]; // 設定滑動⼿手勢 (Swipe Up) UISwipeGestureRecognizer *swipeUpGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeUp:)]; [swipeUpGesture setDirection:UISwipeGestureRecognizerDirectionUp]; [self.view addGestureRecognizer:swipeUpGesture]; // 設定滑動⼿手勢 (Swipe Down) UISwipeGestureRecognizer *swipeDownGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeDown:)]; [swipeDownGesture setDirection: UISwipeGestureRecognizerDirectionDown]; [self.view addGestureRecognizer:swipeDownGesture];
  • 32. ViewController.m (4/6) // 設定捏縮⼿手勢 (Pinch) UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinch:)]; [self.view addGestureRecognizer:pinchGesture]; -(void)handlePinch: (UIPinchGestureRecognizer *)recognizer { NSString *myString = [[NSString alloc] initWithFormat: @"執⾏行捏縮⼿手勢 (Pinch scale: %f)", recognizer.scale]; myLabel.text = myString; } 注意 scale 值... ⼤大於1表⽰示向外捏 ⼩小於1表⽰示向內捏
  • 33. ViewController.m (5/6) // 設定旋轉⼿手勢 UIRotationGestureRecognizer *rotateGesture = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(handleRotate:)]; [self.view addGestureRecognizer:rotateGesture]; -(void)handleRotate:(UIRotationGestureRecognizer *)recognizer { NSString *myString = [[NSString alloc] initWithFormat: @"執⾏行旋轉⼿手勢。⾓角度 %f", [recognizer rotation]*180/M_PI]; myLabel.text = myString; }
  • 34. ViewController.m (6/6) // 設定⻑⾧長按⼿手勢 UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)]; [self.view addGestureRecognizer:longPressGesture]; -(void)handleLongPress:(UIRotationGestureRecognizer *)recognizer { NSString *myString = [[NSString alloc] initWithFormat:@"你執⾏行了⻑⾧長按⼿手勢。"]; CGPoint location = [recognizer locationInView:[recognizer view]]; NSLog(@"%f , %f", location.x, location.y); myLabel.text = myString; }
  • 35. 補充說明 另有拖曳 (pan) ⼿手勢,請⾒見程式原始碼 ⼿手勢 (iOS 3.2) 是在觸控 (iOS 2.x) 之後 推出,如為單純判斷⼿手勢類型,則直接 使⽤用⼿手勢⽅方式。
  • 36. 範例觀摩:Touches The Touches sample application demonstrates how to handle touches, including multiple touches that move multiple objects. After the application launches, three colored pieces appear onscreen that the user can move independently. "Touches_Classic" demonstrates how to handle touches using UIResponder's: touches began, touches moved, and touches ended. "Touches_GestureRecognizers" demonstrates how to use UIGestureRecognizers to handle touch events.
  • 38.
  • 39. Project QV023 加速度感測器 本範例需在實機 上才能執⾏行
  • 40. ViewController.h #import <UIKit/UIKit.h> @interface ViewController : UIViewController <UIAccelerometerDelegate> { UILabel *display; UIAccelerationValue gx, gy, gz; } @end 使⽤用代理的協定
  • 41. ViewController.m (1/2) - (void)loadView { // 設定主視圖 self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]]; self.view.backgroundColor = [UIColor whiteColor]; // 產⽣生顯⽰示區 display = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 380)]; display.font = [UIFont fontWithName:@"Helvetica" size:36.0f]; display.textColor = [UIColor blackColor]; display.backgroundColor = [UIColor clearColor]; display.lineBreakMode = UILineBreakModeWordWrap; display.numberOfLines = 0; display.text = @""; [self.view addSubview:display]; // 取得加速度感應器的實體 UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer]; accelerometer.updateInterval = 0.1; accelerometer.delegate = self; }
  • 42. ViewController.m (2/2) - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate: (UIAcceleration *)acceleration { // 低階篩選程序 Low-pass Filter (重⼒力加速度) gx = acceleration.x * 0.1 + gx * (1.0-0.1); gy = acceleration.y * 0.1 + gy * (1.0-0.1); gz = acceleration.z * 0.1 + gz * (1.0-0.1); // ⾼高階篩選程序 High-pass Filter(瞬間加速度) UIAccelerationValue ax, ay, az; ax = acceleration.x - gx; ay = acceleration.y - gy; az = acceleration.z - gz; // 顯⽰示 display.text = [NSString stringWithFormat: @"X:%fnY:%fnZ:%fnnnX:%fnY:%fnZ:%fn", gx, gy, gz, ax, ay, az]; }
  • 43. Project QV024 延伸QV023的應⽤用 加速度感測器 本範例需在實機 球的移動平衡 上才能執⾏行
  • 44. ViewController.h #import <UIKit/UIKit.h> @interface ViewController : UIViewController <UIAccelerometerDelegate> { UILabel *display; UIImageView *imageView; UIAccelerationValue gx, gy, gz; float ballDX, ballDY; // 球的移動速度 } @end
  • 45. ViewController.m (1/2) - (void)loadView { [super loadView]; // 設定主視圖 self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]]; self.view.backgroundColor = [UIColor whiteColor]; // 產⽣生顯⽰示區 display = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 380)]; display.font = [UIFont fontWithName:@"Helvetica" size:14.0f]; display.textColor = [UIColor blackColor]; display.backgroundColor = [UIColor clearColor]; display.lineBreakMode = UILineBreakModeWordWrap; display.numberOfLines = 0; display.text = @""; [self.view addSubview:display]; // 產⽣生球的圖 imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100f,200f,BALL_SIZE, BALL_SIZE)]; imageView.image = [UIImage imageNamed:@"ball.png"]; [self.view addSubview:imageView]; // 取得加速度感應器的實體 UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer]; accelerometer.updateInterval = 1.0 / 30; accelerometer.delegate = self; // 球的移動速度 ballDX = 0.0f; ballDY = 0.0f; }
  • 46. - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration { // 低階篩選程序 gx = acceleration.x * RATIO + gx * (1.0-RATIO); gy = acceleration.y * RATIO + gy * (1.0-RATIO); gz = acceleration.z * RATIO + gz * (1.0-RATIO); // ⾼高階篩選程序 ViewController.m (2/2) UIAccelerationValue ax, ay, az; ax = acceleration.x - gx; ay = acceleration.y - gy; az = acceleration.z - gz; // 速度更新 ballDX += gx; ballDY -= gy; if(ballDX > MAX_SPEED) ballDX = MAX_SPEED; if(ballDX < -MAX_SPEED) ballDX = -MAX_SPEED; if(ballDY > MAX_SPEED) ballDY = MAX_SPEED; if(ballDY < -MAX_SPEED) ballDY = -MAX_SPEED; // 更新座標 float newX = imageView.center.x + ballDX; float newY = imageView.center.y + ballDY; imageView.center = CGPointMake(newX, newY); // 若超出畫⾯面外,返回初始位置 if(newX<-BALL_SIZE/2 || newX>320+BALL_SIZE/2 || newY<-BALL_SIZE/2 || newY>480+BALL_SIZE/2) { imageView.center = CGPointMake(160, 240); ballDX = 0.0f; ballDY = 0.0f; } // 顯⽰示 display.text = [NSString stringWithFormat:@"X:%fnY:%fnZ:%fnnnX:%fnY:%fnZ:%fn", gx, gy, gz, ax, ay, az]; }
  • 47. Project QV025 加速度感測器 偵測⼿手機的搖動 本範例需在實機 上才能執⾏行
  • 48. ViewController.h #import <UIKit/UIKit.h> @interface ViewController : UIViewController <UIAccelerometerDelegate> { IBOutlet UILabel *display; UIAccelerationValue gx, gy, gz; BOOL shaking; } @end
  • 49. ViewController.m (1/2) #import "ViewController.h" #define SHAKE_AX 1.5 @implementation ViewController - (void)loadView { [super loadView]; UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer]; accelerometer.updateInterval = 0.1; accelerometer.delegate = self; } // 省略部分程式 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { shaking = NO; display.text = @"搖"; } @end
  • 50. ViewController.m (2/2) - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration { // 低階篩選程序 (重⼒力加速度) gx = acceleration.x * 0.1 + gx * (1.0-0.1); gy = acceleration.y * 0.1 + gy * (1.0-0.1); gz = acceleration.z * 0.1 + gz * (1.0-0.1); // ⾼高階篩選程序 (瞬間重⼒力加速度) UIAccelerationValue ax, ay, az; ax = acceleration.x - gx; ay = acceleration.y - gy; az = acceleration.z - gz; // 只要瞬間加速度超過預設⾨門檻值就搖晃 if(!shaking && (ax>SHAKE_AX || ax<-SHAKE_AX)) { shaking = YES; display.text = @"!!!爆炸!!!"; } }
  • 52.
  • 53. 範例觀摩:Erica_Gyro - 須在實機上執⾏行 - CoreMotion framework
  • 55. Project QV173 相機擷取 相⽚片存檔 此程式需於實機上執⾏行
  • 56. ViewController.h #import <UIKit/UIKit.h> @interface ViewController : UIViewController <UIImagePickerControllerDelegate, UINavigationControllerDelegate> { } 影像擷取代理協定 // 顯⽰示拍攝後影像 view @property (nonatomic, retain) IBOutlet UIImageView *imageView; // 儲存按鈕 @property (nonatomic, retain) IBOutlet UIBarButtonItem *saveImageButton; // 在相機上顯⽰示拍攝畫⾯面 - (IBAction) showCameraAction:(id)sender; // 把拍攝後影像儲存到 iPhone 相簿 - (IBAction) saveImageAction:(id)sender; @end
  • 58. ViewController.m (1/2) - (IBAction) showCameraAction:(id)sender { UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init]; imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera; imagePickerController.delegate = self; imagePickerController.allowsEditing = YES; [self presentModalViewController:imagePickerController animated:YES]; } - (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { UIImage *image = [info objectForKey:UIImagePickerControllerEditedImage]; imageView.image = image; saveImageButton.enabled = YES; [self dismissModalViewControllerAnimated:YES]; }
  • 59. ViewController.m (2/2) - (IBAction) saveImageAction:(id)sender { UIImage *image = imageView.image; UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil); saveImageButton.enabled = NO; }