4

UIKit ダイナミクスでカスタム UIDynamicBehavior を実装する方法を示す例を探していました。すべてのチュートリアルと例は、プリミティブ (衝突、重力、アタッチメント、プッシュ、スナップなど) を使用して UIDynamicBehavior を組み立てる方法のみを示しています。

私のアプリでは、いくつかのビューが (ダイナミクスを使用して) 画面の周りに浮かんでいて、他の固定ビューと重なったときにそれらを非表示にしたいと考えています。これを行うために、UIDynamicAnimator および UICollisionBehavior デリゲート メソッドのオーバーラップをテストしたかったのですが、残念ながら、これらのメソッドは、必要なテストを実行するのに十分な粒度を提供しません。

編集:どうやら私は自分の質問(新しいユーザー)に答える前に1日待たなければならなかったので、私の解決策は今答えとして以下に掲載されています。

4

1 に答える 1

7

私が選択したアプローチは、独自の UIDynamicBehavior クラスを開発し、それをアニメーターに追加することでした。これにより、フローティング ビューが固定ビューに重なると、フローティング ビューが消えるようになりました。

以下のサンプル コードは、独自の UIDynamicBehavior クラスを記述して、独自の動作を UIDynamicAnimator にプラグインする方法を示しています。UISinkBehavior クラスを呼び出しました。これは、ビューが「シンクホール」の上を移動するときにビューを「沈める」ためです。

// UISinkBehavior.h
#import <UIKit/UIKit.h>

@protocol UISinkBehaviorDelegate <NSObject>
- (void)sunk:(id)item;
@end

@interface UISinkBehavior : UIDynamicBehavior
@property (weak, nonatomic) id<UISinkBehaviorDelegate> delegate;
- (id)initWithItems:(NSMutableArray*)items withSinkhole:(UIView*)sinkhole;
@end

// UISinkBehavior.m
#import "UISinkBehavior.h"

@interface UISinkBehavior ()
@property (nonatomic) NSMutableArray *items;
@property (nonatomic) id<UIDynamicItem> sinkhole;
@end

@implementation UISinkBehavior

- (id)initWithItems:(NSMutableArray*)items withSinkhole:(UIView*)sinkhole
{
    if (self = [super init])
    {
        _items = items;
        _sinkhole = sinkhole;
        // weak self ref to avoids compiler warning about retain cycles
        __weak typeof(self) ref = self;
        // this is called by the UIDynamicAnimator on every tick
        self.action = ^{
            UIView *item;
            // check each item if it overlaps sinkhole
            for (item in ref.items)
                if (CGRectIntersectsRect(item.frame, sinkhole.frame))
                {
                    // sink it (handled by delegate
                    [ref.delegate sunk:item];
                    // remove item from animation
                    [ref.items removeObject:item];
                    // remove behaviour from animator when last item sunk
                    if (ref.items.count < 1)
                        [ref.dynamicAnimator removeBehavior:ref];
                }
        };
    }    
    return self;
}
@end
于 2014-01-12T03:25:27.667 に答える