Core Graphicsでつくる自作UIコンポーネント入門

18,298 views

Published on

Published in: Technology
2 Comments
55 Likes
Statistics
Notes
No Downloads
Views
Total views
18,298
On SlideShare
0
From Embeds
0
Number of Embeds
1,881
Actions
Shares
0
Downloads
129
Comments
2
Likes
55
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Core Graphicsでつくる自作UIコンポーネント入門

    1. 1. CoreGraphicsでつくる自作UIコンポーネント入門DOTAPON Software@cocoponhttp://dotapon.sakura.ne.jp
    2. 2. cocoponって誰ですか @cocopon デザイナに憧れる ホビープログラマですWindows用の Mac用の iPhone用の ゲームとか オフラインブログとか クミタテ電卓とか Osciroi Calqum
    3. 3. 今日のお題…の前に 前回発表のハイライト …救世主があらわれた!
    4. 4. 今日のお題…の前にXVim!! Vimmerは今すぐダウンロードすべし https://github.com/JugglerShu/XVim 見覚えのある「コマンドライン」が! これで勝てる!!!
    5. 5. 今日のお題 ステキなUIのアプリ、たくさんありますよねPath Twittelator Neue Paylog
    6. 6. 今日のお題 どれもUIKit標準では用意されていない…ど う や って 作 ってるん だろう?
    7. 7. 今日のお題 オープンソースの フキダシUIコンポーネント 「CMPopTipView」を題材に、 CoreGraphicsを使った UIコンポーネント自作の 基礎を見てみよう
    8. 8. 準備OK?https://github.com/chrismiles/CMPopTipView
    9. 9. 読むぞ!CMPopTipView
    10. 10. 画像リソースは…ありません! CMPopTipView.hと CMPopTipView.mのみ どうやって描いてるの?
    11. 11. 描画処理のキホン [UIView drawRect: ... ] 内で… 1. 点をつないで「パス」をつくる2. パスを塗ったり、影をつけたりする
    12. 12. なぜ画像を使わないのか メリットが大きいから! デメリットもある★   実行時のカスタマイズが容易 ★   コードで描くので少し面倒 色とか、角丸のサイズとか… 複雑な描画は心が折れる★   画像リソースがないので、 その分サイズが小さくなる
    13. 13. 描画処理の準備 UIGraphicsGetCurrentContextCGContextRef c = UIGraphicsGetCurrentContext(); 描画するときに必要です
    14. 14. パス用の変数を用意する CGPathCreateMutable CGMutablePathRef bubblePath =CGPathCreateMutable(); “Mutable” は「変更可能」という意味 少しずつパスを作っていける
    15. 15. フキダシの方向で処理を分ける if (pointDirection == PointDirectionUp) { ... } else { ... }PointDirectionUp PointDirectionDown 今回はこちら側を読み進めます
    16. 16. パスの始点を決める CGPathMoveToPoint CGPathMoveToPoint(bubblePath, NULL, targetPoint.x, targetPoint.y);
    17. 17. パスに直線を追加 CGPathAddLineToPoint CGPathAddLineToPoint(bubblePath, NULL, targetPoint.x-pointerSize, targetPoint.y-pointerSize);
    18. 18. パスに角丸を追加 CGPathAddArcToPointCGPathAddArcToPoint( bubblePath, NULL, bubbleRect.origin.x, bubbleRect.origin.y + bubbleRect.size.height, bubbleRect.origin.x, bubbleRect.origin.y + bubbleRect.size.height - cornerRadius, cornerRadius); CGPathAddArcToPoint( 追加するパス, NULL, 角のX, Y, 終点のX, Y, 角丸の半径)
    19. 19. 残りの角丸を追加 同じ要領で残りも追加する
    20. 20. パスを閉じる CGPathCloseSubpath CGPathCloseSubpath(bubblePath);これで1周して、フキダシ形のパスが完成!
    21. 21. パスを描く、その前に CGContextSave(/Restore)GStateCGContextSaveGState(c);CGContextAddPath(c, bubblePath);CGContextSetShadow(c, CGSizeMake(0, 3), 5);CGContextSetRGBFillColor(c, 0.0, 0.0, 0.0, 0.9);CGContextFillPath(c);CGContextRestoreGState(c); コンテキストに設定した情報 (描画色やパスなど)を保存/復元 描画処理のカタマリごとに囲って、他のカタマリに影響が出ないように書くのがベター
    22. 22. 影を描く CGContextSetShadow, ~FillPathCGContextSaveGState(c);CGContextAddPath(c, bubblePath);CGContextSetShadow(c, CGSizeMake(0, 3), 5);CGContextSetRGBFillColor(c, 0.0, 0.0, 0.0, 0.9);CGContextFillPath(c);CGContextRestoreGState(c); CGContextSetShadow( コンテキスト, 影の位置のずれ, ぼかし量) 設定した色・パスの形で影を描画
    23. 23. 背景グラデーションを準備する CGColorGetComponents int numComponents = CGColorGetNumberOfComponents([backgroundColor CGColor]); const CGFloat *components = CGColorGetComponents([backgroundColor CGColor]); if (numComponents == 2) { red = components[0]; green = components[0]; blue = components[0]; alpha = components[1]; } else { red = components[0]; green = components[1]; blue = components[2]; 背景色の色要素を分解して red, green, blue, alpha を取得
    24. 24. 背景グラデーションを準備する CGFloat colorList[] = { //red, green, blue, alpha red*1.16+colourHL, green*1.16+colourHL, blue*1.16+colourHL,alpha, red*1.16+colourHL, green*1.16+colourHL, blue*1.16+colourHL,alpha, red*1.08+colourHL, green*1.08+colourHL, blue*1.08+colourHL, 1.16倍: 明るく 1.16倍: 明るく 1.08倍: ちょっと明るく 背景色 背景色
    25. 25. 背景グラデーションを作成する CGGradientCreateWithColorComponentsCGFloat bubbleMiddle = (bubbleRect.origin.y + bubbleRect.size.height / 2)) / self.bounds.size.height;CGFloat locationList[] = {0.0, bubbleMiddle - 0.03, bubbleMiddle, bubbleMiddle + 0.03, 1.0};...myGradient = CGGradientCreateWithColorComponents( myColorSpace, colorList, locationList, locationCount); 0.0 bubbleMiddle ±0.03 1.0
    26. 26. 背景を塗る CGContextDrawLinearGradient CGContextAddPath(c, bubblePath); CGContextClip(c); ... CGPoint startPoint, endPoint; startPoint.x = 0; startPoint.y = 0; endPoint.x = 0; endPoint.y = CGRectGetMaxY(self.bounds); CGContextClipでフキダシ型にクリップしてから塗る
    27. 27. 作ったものは、解放しよう CG*Release CGGradientRelease(myGradient); CGColorSpaceRelease(myColorSpace); ... CGPathRelease(bubblePath);Create~ な関数で作ったものは、解放しないとリークするよ 「ちゃんと解放してね」ドキュメントにしっかりと書いてあります
    28. 28. 文字を描く [NSString drawInRect: ... ][textColor set];CGRect textFrame = [self contentFrame];[self.message drawInRect:textFrame withFont:textFont lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentCenter];
    29. 29. 自作の幅をさらに広げる キーワード
    30. 30. CoreAnimation 複雑なアニメーション CAKeyframeAnimationで Path風のメニューを実現https://github.com/levey/AwesomeMenu/
    31. 31. CoreAnimation 3次元の変形 CATransform3Dで Clear風の折り畳みを実現https://github.com/mpospese/MPFoldTransition/
    32. 32. 作りはじめる、その前に
    33. 33. そのコンポーネント、もうあるかもよ 車輪の再発明はもったいない まずはネットで探してみよう Cocoa Controls http://cocoacontrols.com/
    34. 34. 作り終わった、そのあとは
    35. 35. 世界に公開してみよう 受けた恩恵は還元して、 「みんなでハッピー」を目指そう github.com
    36. 36. 自分も公開してみました https://github.com/cocopon/CQMFloatingController クミタテ電卓Calqumの 定数選択用コンポーネントを 整理・切り出し CoreGraphics使用、画像不使用 今回の内容の復習に最適!
    37. 37. 自分も公開してみました https://github.com/cocopon/CQMFloatingController クミタテ電卓Calqumの 定数選択用コンポーネントを 整理・切り出し CoreGraphics使用、画像不使用 今回の内容の復習に最適!
    38. 38. CoreGraphicsでつくる自作UIコンポーネント入門 DOTAPON Software @cocopon http://dotapon.sakura.ne.jp

    ×