ラベル Swift の投稿を表示しています。 すべての投稿を表示
ラベル Swift の投稿を表示しています。 すべての投稿を表示

2015年5月6日水曜日

Core Animation Lesson.(カスタム描画/Lesson1-7)

Core Animation Lesson.(Lesson1-7)
カスタム描画.(Lesson1-7)

CALayerのcontentsプロパティを設定するとこだけが背景画像を描画する方法では有りません。UIViewのdrawRectメソッドを実装する事でCoreGraphicsやUIKitを利用し、ダイレクトに背景画像を描画することができます。drawRectメソッドにはデフォルト実装が有りませんが、Viewが最初に表示された時に一度呼び出され、以降は更新が必要になった場合に自動的に呼び出されます。明示的に再描画が必要な時はsetNeedsDisplayを呼び出す事で再描画が行われますので、再描画したいからといってコード内からdrawRectメソッドを直接呼び出してはいけません。

drawRectメソッドの実装

UIViewクラスを継承した新しいクラスを作成し、Storyboard上でViewを配置しCustomクラスとして新しく作成したクラスを指定します。

図. カスタムクラスの設定
drawRectメソッドでは、青色に塗りつぶされた楕円を描画するコードになっています。(以下コード)
class Lesson1_7View: UIView {

    // custom draw
    override func drawRect(rect: CGRect) {
        // get context
        let context: CGContext! = UIGraphicsGetCurrentContext()
        
        // draw with context
        // set fill color
        CGContextSetFillColorWithColor(context, UIColor.blueColor().CGColor)
        // draw ellpise in rect
        CGContextFillEllipseInRect(context, rect)

    }
}
図. カスタム描画
独自に追加したレイヤへのカスタム描画

CALayerにはdelegateプロパティが存在します。それがCALayerDelegateで、displayLayerとdrawLayer メソッドが定義されています。iOSの場合はUIViewを新たに作成するとCALayerも必ず生成されます。この予め生成されているCALayerの場合はUIView側でCALayerDelegateが実装されているため、改めて個別に実装する必要はありません。素直にdrawRectメソッドを実装すれば良いでしょう。

逆に新たに作成したCALayerでカスタム描画したい場合にCALayerDelegateを実装する必要があります。因みに、CALayerDelegateはCALayerクラスにNSObjectのエクステンション(カテゴリ)で定義されており、リファレンスにはInformal Protocolと表現されています。ですので、明示的にCALayerDelegateを採用するコード(クラス定義)を書く必要は無いようです。

extension NSObject {
    
    /* If defined, called by the default implementation of the -display
     * method, in which case it should implement the entire display
     * process (typically by setting the `contents' property). */
    
    func displayLayer(layer: CALayer!)
    
    /* If defined, called by the default implementation of -drawInContext: */
    
    func drawLayer(layer: CALayer!, inContext ctx: CGContext!)
    
    /* Called by the default -layoutSublayers implementation before the layout
     * manager is checked. Note that if the delegate method is invoked, the
     * layout manager will be ignored. */
    
    func layoutSublayersOfLayer(layer: CALayer!)
    
    /* If defined, called by the default implementation of the
     * -actionForKey: method. Should return an object implementating the
     * CAAction protocol. May return 'nil' if the delegate doesn't specify
     * a behavior for the current event. Returning the null object (i.e.
     * '[NSNull null]') explicitly forces no further search. (I.e. the
     * +defaultActionForKey: method will not be called.) */
    
    func actionForLayer(layer: CALayer!, forKey event: String!) -> CAAction!
}
コード. CALayerクラス内にあるエクステンション定義(Swift)

CALayerはdelegateが設定されているかを調べます。そして、設定されている場合はdisplayLayerメソッドが実装されているか確認します。実装されている場合は呼び出しを行い、もしdisplayLayer実装されていなかった場合はさらにdrawLayerメソッドが実装されているか確認し、実装されている場合はdrawLayerメソッドを呼び出します。
要するに、displayLayer → drawLayer の順で呼び出されるわけですが、displayLayerが実装されている場合はdrawLayerが実装されていても、呼び出されませんので注意が必要です。

新たにCALayerを作成して、そのレイヤをカスタム描画してみます。新たに作成したレイヤには赤色の円を描いています。

図. 独自に追加したレイヤのカスタム描画
class Lesson1_7ViewController: UIViewController {
    @IBOutlet weak var myView: Lesson1_7View!
    
    private var newLayer: CALayer!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        
        // create new layer
        newLayer = CALayer()
        newLayer.frame = CGRectMake(0, 0, 100, 100)
        newLayer.contentsScale = UIScreen.mainScreen().scale
        // set delegate
        newLayer.delegate = self
        
        // add new layer to uiview hosted layer
        myView.layer.addSublayer(newLayer)
        
        // display new layer
        newLayer.display()
    }
    
    override func viewDidDisappear(animated: Bool) {
        // clean up
        newLayer.delegate = nil
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

/***
    override func displayLayer(layer: CALayer!) {
        //
    }
***/
    
    override func drawLayer(layer: CALayer!, inContext ctx: CGContext!) {
        NSLog("perform drawLayer.")
        //
        CGContextSetFillColorWithColor(ctx, UIColor.redColor().CGColor)
        CGContextFillEllipseInRect(ctx, layer.frame)
    }
}

以下コードが新しいレイヤを作成し、delegateを設定しています。

// create new layer
newLayer = CALayer()
newLayer.frame = CGRectMake(0, 0, 100, 100)
newLayer.contentsScale = UIScreen.mainScreen().scale

// set delegate
newLayer.delegate = self

そして、以下がカスタムコード描画部分です。CGContextオブジェクトが引数にあるので、drawLayerメソッドの方を実装しています。drawLayerを呼び出したいため、displayLayerメソッドはコメントアウトにしています。

override func drawLayer(layer: CALayer!, inContext ctx: CGContext!) {
    NSLog("perform drawLayer.")
    //
    CGContextSetFillColorWithColor(ctx, UIColor.redColor().CGColor)
    CGContextFillEllipseInRect(ctx, layer.frame)
}



今回使用したサンプルプログラムはGithub上のCoreAnimationLessonに置いています。


AD.

2015年4月12日日曜日

Core Animation Lesson.(Lesson1-4〜)

前回(Core Animation Lesson1(Lesson1-1〜)) から引き続きCALayerのプロパティについて調査しました。

contentsScaleプロパティ(CALayer)

本プロパティ値はレイヤ上の背景画像とView上のピクセルサイズ比率を定義するプロパティです。要するにRetinaディスプレイか否かを設定します。contentsScaleの値は通常のディスプレイで1.0を指し、Retinaディスプレイの場合は2.0となります。デフォルト値は1.0です。 この値は以下の様にUIScreenクラスから取得するのが一般的のようです。

    // set contentsScale to The Retina value
    myView.layer.contentsScale = UIScreen.mainScreen().scale

但し、CALayerのcontentsGravityにfill/fit系の拡大縮小のオプションを指定している場合、contentsScaleの値意味を持たなくなるので、注意が必要です。

表. CALayerのcontentsScaleの値について
contentsScale 概要
1.0 1Pointが1Pixcelの通常ディスプレイを指す。
2.0 1Pointが2x2(4Pixcels)のRetinaディスプレイを指す。


下の表示イメージは同一画像をRetina/非Retinaで表示してみた例です。
図. Retinaディスプレイ[←左図](contentsScale=2.0)と
非Retinaディスプレイ[右図→](contentsScale=1.0)
masksToBoundsプロパティ(CALayer)

Viewよりも大きい画像はViewからはみ出して表示されてしまいますが、CALayerのmasksToBoundsプロパティを設定することで抑止できます。値はBool値でtrueが設定されるとマスクされます。また、このプロパティはUIViewのclipesToBindsプロパティと同等の機能となります。

図. masksToBounds=false

図. masksToBounds=true


以下、サンプルコードです。SegmentedControlボタンでcontentsScale, SwitchボタンでmasksToBoundsのオンオフを設定しています。

import UIKit

class Lesson1_4ViewController: UIViewController {

    @IBOutlet weak var myView: UIView!
    @IBOutlet weak var mySegmentedControl: UISegmentedControl!
    @IBOutlet weak var mySwitch: UISwitch!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        
        // image
        let image = UIImage(named: "chess.png")
        myView.layer.contents = image?.CGImage
        myView.layer.contentsGravity = kCAGravityCenter
        
        // set default contentsScale to The Retina value
        myView.layer.contentsScale = UIScreen.mainScreen().scale
        // set default clip setting
        myView.layer.masksToBounds = true
        
        // set action for segmented control
        mySegmentedControl.addTarget(self, action: "segmentedValueChanged:", forControlEvents: UIControlEvents.ValueChanged)
        // set action for switch
        mySwitch.addTarget(self, action: "switchValueChanged:", forControlEvents: UIControlEvents.ValueChanged)
        
        // dump contentsScale
        println("contentsScale : \(myView.layer.contentsScale)")
        println("image Scale   : \(image?.scale)")
        println("UIScreen scale: \(UIScreen.mainScreen().scale)")
        
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    
    func segmentedValueChanged(target: UISegmentedControl) {
        if (target.selectedSegmentIndex == 0) {
            myView.layer.contentsScale = 1.0
            
        } else {
            myView.layer.contentsScale = 2.0
            
        }
    }
    
    func switchValueChanged(target: UISwitch) {
        if target.on {
            myView.layer.masksToBounds = true
        } else {
            myView.layer.masksToBounds = false
        }
    }
}
contentsRectプロパティ(CALayer)

指定された範囲をクリップするイメージですが、大きな画像ファイルに小さいイメージをパックする事で、小さいイメージを個々に読み込むより、大きなファイルを一回だけ読み込ませる方が読み込み時間、使用メモリ量のパフォーマンスに優れています。ゲームの様に小さな画像を多数使用する場合にメリットが大きい様です。また、contentsRectの単位はpoint単位では無くunit coordinate単位であることにも注意が必要です。

以下の図は、1枚の画像ファイルにAとBが横並びで描画されています。その画像ファイルを1回だけ読み込み、contentsRectプロパティを利用し元画像の必要な部分(AとB)をクリッピングし縦並びで表示しています。


以下、ソースコードですが、CALayerのcontentsには元画像を設定しcontentsRectプロパティにてそれぞれ必要な領域を指定しています。contentsRectはCGRect型で指定する値はUnitCoordinate単位となります。UnitCoordinate単位については後述します。

import UIKit

class Lesson1_5ViewController: UIViewController {

    @IBOutlet weak var viewA: UIView!
    @IBOutlet weak var viewB: UIView!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        // load image once.
        let image = UIImage(named: "AB.png")
        
        // A
        viewA.layer.contents = image?.CGImage
        viewA.layer.contentsRect = CGRectMake(0, 0, 0.5, 1.0)
        
        // B
        viewB.layer.contents = image?.CGImage
        viewB.layer.contentsRect = CGRectMake(0.5, 0, 0.5, 1.0)
        
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}
Point, Unit単位について
表. Point, Unit単位について
Coordinate Type 概要
Point Pointは仮想的なPixelであり、デバイスの解像度によって変化する。通常デバイスでは1Pointが1Pixelとなるが、Retina Display では、2x2の計4Pixelsとなる。
Unit Unit単位は0.0〜1.0まで指定可能な比率で指定する便利な指定方法で、1.0が100%のサイズを意味している。比率で指定しているため、元の画像のサイズが変更されても再調整する必要が無いのが利点。

以下図はUnit単位を表しています。右下が最大値である(1, 1)を表し、中心点は(0,5, 0,5)となります。

図. Unit単位について
contentsCenterプロパティ(CALayer)

このプロパティは、プロパティ名から想像される機能と異なり、イメージの伸縮エリアについての設定が行われます。これは、インターフェースビルダーからも設定可能な値で、デフォルト値はUnit単位で(0,0,1,1)となり全域が一様に伸縮する設定となっています。contentCenterで指定した矩形の外側はそれぞれの位置により伸縮の方向が異なります。

以下のイメージを考えてみます。分かりやすいように方眼紙のようなマス目をが描かれているイメージを描画しています。この画像イメージにcontentsCenterプロパティを指定してみます。

図(↓)contentsCenterとして(0.25, 0.25, 0.5, 0.5)を指定しました。方眼紙のイメージで分かりやすいかと思ったのですが、全然分かり難いですね。良く見てみると分かりますが、方眼紙のマス目の高さや幅ががcontentsCenterで指定した矩形内と外で異なっていることに気づくと思います。

図(↓)contentsCenterで指定した矩形枠内と外での引き伸ばしについて、赤枠は縦横均等、緑は縦、青は横、黄色は無しとなっています。

contentsCenterはViewのプロパティとしてGUIからも設定可能です。


今回使用したサンプルプログラムはGithub上のCoreAnimationLessonに置いています。


2015年3月16日月曜日

Core Animation Lesson.(Lesson1)

Core Animationに関して、画像、座標、エフェクト、トランスフォーム、アニメーション等をシリーズ化してまとめていきたいと考えています。

Core Animationとは

Core Animationと聞くと、なにかアニメーションに特化した小難しいFrameworkのような印象を受けてしまいますが、アニメーション自体はCore Animationが提供する数ある特徴の一部であり、アニメーションだけに特化したFrameworkではありません。Core Animationはビジュアルコンテンツを画面描画する機能群から構成された共通基盤で、より高速に動作するよう設計されています。

UIViewとCALayer

Core Animation はどの様にして使うのでしょうか。それは、UIViewクラスで既に使用されています。 UIViewは、画像やテキスト、動画等のコンテンツの描画、タッチやジェスチャー入力に対応するクラスで、subviewとして子のViewを階層構造で管理しています。加えて、Core Graphicsベースの描画、アファイン変換(回転や拡大縮小)と簡単なアニメーションをサポートします。それら機能はCore AnimationのCALayerというクラスにより提供されています。

CALayerはUIViewととても良く似たコンセプトで設計されています。UIViewは矩形のオブジェクトでViewを階層構造で管理可能です。同様にCALayerも矩形オブジェクトであり、Layer自身に子のLayerをsublayersとして追加することが可能で親子関係を構築する事が出来ます。

Viewの階層構造イメージ図(View Debuggingしただけですが)

CALayerがUIViewと大きく異なっている点は、CALayer自身はレスポンダチェインに属さないために、タッチイベントを処理出来ないことに加えて、主に以下の特徴が挙げられます。

CALayerの主な特徴
  • ドロップシャドウ、角丸、カラードボーダー
  • 3D座量変換、ポジショニング
  • アルファマスク
  • マルチステップ、非連続的なアニメーション
※これら機能は改めて紹介したいと思います。
背景描画について(Lesson1)

CALayerを使用した背景色・背景画像の表示と、背景画像の見せ方(表示位置・拡大/縮小)に関するUIView及びCALayerのプロパティ値について。

単色背景の描画(Lesson1-1)

それでは、CALayerを使用して背景を描画してみましょう。UIViewを生成すると、iOSの場合デフォルトで必ず1つCALayerが生成されます。そのCALayerは使用せずに、新たに一つCALayerを生成して描画してみます。

青色の固定サイズの矩形を明示的に新しいCALayerを作成して、青色の背景色を設定します。CALayerのaddSublayerメソッドで新しいLayerを追加します。 サンプル実装ではUIVIew を1つ追加し、その上に描画します。

import UIKit

class Lesson1_1ViewController: UIViewController {
    @IBOutlet weak var myView: UIView!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // create new layer
        let myLayer = CALayer()
        myLayer.frame = CGRectMake(10, 10, 200, 200)
        myLayer.backgroundColor = UIColor.blueColor().CGColor

        // add new layer to backing layer
        myView.layer.addSublayer(myLayer)
        
    }
}

CALayerのbackgroundColorプロパティはUIViewクラスのそれがUIColor?型であるのと違い、CGColor!型であることに注意して下さい。

画像の描画(Lesson1-2)

それでは簡単な画像を描画してみます。画像はUIImageのインスタンスを作成し、そのCGImageプロパティ値をCALayerのcontentsプロパティへ設定しているだけです。Lesson1-1と違ってCALayerはUIViewで暗黙的に作成されたCALayerを使用しています。このレイヤはUIViewクラスのlayerプロパティで参照することが出来ます。因みに、画像はチェスの駒です。

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // initialize segmented control
        mySegmentedControl.addTarget(self, action: "segmentedValueChanged:", forControlEvents: UIControlEvents.ValueChanged)


        // image content
        let image = UIImage(named: "chess.png")
        
        // set image to layer contents
        myView.layer.contents = image?.CGImage
        
    }

残念なことに、よく見てみると駒が少し太って表示されていることに気付くと思います。 画像を枠内にどのように表示するかはUIViewクラスのcontentModeプロパティで設定することが出来ます。この値は、UIViewContentMode列挙型で定義されていて、デフォルトはScaleToFillとなっているため画面一杯に表示されることになります。正しい比率を維持したまま画面に表示するにはScaleAspectFitを設定すると良いでしょう。

myView.contentMode = UIViewContentMode.ScaleAspectFit
枠内にフィットするように画像サイズを自動調整(アスペクト比は維持)

UIViewContentModeの各値は以下の様に定義されています。詳細はドキュメントを参照下さい。

enum UIViewContentMode : Int {
    case ScaleToFill    // default 
    case ScaleAspectFit // 枠内にフィットするように自動調整(同アスペクト比)
    case ScaleAspectFill// 枠内を埋めるように自動調整(同アスペクト比)
    case Redraw
    case Center
    case Top
    case Bottom
    case Left
    case Right
    case TopLeft
    case TopRight
    case BottomLeft
    case BottomRight
}
UIViewContentMode.ScaleAspectFill
UIViewContentMode.Center
UIViewContentMode.Bottom
CALayerによる画像サイズ調整(Lesson1-3)

Lesson1-2ではUIViewクラスのcontentModeプロパティにより画像表示を調整しましたが、CALayerクラスにも同様のプロパティ値が存在します。それが、contentsGravityプロパティです。 contentsGravityはNSString型で定義されています。 正しい比率を維持したまま画面に表示するにはkCAGravityResizeAspectを指定します。

let kCAGravityCenter: NSString!
let kCAGravityTop: NSString!              // NOTICE!
let kCAGravityBottom: NSString!           // NOTICE!
let kCAGravityLeft: NSString!
let kCAGravityRight: NSString!
let kCAGravityTopLeft: NSString!
let kCAGravityTopRight: NSString!
let kCAGravityBottomLeft: NSString!
let kCAGravityBottomRight: NSString!
let kCAGravityResize: NSString!           // default
let kCAGravityResizeAspect: NSString!     // 枠内にフィットするように自動生成(同アスペクト比)
let kCAGravityResizeAspectFill: NSString! // 枠内を埋めるように自動調整(同アスペクト比)

しかし、kCAGravityTop, kCAGravityBottom を指定すると表示が上下逆になることに気付きます。これはiOSとOS XによるデフォルトのY軸の向きが異なることが原因で、iOSの場合は左上、OS Xの場合は左下が起点となります。 geometryFlippedプロパティをtrueに設定すれば思った通りの結果になるはずです。

iOS/OS XのY軸向きの違い

続きは次回。次回はCALayerのプロパティであるcontentsScale/masksToBounds/contentsRect/contentsCenter について調査したいと考えています。

説明に使用したサンプル・アプリケーションはGitHub上のCoreAnimationLessonとして配置していますので、参考にどうぞ。今後CoreAnimationに関するサンプルは本リポジトリ上に実装していく予定です。


2014年9月16日火曜日

UITableViewのセルの高さを動的に計算するSelf-Sizing Cellsを試してみた(iOS8, Swift)

はじめに
UITableviewCellの高さを動的に変更する実装はiOS7の頃(?)から可能で、iOS8では実装が簡略されてさらにパフォーマンスが高いよといったお話です。
どういう点が簡略化されたの?
iOS7では主に以下の実装が必要でした。
  1. AutoLayoutを有効にしてConstraintsを設定
  2. tableView:heightForRowAtIndexPath: メソッド実装によるセルの高さ計算
  3. tableView:cellForRowAtIndexPath: メソッド実装
iOS8の場合、 2番目の高さを計算する処理がまるっと省略可能で、おまじない程度の設定で済みます。
Constraintsの追加と設定(AutoLayout)
本例ではUITableViewControllerとして実装されたUITableVivew及びUITableViewCellのContentViewにLabelを一つ配置しています。 まずはLabelのConstraintsを追加していきます。

まずはUITableviewControllerの配置。
Cell上へラベルの配置。
Cell上のContentViewにLabelを一つ配置しています。
Constraintsを追加していきます。Labelの上下左右のマージンを設定します。
ラベルは複数行を許可するためLinesの値を0に設定しておく必要があります。
全体的な構成はこんな感じ。
UITableViewCellは独自のカスタムクラスを設定しておき、ラベルのアウトレットの作成をしておきます。
rowHeightの設定
tableViewのプロパティであるrowHeight及びestimatedRowHeightの設定を行います。 以下、UITableViewControllerの実装クラスです。
class TableViewController : UITableViewController {
    
    override func viewDidLoad() {
        //
        super.viewDidLoad()
        
        //initialize
        tableView.estimatedRowHeight = 60
        tableView.rowHeight = UITableViewAutomaticDimension
        
    }
    
    //MARK: implementation of uitableviewcontroller datasources
    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }
    
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 5
    }
    
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        //
        let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as CustomCell
        
        //dummy text
        var dummyString = "01234567890"
        for i in 0...indexPath.row {
            dummyString += dummyString
        }
        //set text
        cell.customLabel.text = "index : \(indexPath.row), dummyString : \(dummyString)"

        return cell
    }
}
おまじないはviewDidLoadメソッド内で実装している以下の箇所
tableView.estimatedRowHeight = 60
tableView.rowHeight = UITableViewAutomaticDimension
tableView.rowHeight = UITableViewAutomaticDimension
の設定が自動設定を表しています。estimateRowHeightは設定することでスクロール中のパフォーマンス向上につながるらしいです。
tableView:cellForRowAtIndexPath: メソッド実装
rowが増すごとに表示文字列を増やしているダミー処理がありますが、特に通常と変わった実装はありません。
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        //
        let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as CustomCell
        
        //dummy text
        var dummyString = "01234567890"
        for i in 0...indexPath.row {
            dummyString += dummyString
        }
        //set text
        cell.customLabel.text = "index : \(indexPath.row), dummyString : \(dummyString)"

        return cell
    }
実装結果
実行イメージ。
もし、tableView.rowHeight = UITableViewAutomaticDimension の設定を行わないと以下のようになります。
コードの詳細はGitHubを参照して下さい。
https://github.com/takuran/SelfSizingCellExample
参考:What's New in Table and Collection Views(https://developer.apple.com/videos/wwdc/2014/)
※上記参考先リンクはiOS Developer 登録していないと参照出来ないかも。スミマセン。

2014年9月8日月曜日

Swift環境からObjective-Cで書かれたCocoaPodsを使用する
(SwiftでFMDBを使う)

Swift環境からObjective-Cで書かれたCocoaPodsのライブラリを利用してみる
ライブラリはFMDBを取り込んで、FMDBを使用した簡単なプログラムをSwiftを用いて作成します。
空プロジェクトの作成
まずは、空プロジェクトを作成し、そしてすぐに閉じます。CocoaPodsでFMDBを取り込むプロジェクトファイルだけを前もって作成します。

※因みに本サンプルはXcode6 beta7にて作成しています。
podfileの作成とインストール
podfileの内容を以下のようにして作成したプロジェクトの直下に作成し、
pod 'FMDB'
以下コマンドを実行してインストールを実行。
% pod install
インストールしたら、作成されたワークスペース(プロジェクトファイルじゃないです)を開きます。 下記の様にコマンドラインから起動しても良いですし、FinderからXXX.xcworkspaceファイルをダブルクリックしても良いです。
% open XXX.xcworkspace
ワークスペースを起動したら、以下のようにPodsプロジェクトが作成されていることを確認して下さい。
※CocoaPodsは既にインストール済みを前提とします。CocoaPodsのインストールやそのた詳細についてはCOCOAPODSを参照。

Bridging Headerの作成
Objective-CをSwift環境から利用するにはBridging Headerを作成する必要があります。
このヘッダにSwift環境で使用するObjective-Cのヘッダファイルを記載することになります。
Bridging-Headerは、
1)仮のObjective-Cのファイルを作成することで自動作成、自動設定する方法(自動生成)
2)個別に作成し設定する方法(独自作成)
があります。
Bridging Headerを自動生成する場合は
Objective-Cのファイルを生成します。 Xcode menu > File > New > File... を選択しファイル新規作成します。 以下の様に、Objective-C Fileを選択しNextを押下。
ファイル名は後ほど削除するので、何でも良いです。
すると、以下の様に bridging header を作成するか問われるのでYESを押下します。
以下の様に bridging headerが作成されます。
以上で完了です。後はObjective-Cのヘッダファイルをbridging headerに記載するのみです。 FMDBの場合は以下のようにすれば良いでしょう。
//
//  Use this file to import your target's public headers that you would like to expose to Swift.
//
#import "FMDatabase.h"
作成したdummy.mファイルは削除して構いません。
Bridging Headerを独自に作成、設定する場合は
まずはbridging headerを作成します。 ファイル名はなんでも良いですが、bridging headerと分かるようにしましょう。
作成したら、BuildSettingを変更します。作成したプロジェクトを選択して、Swift Conpiler - Code Generation の設定項目値の Objective-C Bridging Header の項目を編集します。
ヘッダの内容は自動設定の時と同じです。自前でヘッダを作成すると#ifdef/#endifが自動挿入されますが、特に削除して問題無いでしょう。(自動作成時に存在しなかったので)
//  Bridging-Header.h
//  UsingCocoaPodsInSwift
//
#import "FMDatabase.h"

以上で、準備は終わりです。
SwiftからFMDBのメソッド呼び出し
あとはSwiftでコードが書いていくだけです。FMDBが提供しているメソッドの呼び出しはSwift言語仕様に変換されて呼び出すことになりますが、Xcodeのコード補完の機能があるので、メソッド名さえ分かっていればそれほど難しくはないでしょう。
抜粋しますが、FMDBに関するメソッドとして、初期化と更新クエリの呼び出し箇所を載せておきます。詳細は後述するGitHub上のソースコードを参照下さい。

FMDBインスタンス生成
        m_db = FMDatabase(path:m_dbPath)
トランザクションを開始してインサート処理
    func createNewContent(content:String) -> Bool {
        if m_db.goodConnection() {
            m_db.beginTransaction()
            m_db.executeUpdate("insert into memo (contents, 'update') values (?, ?)", withArgumentsInArray: [content, NSDate()])
            m_db.commit()
            //OK
            return true
        }
        //FAIL, database not opend.
        return false;
    }
詳細はGitHubに上げていますので、適宜参照して下さい。
https://github.com/takuran/UsingCocoaPodsInSwift
以下画面サンプル。