我需要为iOS实现菜单,例如android.menu
表示导航栏上的按钮(右侧)。
如果我点击该菜单将会显示。
我正在使用故事板。
答案 0 :(得分:10)
所以你想要这样的东西:
甚至在风景中工作:
我认为我需要永远解释:D
基本上我创建了一个自定义UINavigationController,如上面的评论所述,称为ActionBarNavigationController
从这个自定义UINavigationController,我添加了一个自定义UIView,用右侧的下拉按钮显示ActionBar
。
下拉菜单是UITableView
,其中包含您选择的已填充列表。
我在iOS中使用protocol
来处理即使在下拉菜单的每一行都有点按。
一切都完全是在代码中完成的。如果您愿意,可以将这些文件添加到项目中,我已在必要时提供了完整的代码。
#import "AppDelegate.h"
#import "ActionBarNavController.h"
#import "ViewController.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// ----------------------------------------------------------------------
// Our custom UINavigationController will contain the
// Android styled action bar as a subview as well as the
// drop down list.
//
// You can probably set the menu list items inside each individual
// controller instead of here. This is just for demo purpose.
// ----------------------------------------------------------------------
ActionBarNavController *actionBarNavController = [[ActionBarNavController alloc] init];
// ----------------------------------------------------------------------
// Initialize our main view controller and add it to
// action bar navigation controller.
// ----------------------------------------------------------------------
ViewController *viewController = [[ViewController alloc] init];
actionBarNavController.viewControllers = @[viewController];
self.window.rootViewController = actionBarNavController;
[self.window makeKeyAndVisible];
[actionBarNavController setNavTitle:@"Action Bar"];
// telling the controller the drop down list items
[actionBarNavController setMenuList:@[@"Action1", @"Action2", @"Action3"]];
return YES;
}
ViewController只是普通的UIViewController,它符合我在下面的类中创建的ActionBarNavControllerDelegate
。确保包含它。
#import <UIKit/UIKit.h>
#import "ActionBarNavController.h"
@interface ViewController : UIViewController <ActionBarNavControllerDelegate>
@property (nonatomic, strong) ActionBarNavController *navController;
@property (nonatomic, strong) UILabel *lblMessage;
@end
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// store the nav controller for easy access
self.navController = (ActionBarNavController *)self.navigationController;
self.navController.actionBarDelegate = self;
[[UIApplication sharedApplication] setStatusBarHidden:NO];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
[self initViews];
[self initConstraints];
}
-(void)initViews
{
self.view.backgroundColor = [UIColor whiteColor];
self.lblMessage = [[UILabel alloc] init];
self.lblMessage.text = @"This is your main view controller.\n\nPress the top right action bar button to see drop down menu.";
self.lblMessage.font = [UIFont systemFontOfSize:20];
self.lblMessage.numberOfLines = 0;
self.lblMessage.lineBreakMode = NSLineBreakByWordWrapping;
self.lblMessage.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:self.lblMessage];
}
-(void)initConstraints
{
self.lblMessage.translatesAutoresizingMaskIntoConstraints = NO;
id views = @{
@"lblMessage": self.lblMessage
};
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-[lblMessage]-20-|" options:0 metrics:nil views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[lblMessage]|" options:0 metrics:nil views:views]];
}
#pragma mark - DropDownMenu Delegate Methods -
-(void)actionBarDropDownChosenItem:(NSString *)chosenItem
{
if([chosenItem isEqualToString:@"Action1"])
{
self.lblMessage.text = @"You have chosen action 1";
}
else if([chosenItem isEqualToString:@"Action2"])
{
self.lblMessage.text = @"You have chosen action 2";
}
else if([chosenItem isEqualToString:@"Action3"])
{
self.lblMessage.text = @"You have chosen action 3";
}
// hide actionBar drop down list
[self.navController hideDropDownMenu];
}
@end
此ActionBarNavController包含ActionBar自定义视图的实例。它处理用户点击下拉按钮的交互。
#import <UIKit/UIKit.h>
#import "ActionBar.h"
// ------------------------------------------------------------
// Protocol is for handling when user selects an action
// from the drop down list, we need to inform any conforming
// delegate view controller the option was chosen.
// ------------------------------------------------------------
@protocol ActionBarNavControllerDelegate <NSObject>
@optional
-(void)actionBarDropDownChosenItem:(NSString *)chosenItem;
@end
@interface ActionBarNavController : UINavigationController <UITableViewDataSource, UITableViewDelegate>
// actionBar is a custom subclass that looks like Android's action bar
@property (nonatomic, strong) ActionBar *actionBar;
// the tableview will be our drop down list
@property (nonatomic, strong) UITableView *tableView;
// a boolean flag for toggling drop down menu
@property (nonatomic, assign) BOOL dropDownVisible;
@property (nonatomic, strong) NSArray *arrMenuItems;
@property (nonatomic, weak) id<ActionBarNavControllerDelegate> actionBarDelegate;
-(void)setNavTitle:(NSString *)navTitle;
-(void)setMenuList:(NSArray *)menuItems;
-(void)showDropDownMenu;
-(void)hideDropDownMenu;
@end
#import "ActionBarNavController.h"
#import "DropDownCell.h"
@interface ActionBarNavController ()
@end
@implementation ActionBarNavController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self initViews];
[self initConstraints];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Setup Methods -
-(void)initViews
{
self.view.clipsToBounds = YES;
// hide default navigation bar
[self setNavigationBarHidden:YES animated:NO];
self.navigationBar.translucent = NO;
// using our own custom looking action bar
self.actionBar = [[ActionBar alloc] init];
[self.actionBar.btnMenu addTarget:self action:@selector(toggleMenu) forControlEvents:UIControlEventTouchUpInside];
// setting up drop down list using a UITableView
self.tableView = [[UITableView alloc] init];
self.tableView.dataSource = self;
self.tableView.delegate = self;
self.tableView.alpha = 0;
self.tableView.backgroundColor = [UIColor colorWithRed:0.15 green:0.15 blue:0.15 alpha:1.0];
self.tableView.rowHeight = 50;
self.tableView.scrollEnabled = NO;
[self.view addSubview:self.actionBar];
[self.view addSubview:self.tableView];
}
-(void)initConstraints
{
self.actionBar.translatesAutoresizingMaskIntoConstraints = NO;
self.tableView.translatesAutoresizingMaskIntoConstraints = NO;
id views = @{
@"actionBar": self.actionBar,
@"tableView": self.tableView
};
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[actionBar]|" options:0 metrics:nil views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[tableView(200)]|" options:0 metrics:nil views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[actionBar(70)][tableView(150)]" options:0 metrics:nil views:views]];
}
#pragma mark - Other Methods -
-(void)setNavTitle:(NSString *)navTitle
{
self.actionBar.lblTitle.text = navTitle;
[self.view layoutIfNeeded];
}
-(void)setMenuList:(NSArray *)menuItems
{
self.arrMenuItems = menuItems;
[self.tableView reloadData];
}
#pragma mark - Drop Down Button Methods -
-(void)toggleMenu
{
if(self.dropDownVisible)
{
self.dropDownVisible = NO;
[self hideDropDownMenu];
}
else
{
self.dropDownVisible = YES;
[self showDropDownMenu];
}
}
-(void)showDropDownMenu
{
self.dropDownVisible = YES;
[UIView animateWithDuration:0.15 animations:^{
self.tableView.alpha = 1.0;
}];
}
-(void)hideDropDownMenu
{
self.dropDownVisible = NO;
[UIView animateWithDuration:0.15 animations:^{
self.tableView.alpha = 0.0;
}];
}
#pragma mark - TableView Methods -
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.arrMenuItems.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellID = @"cellID";
DropDownCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if(cell == nil)
{
cell = [[DropDownCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
}
cell.lblTitle.text = self.arrMenuItems[indexPath.row];
return cell;
}
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
// Remove seperator inset
if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
[cell setSeparatorInset:UIEdgeInsetsZero];
}
// Prevent the cell from inheriting the Table View's margin settings
if ([cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)]) {
[cell setPreservesSuperviewLayoutMargins:NO];
}
// Explictly set your cell's layout margins
if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsZero];
}
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if([self.actionBarDelegate respondsToSelector:@selector(actionBarDropDownChosenItem:)])
{
[self.actionBarDelegate actionBarDropDownChosenItem:self.arrMenuItems[indexPath.row]];
}
}
@end
此ActionBar类是自定义UIView,用于显示带有下拉按钮的操作栏。
#import <UIKit/UIKit.h>
@interface ActionBar : UIView
@property (nonatomic, strong) UIView *container;
@property (nonatomic, strong) UILabel *lblTitle;
@property (nonatomic, strong) UIButton *btnMenu;
@end
#import "ActionBar.h"
@implementation ActionBar
-(id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if(self)
{
[self initViews];
[self initConstraints];
}
return self;
}
-(void)initViews
{
self.container = [[UIView alloc] init];
self.container.backgroundColor = [UIColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:1.0];
self.lblTitle = [[UILabel alloc] init];
self.lblTitle.textColor = [UIColor whiteColor];
self.lblTitle.text = @"Title";
self.btnMenu = [[UIButton alloc] init];
[self.btnMenu setImage:[UIImage imageNamed:@"androidMenuButton"] forState:UIControlStateNormal];
[self.container addSubview:self.lblTitle];
[self.container addSubview:self.btnMenu];
[self addSubview:self.container];
}
-(void)initConstraints
{
self.container.translatesAutoresizingMaskIntoConstraints = NO;
self.lblTitle.translatesAutoresizingMaskIntoConstraints = NO;
self.btnMenu.translatesAutoresizingMaskIntoConstraints = NO;
id views = @{
@"container": self.container,
@"lblTitle": self.lblTitle,
@"btnMenu": self.btnMenu
};
// container constraints
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[container]|" options:0 metrics:nil views:views]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[container]|" options:0 metrics:nil views:views]];
// container subview constraints
[self.container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10-[lblTitle]-10-[btnMenu]|" options:0 metrics:nil views:views]];
[self.container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[lblTitle]|" options:0 metrics:nil views:views]];
[self.container addConstraint:[NSLayoutConstraint constraintWithItem:self.btnMenu attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.lblTitle attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]];
}
@end
此自定义UITableViewCell类控制下拉菜单单元格的外观。
#import <UIKit/UIKit.h>
@interface DropDownCell : UITableViewCell
@property (nonatomic, strong) UILabel *lblTitle;
@end
#import "DropDownCell.h"
@implementation DropDownCell
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if(self)
{
[self initViews];
[self initConstraints];
}
return self;
}
-(void)initViews
{
self.backgroundColor = [UIColor clearColor];
self.contentView.backgroundColor = [UIColor clearColor];
self.selectionStyle = UITableViewCellSelectionStyleNone;
self.lblTitle = [[UILabel alloc] init];
self.lblTitle.textColor = [UIColor whiteColor];
[self.contentView addSubview:self.lblTitle];
}
-(void)initConstraints
{
self.lblTitle.translatesAutoresizingMaskIntoConstraints = NO;
id views = @{
@"lblTitle": self.lblTitle
};
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10-[lblTitle]|" options:0 metrics:nil views:views]];
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[lblTitle]|" options:0 metrics:nil views:views]];
}
@end
androidMenuButton @ 1x,@ 2x,@ 3x
答案 1 :(得分:0)
我会使用Popover而不是完整的自定义菜单。在iPhone上,建议使用全屏模式演示而不是弹出菜单,但仍然可以。
此图片来自Popover documentation。
有关如何操作的详细信息,请参阅this answer。