Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

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

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all
  • Be the first to comment

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

×