私が選択したアプローチは、独自の 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