QuadCurveMenu 1.0.0

QuadCurveMenu 1.0.0

测试已测试
语言语言 Obj-CObjective C
许可证 MIT
发布最后发布2014年12月

无人认领 维护。



  • 作者:
  • Franklin Webber

QuadCurveMenu 是一个与 Path 应用程序的菜单相同风格的菜单。

expand expand-linear

custom-expand custom-selection custom-images

这是我基于 levey 的 AwesomeMenu 的分支。我提出了一项拉取请求,但这并不是原始作者的初衷。这个分支有一些显著的不同之处,我在 拉取请求 中概述了这些不同。

我真的喜欢这个菜单,并希望使用任何数据源(不仅仅是数组),更多的触摸事件,以及能够操作图像和动画的能力。我还希望菜单项能够持有一些数据对象,这样我就可以在选中时存储和检索数据,而不是依赖于索引。

最终,这是一个更模块化的库,允许您为菜单定义新功能,而无需撕裂现有库的内容。

  • 组件化成多个文件

QuadCurveMenu 被定义在多个文件中,以分离关注点并使代码更易于维护和清晰。这确实增加了当代码包含在项目中时的负担。

  • 将项目转换为 ARC

  • 示例中的 AppDelegate 不再负责菜单,并创建了一个示例视图控制器。

  • 菜单将为 willExpanddidExpandwillClosedidClose 生成委托事件。

  • 菜单在扩展之前会请求委托的 shouldExpand,在关闭之前请求 shouldClose

  • 菜单将生成触摸(didTapMenu)和长按(didLongPressMenu)事件。

  • 菜单从数据源委托中进行填充

  • 菜单由 MenuItemFactory 进行设计

  • 菜单由可定义的动画组成,用于扩展、关闭、选中、未选中

  • 菜单动画现在在其自己的独立类中

  • 菜单可以显示以径向、线性或自定义样式的菜单项

  • 菜单项将为触摸(didTapMenuItem)和长按(didLongPressMenuItem)生成事件

  • 菜单项将自动进行宝石化(AGMedallionView),因此无需创建自定义的 宝石化 图像。

  • 菜单项由 MenuItemFactory 进行设计

  • 菜单项包含数据对象

入门指南

默认用法

QuadCurveMenu 定义了一个简单的初始化器,它生成一个径向菜单,360 度,在给定的帧内居中,显示每个元素提供的数组中的菜单项。

@implementation AwesomeViewController

- (void)viewDidLoad {
  [super viewDidLoad]

  NSArray *menuItemArray = [NSArray arrayWithObjects:@"1",@"2",nil];

  QuadCurveMenu *menu = [[QuadCurveMenu alloc] initWithFrame:self.view.bounds withArray:menuItemArray];

  [self.view addSubview:menu];
}

@end

自定义数据源

您可能会发现使用 NSArray 对数据源的限制作出可以有自定义数据源的菜单。

首先,您定义一个数据源,或者使用符合 QuadCurveDataSourceDelegate 协议现成的数据源。

默认情况下,当您使用数组实现时,它使用 QuadCurveDefaultDataSource,它只是对 NSArray 进行了包装。

@interface AwesomeDataSource : NSObject <QuadCurveDataSourceDelegate> {
    NSMutableArray *dataItems;
}
@end

@implementation AwesomeDataSource

- (id)init {
    self = [super init];
    if (self) {
        dataItems = [NSMutableArray arrayWithObjects:@"1",@"2",@"3",@"4",@"5",@"6", nil];
    }
    return self;
}

#pragma mark - QuadCurveDataSourceDelegate Adherence

- (int)numberOfMenuItems {
    return [dataItems count];
}

- (id)dataObjectAtIndex:(NSInteger)itemIndex {
    return [dataItems objectAtIndex:itemIndex];
}

使用自定义数据源创建 QuadCurveMenu

@implementation AwesomeViewController

- (void)viewDidLoad {
  [super viewDidLoad]

  AwesomeDataSource *dataSource = [[AwesomeDataSource alloc] init];

  QuadCurveMenu *menu = [[QuadCurveMenu alloc] initWithFrame:self.view.bounds dataSource:dataSource];

  [self.view addSubview:menu];
}

@end

事件代理

设置一个代理对象,这通常是显示 QuadCurveMenu 的视图控制器,该控制器通常符合 QuadCurveMenuDelegate 协议。

@interface AwesomeViewController : UIViewController <QuadCurveMenuDelegate>

@end

@implementation AwesomeViewController

- (void)viewDidLoad {
  [super viewDidLoad]

  AwesomeDataSource *dataSource = [[AwesomeDataSource alloc] init];

  QuadCurveMenu *menu = [[QuadCurveMenu alloc] initWithFrame:self.view.bounds dataSource:dataSource];

  menu.delegate = self;

  [self.view addSubview:menu];
}

- (void)quadCurveMenu:(QuadCurveMenu *)menu didTapMenu:(QuadCurveMenuItem *)mainMenuItem {
    NSLog(@"Menu - Tapped");
}

- (void)quadCurveMenu:(QuadCurveMenu *)menu didLongPressMenu:(QuadCurveMenuItem *)mainMenuItem {
    NSLog(@"Menu - Long Pressed");
}

- (void)quadCurveMenu:(QuadCurveMenu *)menu didTapMenuItem:(QuadCurveMenuItem *)menuItem {
    NSLog(@"Menu Item (%@) - Tapped",menuItem.dataObject);
}

- (void)quadCurveMenu:(QuadCurveMenu *)menu didLongPressMenuItem:(QuadCurveMenuItem *)menuItem {
    NSLog(@"Menu Item (%@) - Long Pressed",menuItem.dataObject);
}

- (void)quadCurveMenuWillExpand:(QuadCurveMenu *)menu {
    NSLog(@"Menu - Will Expand");
}

- (void)quadCurveMenuDidExpand:(QuadCurveMenu *)menu {
    NSLog(@"Menu - Did Expand");
}

- (void)quadCurveMenuWillClose:(QuadCurveMenu *)menu {
    NSLog(@"Menu - Will Close");
}

- (void)quadCurveMenuDidClose:(QuadCurveMenu *)menu {
    NSLog(@"Menu - Did Close");
}

- (BOOL)quadCurveMenuShouldClose:(QuadCurveMenu *)menu {
    // Returning YES will allow the menu to close; NO to prevent it from closing.
    return YES;
}

- (BOOL)quadCurveMenuShouldExpand:(QuadCurveMenu *)menu {
    // Returning YES will allow the menu to expand; NO to prevent it from expanding.
    return YES;
}

@end

自定义菜单图像和菜单项图像

您可以配置中心、主菜单项和从主菜单出现的菜单项的外观。

默认情况下,QuadCurveMenu 对主菜单使用 [QuadCurveDefaultMenuItemFactory defaultMainMenuItemFactory],对每个菜单项使用 [QuadCurveDefaultMenuItemFactory defaultMenuItemFactory]。这些定义看起来像路径应用程序。

您可以定义自定义的 QuadCurveDefaultMenuItemFactory 实例。

@implementation AwesomeViewController

- (void)viewDidLoad {
  [super viewDidLoad]

  AwesomeDataSource *dataSource = [[AwesomeDataSource alloc] init];

  QuadCurveMenu *menu = [[QuadCurveMenu alloc] initWithFrame:self.view.bounds dataSource:dataSource];

  menu.delegate = self;

  // Use a facebook center button for the menu

  [menu setMainMenuItemFactory:[[QuadCurveDefaultMenuItemFactory alloc] initWithImage:[UIImage imageNamed:@"facebook.png"] highlightImage:[UIImage imageNamed:nil]]];

  // Use an unknown user button for the menu items

  [menu setMenuItemFactory:[[QuadCurveDefaultMenuItemFactory alloc] initWithImage:[UIImage imageNamed:@"unknown-user.png"] highlightImage:[UIImage imageNamed:nil]]];

  [self.view addSubview:menu];
}

您还可以定义符合协议 QuadCurveMenuItemFactory 的自定义对象。

#pragma mark - QuadCurveMenuItemFactory Adherence

- (QuadCurveMenuItem *)createMenuItemWithDataObject:(id)dataObject {

    QuadCurveMenuItem *item = [[QuadCurveMenuItem alloc] initWithImage:image
                                                      highlightedImage:highlightImage
                                                          contentImage:contentImage
                                               highlightedContentImage:highlightContentImage];

    [item setDataObject:dataObject];

    return item;
}

自定义菜单方向

默认情况下,QuadCurveMenu 以 360 度辐射菜单的形式显示。这可以通过配置现有的菜单目录或定义自定义的 QuadCurveMotionDirector 来进行自定义。

这与原始源中定义的一组菜单属性(控制布局)有所不同。

QuadCurveRadialDirector

您可以使用以下选项定义自定义的辐射目录:

  • rotateAngle - 菜单的初始起始角度(默认:0 度)
  • menuWholeAngle - 菜单项显示的可用的总角度(默认:360 度)

  • endRadius - 从主菜单中心到(菜单项将坐落的地方)的最终距离

  • nearRadius - 菜单项离主菜单中心最近的距离
  • farRadius - 菜单项离主菜单中心最远的距离

QuadCurveLinearDirector

您可以使用以下选项定义自定义的线性目录:

  • angle - 显示菜单项的角度
  • padding - 每个菜单项之间的空间

自定义 QuadCurveMotionDirector

如果辐射或线性布局不够强大,您可以定义符合 QuadCurveMotionDirector 接口的自定义目录。

@protocol QuadCurveMotionDirector <NSObject>

- (void)positionMenuItem:(QuadCurveMenuItem *)item
                 atIndex:(int)index
                 ofCount:(int)count
                fromMenu:(QuadCurveMenuItem *)mainMenuItem;

@end

自定义动画

有几个动画可以通过属性进行自定义。查看示例项目,您应该会看到一个包含应用程序中使用的默认动画的 动画 组。您可以在那里自定义它们,或者定义自己的并设置为 QuadCurveMenu 的属性。

以下是一个交换默认的 选中未选中 动画示例

menu.selectedAnimation = [[QuadCurveShrinkAnimation alloc] init]
menu.unselectedanimation = [[QuadCurveBlowupAnimation alloc] init]

动画是一个遵循协议 QuadCurveAnimation 的对象。

- (NSString *)animationName {
    return @"blowup";
}

- (CAAnimationGroup *)animationForItem:(QuadCurveMenuItem *)item {

    CGPoint point = item.center;

    CAKeyframeAnimation *positionAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    positionAnimation.values = [NSArray arrayWithObjects:[NSValue valueWithCGPoint:point], nil];
    positionAnimation.keyTimes = [NSArray arrayWithObjects: [NSNumber numberWithFloat:.3], nil];

    CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
    scaleAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(3, 3, 1)];

    CABasicAnimation *opacityAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
    opacityAnimation.toValue  = [NSNumber numberWithFloat:0.0f];

    CAAnimationGroup *animationgroup = [CAAnimationGroup animation];
    animationgroup.animations = [NSArray arrayWithObjects:positionAnimation, scaleAnimation, opacityAnimation, nil];
    animationgroup.duration = 0.3f;

    return animationgroup;

}

名称用作在图层中动画的名称。动画本身用 QuadCurveMenuItem 调用,并且应该返回将执行的动作组。