CS193p Lecture 5

iTunes U スタンフォード大学のiOSアプリ開発講義のLecure 5(Protocols and Gestures)の講義メモです。

Autorotation

回転の制御は次のメソッドを実装することで可能。

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation {
     return UIInterfaceOrientationIsPortrait(orientation); / / only support portrait
     return YES; / / support all orientations
     return (orientation != UIInterfaceOrientationPortraitUpsideDown); / / anything but
}

向きを変えた時のViewオブジェクトの位置と伸縮具合は、struts and springで決まり、Xcodeのサイズインスペクタで設定できる。

向きが変わってもdrawRect: はコールされない。そのため位置や伸縮がstruts and springで設定されたとおりに変更されてしまう。そして、たとえアスペクト比や、相対位置をdrawRect: 以下で設定して描画していたとしてもdrawRect: はコールされないので意図しない位置に意図しないアスペクト比で描画されてしまうかもしれない。
そこで、次のプロパティを使って制御する。

@property (nonatomic) UIViewContentMode contentMode;
    (1) UIViewContentMode{Left,Right,Top,Right,BottomLeft,
                        BottomRight,TopLeft,TopRight}
        right に設定していると、向きが変わったらオブジェクトは右に押し寄せられる
    (2) UIViewContentModeScale{ToFill,AspectFill,AspectFit}
        デフォルトはToFillでアスペクト比関係なしに、フィットするように歪んで伸縮する
    (3) UIViewContentModeRedraw  // drawRect: がコールされる

UIViewの初期化

storyboardで作成したオブジェクトは、initWithFrameがコールされないので、かわりにawakeFromNibを使って初期化する。

■初期化のテンプレート

- (void)setup { ... }
- (void)awakeFromNib { [self setup]; }
- (id)initWithFrame:(CGRect)aRect {
     self = [super initWithFrame:aRect];
     [self setup];
     return self;
}

Protocols (18:00〜)

Protocolsは、ヘッダファイルで定義する。
delegate , dataSource は、たいていweakで定義される。
例)

@property (nonatomic, weak) id <UISomeObjectDelegate> delegate;

Gesture Recognizers (29:25〜)

ジェスチャの認識は、ローレベルでもできるが、簡単にパターンで認識できるようになっている。

ジェスチャ認識の実装方法

ジェスチャはViewしか認識しないので、1)Viewに対して特定のジェスチャ認識時に誰がそのハンドリングをどうやって行うかを指定する、2)View自身がジェスチャをハンドリングする、という2つの実装方法がある。
ハンドリングする場所は、画面の表示方法を変更するようなジェスチャはViewで、モデルをいじるようなジェスチャはコントローラで行うべきだろう。

実装例

コントローラからViewにジェスチャ認識を追加する例

- (void)setPannableView:(UIView *)pannableView
{
  _pannableView = pannableView;
  UIPanGestureRecognizer *pangr = [[UIPanGestureRecognizer alloc]

initWithTarget:pannableView

action:@selector(pan:)];

  [pannableView addGestureRecognizer:pangr];
}   

ジェスチャのステータス

@property (readonly) UIGestureRecognizerState state;

possible ~ 認識可能状態
recognized ~ ジェスチャを認識した
began ~ 継続するジェスチャの開始
failed ~ ジェスチャを強制的に終了させる
changed ~ 継続するジェスチャに変化があった
ended ~ 継続するジェスチャが終了
cancelled ~ 継続するジェスチャがキャンセルされた

ジェスチャのクラス

UIPanGestureRecognizer
- (CGPoint)translationInView:(UIView *)aView;  //移動距離を返す
- (CGPoint)velocityInView:(UIView *)aView;  //速度を返す
- (void)setTranslation:(CGPoint)translation inView:(UIView *)aView; //移動距離をリセット
UIPinchGestureRecognizer
    @property CGFloat scale; // readonlyではないのでリセット可能
    @property (readonly) CGFloat velocity; // 単位は毎秒
UIRotationGestureRecognizer
    @property CGFloat rotation; // readonlyではない; 単位はラジアン
    @property (readonly) CGFloat velocity; //単位はラジアン/秒
UISwipeGestureRecognizer

 次のスワイプタイプを設定して、それから状態を確認する。
    @property UISwipeGestureRecognizerDirection direction; //スワイプの向き

    @property NSUInteger numberOfTouchesRequired; //指の本数
UITapGestureRecognizer
   次のタップタイプを設定して、それから状態を確認する。
    @property NSUInteger numberOfTapsRequired; //タップの回数
    @property NSUInteger numberOfTouchesRequired; //例)2本指タップが必要?

描画アプリの実装デモ (42:41〜)

Viewに顔の絵を描いて、ピンチジェスチャでその縮尺を変更するアプリの実装デモです。

面倒な部分のコードは、時間短縮のためにコピー&ペーストされてどんどん先に進んで行くので、ビデオを見ながらコーディングしていると追いつきません。

ソースコードは公式サイトにアップされているので、講義ビデオで実装方法をなんとなくつかんで、あとで詳しくソースコードを見て確認するのが良いと思います。

■シミュレータの操作

ピンチ:シミュレータ上で、optionキーを押しながらクリックしてマウスを動かす
スワイプ:optionキーとshiftキーを押しながらクリックしてマウスを動かす

時計回りに端末を回転:command + →

反時計回りに端末を回転:command + ←

<前の記事 

電卓アプリの課題2完成    - iTunesで字幕を表示 次の記事>