Как реализовать пользовательское действие UIDynamicBehavior

Я искал пример, показывающий, как реализовать пользовательский UIDynamicBehavior в динамике UIKit. Все учебные пособия и примеры показывают только, как собрать UIDynamicBehavior, используя примитивы (столкновение, гравитация, прикрепление, толчок, привязка и т. Д.)

В моем приложении некоторые виды плавают по экрану (используя динамику), и я хочу, чтобы они исчезали, когда они перекрывают другие стационарные виды. Для этого я хотел проверить наложение в методах делегатов UIDynamicAnimator и UICollisionBehavior, но, к сожалению, эти методы не обеспечивают достаточной степени детализации, чтобы выполнить необходимые мне тесты.

РЕДАКТИРОВАТЬ: очевидно, мне пришлось подождать день, прежде чем ответить на свой вопрос (новый пользователь), поэтому мое решение опубликовано ниже в качестве ответа сейчас.

1 ответ

Решение

Подход, который я выбрал, состоял в том, чтобы разработать свой собственный класс 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
Другие вопросы по тегам