问题描述
我需要为 iOS 实现菜单,例如 android.menu
表示导航按钮栏(右侧).
I need to implement menu for iOS like android.menu
means button on navigation bar(right side).
如果我点击那个菜单就会显示出来.
If I click that menu will display.
我正在使用故事板.
推荐答案
所以你想要这样的:
即使在横向也能工作:
我想我要花很长时间来解释:D
I think it's going to take forever for me to explain :D
基本上,我创建了一个自定义 UINavigationController,如上面的评论中所述,称为 ActionBarNavigationController
Basically I created a custom UINavigationController as mentioned in the comments above, called it ActionBarNavigationController
从这个自定义 UINavigationController,我添加了一个自定义 UIView 来显示 ActionBar
和右侧的下拉按钮.
From this custom UINavigationController, I added a custom UIView to display the ActionBar
with the drop down button on the right.
下拉菜单是一个带有您选择的填充列表的 UITableView
.
The drop down menu is a UITableView
with a populated list of your choice.
我在 iOS 中使用 protocol
来处理即使在下拉菜单的每一行上的点击.
I used protocol
in iOS to handle the tap even on each row of the drop down menu.
一切都是在代码中完成的.如果你愿意,你可以将这些文件添加到你的项目中,我在下面提供了必要的完整代码.
Everything was done purely in code. You can add these files to your project if you like, I've provided the code in full below where necessary.
#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;
}
视图控制器.h
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
ViewController.m
#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.
Press 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.h
这个 ActionBarNavController 包含一个 ActionBar 自定义视图的实例.它处理用户点击下拉按钮的交互.
ActionBarNavController.h
This ActionBarNavController contains an instance of the ActionBar custom view. It handles the interactions of the user tapping on the drop down button.
#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
ActionBarNavController.m
#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.h
此 ActionBar 类是自定义 UIView,用于显示带有下拉按钮的操作栏.
ActionBar.h
This ActionBar class is the custom UIView to show the action bar with drop down button.
#import <UIKit/UIKit.h>
@interface ActionBar : UIView
@property (nonatomic, strong) UIView *container;
@property (nonatomic, strong) UILabel *lblTitle;
@property (nonatomic, strong) UIButton *btnMenu;
@end
ActionBar.m
#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
DropDownCell.h
这个自定义 UITableViewCell 类控制下拉菜单单元格的外观.
DropDownCell.h
This custom UITableViewCell class controls the look and feel of the drop down menu cells.
#import <UIKit/UIKit.h>
@interface DropDownCell : UITableViewCell
@property (nonatomic, strong) UILabel *lblTitle;
@end
DropDownCell.m
#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
Drop Down Icon
androidMenuButton@1x, @2x, @3x
这篇关于如何在像 Android 一样的 iOS 中实现菜单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!