Skip to content

Commit

Permalink
Merge pull request #7408 from hansemannn/TIMOB-5812
Browse files Browse the repository at this point in the history
[TIMOB-5812] iOS: Support UIMenuController
  • Loading branch information
cheekiatng committed Nov 11, 2015
2 parents 934da77 + 594b333 commit deb14ca
Show file tree
Hide file tree
Showing 10 changed files with 479 additions and 8 deletions.
130 changes: 130 additions & 0 deletions apidoc/Titanium/UI/iOS/MenuPopup.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
---
name: Titanium.UI.iOS.MenuPopup
summary: |
A menu popup provides the ability to create custom tooltip options using the `items` property
covering the native `UIMenuController` class.
See also:
* [iOS Developer Library: UIMenuController](https://developer.apple.com/library/prerelease/ios/documentation/iPhone/Reference/UIMenuController_Class/index.html)
platforms: [iphone,ipad]
since: "5.2.0"
osver: {ios: {min: "9.0"}}

properties:
- name: items
summary: The items of the menu popup.
description: |
The items will be shown as soon in the menu popup when the `show` method is called.
To hide them again, use the `hide` method in conjunction.
type: [String]

methods:
- name: show
summary: Shows the menu popup.
parameters:
- name: params
summary: Includes options how the menu popup should be shown.
type: MenuPopupShowParams
optional: false

- name: hide
summary: Hides the menu popup.
parameters:
- name: params
summary: Includes options how the menu popup should be hidden.
type: MenuPopupHideParams
optional: true

- name: isVisible
summary: Indicates whether the menu popup is currently visible.

events:
- name: click
summary: Fired when the user clicks at one of the menu popup items.
description: |
This event provides the properties `title` and `index` which relate to the name and position
of the clicked item inside the `items` property.
properties:
- name: index
summary: The index of the clicked item.
type: Number

- name: title
summary: The title of the clicked item.
type: String

examples:
- title: Example using multiple `items` and a `click` event.
example: |
The example below creates a new menu popup and shows it when the user clicks on the button.
var win = Ti.UI.createWindow({
backgroundColor: "#fff",
});
var button = Ti.UI.createButton({
title: "Show options"
});
win.add(button);
var menu = Ti.UI.iOS.createMenuPopup({
items: ["Option 1", "Option 2"]
});
menu.addEventListener("click", function(e) {
alert(e);
});
button.addEventListener("click", function() {
menu.show({
view: button
});
});
win.open();
---
name: MenuPopupShowParams
summary: Dictionary of options for showing a menu popup with <Titanium.UI.iOS.MenuPopup.show>.
platforms: [iphone,ipad]
since: "5.2.0"
description: |
The parameters used when showing a menu popup. Must include the `view` property to tell the menu popup
at which view it should be shown. Also set the `animated` property to `false` if you want to show the
menu popup without an animation.
properties:
- name: view
summary: The view where the menu pop is shown at.
type: Titanium.UI.View
optional: false

- name: animated
summary: Determines whether the menu popup should be opened or closed animated.
type: Boolean
default: true
optional: true

- name: arrowDirection
summary: Indicates the arrow direction of the menu popup.
description: Use this property to indicate the menu popups arrow to use.
type: Number
constants: [Titanium.UI.iOS.MENU_POPUP_ARROW_DIRECTION_UP,Titanium.UI.iOS.MENU_POPUP_ARROW_DIRECTION_DOWN,
Titanium.UI.iOS.MENU_POPUP_ARROW_DIRECTION_LEFT,Titanium.UI.iOS.MENU_POPUP_ARROW_DIRECTION_RIGHT,
Titanium.UI.iOS.MENU_POPUP_ARROW_DIRECTION_DEFAULT]

---
name: MenuPopupHideParams
summary: Dictionary of options for hiding a menu popup with <Titanium.UI.iOS.MenuPopup.hide>.
platforms: [iphone,ipad]
since: "5.2.0"
description: |
Set the `animated` property to `false` if you want to hide the menu popup without an animation.
properties:
- name: animated
summary: Determines whether the menu popup should be opened or closed animated.
type: Boolean
default: true
optional: true
26 changes: 26 additions & 0 deletions apidoc/Titanium/UI/iOS/iOS.yml
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,32 @@ properties:
since: "5.1.0"
osver: {ios: {min: "9.0"}}

- name: MENU_POPUP_ARROW_DIRECTION_UP
summary: An arrow that points upward.

type: Number
permission: read-only

- name: MENU_POPUP_ARROW_DIRECTION_DOWN
summary: An arrow that points downward.
type: Number
permission: read-only

- name: MENU_POPUP_ARROW_DIRECTION_LEFT
summary: An arrow that points toward the left.
type: Number
permission: read-only

- name: MENU_POPUP_ARROW_DIRECTION_RIGHT
summary: An arrow that points toward the right.
type: Number
permission: read-only

- name: MENU_POPUP_ARROW_DIRECTION_DEFAULT
summary: An arrow that is automatically aligned.
type: Number
permission: read-only

- name: PUSH_MODE_CONTINUOUS
summary: |
Use with <Titanium.UI.iOS.PushBehavior.pushMode> to specifiy a continuous force.
Expand Down
25 changes: 25 additions & 0 deletions iphone/Classes/TiUIiOSMenuPopup.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* Appcelerator Titanium Mobile
* Copyright (c) 2009-2015 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*/
#ifdef USE_TI_UIIOSMENUPOPUP
#import "TiUIView.h"
#import "TiUIiOSMenuPopupProxy.h"
#import <UIKit/UIKit.h>

@interface TiUIiOSMenuPopup : TiUIView

/**
Shows the menu popup.
*/
-(void)show:(id)args;

/**
Hides the menu popup.
*/
-(void)hide:(id)args;

@end
#endif
102 changes: 102 additions & 0 deletions iphone/Classes/TiUIiOSMenuPopup.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/**
* Appcelerator Titanium Mobile
* Copyright (c) 2009-2015 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*/

#ifdef USE_TI_UIIOSMENUPOPUP
#import "TiUIiOSMenuPopup.h"
#import "TiApp.h"

@interface TiUIiOSMenuPopup()
@property (nonatomic, readonly) TiUIiOSMenuPopupProxy *menuPopupProxy;
@end

@implementation TiUIiOSMenuPopup

-(BOOL)canBecomeFirstResponder
{
return YES;
}

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
NSString *sel = NSStringFromSelector(action);
NSRange match = [sel rangeOfString:@"menuItem-"];
if (match.location == 0) {
return YES;
}
return NO;
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
if ([super methodSignatureForSelector:sel]) {
return [super methodSignatureForSelector:sel];
}
return [super methodSignatureForSelector:@selector(fireEventWithIndex:)];
}

- (void)forwardInvocation:(NSInvocation *)invocation {
NSString *sel = NSStringFromSelector([invocation selector]);
NSRange match = [sel rangeOfString:@"menuItem-"];
if (match.location == 0) {
id index = [sel substringFromIndex:9];
[self fireEventWithIndex:[TiUtils intValue:index]];
} else {
[super forwardInvocation:invocation];
}
}

-(TiUIiOSMenuPopupProxy*)menuPopupProxy
{
return (TiUIiOSMenuPopupProxy*)self.proxy;
}

-(void)show:(id)args
{
ENSURE_SINGLE_ARG_OR_NIL(args,NSDictionary);
ENSURE_TYPE([args objectForKey:@"view"], TiViewProxy);
ENSURE_UI_THREAD_1_ARG(args);

TiViewProxy *sourceView = [args objectForKey:@"view"];
UIMenuControllerArrowDirection arrowDirection = [TiUtils intValue:@"arrowDirection" properties:args def:UIMenuControllerArrowDefault];
BOOL animated = [TiUtils boolValue:@"animated" properties:args def:YES];

if (sourceView == nil) {
NSLog(@"[ERROR] The Ti.UI.iOS.MenuPopup.show method must contain the 'view' property.");
return;
}

[self becomeFirstResponder];

[[[[[TiApp app] controller] topPresentedController] view] addSubview:self];

UIMenuController* controller = [UIMenuController sharedMenuController];
UIView *view = [sourceView view];

[controller setArrowDirection:arrowDirection];
[controller setMenuItems:[self.menuPopupProxy menuItems]];
[controller setTargetRect:view.bounds inView:view];
[controller setMenuVisible:YES animated:animated];
}

-(void)hide:(id)args
{
BOOL animated = [TiUtils boolValue:@"animated" properties:args def:YES];

[[UIMenuController sharedMenuController] setMenuVisible:NO animated:animated];
}

-(void)fireEventWithIndex:(int)index
{
if ([self.menuPopupProxy _hasListeners:@"click"]) {

[self.menuPopupProxy fireEvent:@"click" withObject:@{
@"index" : NUMINT(index),
@"title" : [[[self.menuPopupProxy menuItems] objectAtIndex:index] title]
}];
}
}

@end
#endif
38 changes: 38 additions & 0 deletions iphone/Classes/TiUIiOSMenuPopupProxy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Appcelerator Titanium Mobile
* Copyright (c) 2009-2015 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*/
#ifdef USE_TI_UIIOSMENUPOPUP
#import "TiViewProxy.h"

@interface TiUIiOSMenuPopupProxy : TiViewProxy

/**
The menu items to be presented inside the menu.
*/
@property(nonatomic,retain) NSMutableArray<UIMenuItem*> *menuItems;

/**
Shows the menu popup.
*/
-(void)show:(id)args;

/**
Hides the menu popup.
*/
-(void)hide:(id)args;

/*
Sets the items of the menu.
*/
-(void)setItems:(id)args;

/*
Determines if the menu is currenty visible.
*/
-(NSNumber*)isVisible:(id)unused;

@end
#endif

0 comments on commit deb14ca

Please sign in to comment.