5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

OSS解説 BRFlabbyTable

Posted at

BRFlabbyTable

687474703a2f2f692e696d6775722e636f6d2f304b6855684d4e2e706e67.png

グニャグニャと動くUItableViewです。(リンク先参照)
有機的な動きはSkypeなどでも取り入れられています。
フラットデザインとの相性も良く、見栄えも良いのでこれを自在に使えたらカッコイイですよね!

BRFlabbyTableはApache licenceの元で利用することが出来ます。
折角OSSなので、どのような仕組みなのか見て行きましょう。

今回はReleaseバージョンの1.0.0を利用しています。

BRMainViewController

まずはサンプルを開いて、メインのViewControllerを見てみましょう。
ここでBRFlabbyTableの使い方や構造がわかります。

まずはdelegateから。
ここで登場するdelegateは3つ
UITableViewDelegate UITableViewDataSource BRFlabbyTableManagerDelegate
です。

UITableViewDelegateUITableViewDataSourceは、別段解説する必要は無いと思います。
一点、
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
でUITableViewCellではなく、BRFlabbyTableViewCellを返している部分に注目してください。
つまり、BRFlabbyTableは独自のtableViewなのではなく、UITableViewCellによる実装で作られているということです。

そして、BRFlabbyTableManagerDelegateですが、ここでは
- (UIColor *)flabbyTableManager:(BRFlabbyTableManager *)tableManager flabbyColorForIndexPath:(NSIndexPath *)indexPath
というメソッドだけがあります。
ここでは、特定IndexPathの背景色を返します。

以上でViewController部分の説明は終わりです。
カッコイイ見た目のわりにはUITableViewの使い方を崩さずに実装でき、既存のプロジェクトのUITableView部分を入れ替えれば実装出来るという親和性の高いOSSですね。
次にいよいよソースを見て行きましょう。

BRflabbyTableのソース

BRflabbyTableの構造は大きく分けて3つ
BRFlabbyTableManager BRFlabbyTableViewCell NSIndexPath+BRFlabbyTable
です。

BRFlabbyTableViewCell

このCellはUITableViewCellを継承しており、BRFlabbyTableManagerで指定された通りに描画を行います。
その為、drawrectがソースの大半を占めています。

drawrectでの動作は大きく分けて2つ

_flabbyHighlightState == BRFlabbyHighlightStateCellTouched || !_isFlabby || (fabs(_verticalVelocity) < 1.0 && _flabbyHighlightState == BRFlabbyHighlightStateNone)

の時の動作、これは一言でいえば「静止時の動作」です。
ごちゃごちゃ条件がついていますが、しきい値やタップのステートの条件になります。

ここでしているのは簡単で

CGContextSetFillColorWithColor(ctx, [_flabbyColor CGColor]);
        CGContextFillRect(ctx, rect);

と、ただCellを塗っているだけです。

もう片方は先ほどの条件をelseした部分、つまり指を乗せたりスクロールしたりして有機的な動きをしているのを描画している部分です。

先ほど同様Cell全体を塗った上で3つの分岐をしています。


switch (_flabbyHighlightState) {
            case BRFlabbyHighlightStateCellAboveTouched:
                controlPointX1 = _touchXLocationInCell + x;
                controlPointX2 = _touchXLocationInCell + x;
                controlPointX3 = x + (w/2 + x) + (w - (w/2 + x))/2;
                controlPointX4 = (x + (w/2 + x))/2;
                controlPointY1 = HIGHLIGHT_Y_CONTROL_POINT;
                controlPointY2 = y+h+controlYOffset;
                CGContextSetFillColorWithColor(ctx, [_flabbyColorAbove CGColor]);
                CGContextFillRect(ctx, CGRectMake(x, y, w, h/2));
                break;
            case BRFlabbyHighlightStateCellBelowTouched:
                controlPointX1 = (x + (w/2 + x))/2;
                controlPointX2 = x + (w/2 + x) + (w - (w/2 + x))/2;
                controlPointX3 = _touchXLocationInCell + x;
                controlPointX4 = _touchXLocationInCell + x;
                controlPointY1 = controlYOffset;
                controlPointY2 = y+h-HIGHLIGHT_Y_CONTROL_POINT;
                CGContextSetFillColorWithColor(ctx, [_flabbyColorBelow CGColor]);
                CGContextFillRect(ctx, CGRectMake(x, y+h/2, w, h/2));
                break;
            default:
                controlPointX1 = (x + (w/2 + x))/2;
                controlPointX2 = x + (w/2 + x) + (w - (w/2 + x))/2;
                controlPointX3 = controlPointX2;
                controlPointX4 = controlPointX1;
                controlPointY1 = y+controlYOffset;
                controlPointY2 = y+h+controlYOffset;
                break;
        }

この分岐はそれぞれ
iOS Simulator Screen Shot May 7, 27 Heisei, 2.57.50 AMのコピー.png
このように指を置いているCellを中心に上下のセルの指定をしています。
ここで勘の良い人は気が付くと思いますが、このBRflabbyTableは目の錯覚が利用されているわけです。

iOS Simulator Screen Shot May 7, 27 Heisei, 2.57.50 AMのコピー.png

そう、中央のセルは決して上下にはみ出しているわけではなく上下のセルではみ出した部分を描画しているわけです。
iOS Simulator Screen Shot May 7, 27 Heisei, 3.11.26 AM.png

黄色と青の部分が上下のセルで描画されている部分です。

スクロールの際は、方向に合わせてすべてBRFlabbyHighlightStateCellAboveTouchedかBRFlabbyHighlightStateCellBelowTouchedにすればよいわけです。

描画はX1,X2,X3,X4とY1,Y2の組み合わせ4点を元に

        CGMutablePathRef path = CGPathCreateMutable();
        CGPathMoveToPoint(path, nil, x, y);
        CGPathAddCurveToPoint(path, nil, controlPointX1, controlPointY1, controlPointX2, controlPointY1, x+w, y);
        CGPathAddLineToPoint(path, nil, x+w, y+h);
        CGPathAddCurveToPoint(path, nil, controlPointX3, controlPointY2, controlPointX4, controlPointY2, x, y+h);
        CGPathCloseSubpath(path);
        CGContextAddPath(ctx, path);
        CGContextSetFillColorWithColor(ctx, [_flabbyColor CGColor]);
        CGContextFillPath(ctx);
        CGPathRelease(path);

このようなコードでカーブを描いています。

それぞれの点を描画すると以下のような位置になります。

iOS Simulator Screen Shot May 7, 27 Heisei, 3.29.16 AM.png

上下のカーブをそれぞれ2点で描いているわけです。

というわけで、BRflabbyTableの有機的なUITableViewCellは目の錯覚を利用しセルがはみ出ているように見せているというトリックでした。
また利用している描画関数もカーブ関数ぐらいなので中身を見てみると以外にも(良い意味で)シンプルな構造だったというわけです。

もっと興味のある方はBRFlabbyTableManagerNSIndexPath+BRFlabbyTableも覗いてみるといいかもしれません。
NSIndexPath+BRFlabbyTableでは前と後ろの色を取得する部分、BRFlabbyTableManagerではタップ位置を取得する部分を見ることが出来ます。

いじょ

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?