前言
这次推出的控件,比较常用,搜索界面下拉菜单
,如果喜欢我的文章,可以关注我微博:袁峥Seemygo
Demo效果:
效果图.gifDemo演示:
1.创建下拉菜单
YZPullDownMenu *menu = [[YZPullDownMenu alloc] init];
menu.frame = CGRectMake(0, 20, YZScreenW, 44);
[self.view addSubview:menu];
2.设置下拉菜单代理
menu.dataSource = self;
3.添加所有下拉菜单对应的子控制器
为什么要这样设计?
,因为每个app对应的下拉菜单不确定,所以交给各个开发者决定,下拉菜单的界面。
- (void)setupAllChildViewController
{
YZAllCourseViewController *allCourse = [[YZAllCourseViewController alloc] init];
YZSortViewController *sort = [[YZSortViewController alloc] init];
YZMoreMenuViewController *moreMenu = [[YZMoreMenuViewController alloc] init];
// 控制器最好作为自己的子控制器
[self addChildViewController:allCourse];
[self addChildViewController:sort];
[self addChildViewController:moreMenu];
}
4.实现YZPullDownMenu数据源方法
#pragma mark - YZPullDownMenuDataSource
// 返回下拉菜单多少列
- (NSInteger)numberOfColsInMenu:(YZPullDownMenu *)pullDownMenu
{
return 3;
}
// 返回下拉菜单每列按钮
- (UIButton *)pullDownMenu:(YZPullDownMenu *)pullDownMenu buttonForColAtIndex:(NSInteger)index
{
YZMenuButton *button = [YZMenuButton buttonWithType:UIButtonTypeCustom];
[button setTitle:_titles[index] forState:UIControlStateNormal];
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[button setTitleColor:[UIColor colorWithRed:25 /255.0 green:143/255.0 blue:238/255.0 alpha:1] forState:UIControlStateSelected];
[button setImage:[UIImage imageNamed:@"标签-向下箭头"] forState:UIControlStateNormal];
[button setImage:[UIImage imageNamed:@"标签-向上箭头"] forState:UIControlStateSelected];
return button;
}
// 返回下拉菜单每列对应的控制器
- (UIViewController *)pullDownMenu:(YZPullDownMenu *)pullDownMenu viewControllerForColAtIndex:(NSInteger)index
{
return self.childViewControllers[index];
}
// 返回下拉菜单每列对应的高度
- (CGFloat)pullDownMenu:(YZPullDownMenu *)pullDownMenu heightForColAtIndex:(NSInteger)index
{
// 第1列 高度
if (index == 0) {
return 400;
}
// 第2列 高度
if (index == 1) {
return 180;
}
// 第3列 高度
return 240;
}
5.【更新菜单标题,需要发送通知给我】
为什么要这样设计?
解耦,自己的控制器中就不需要导入我的框架的头文件了,侵入性不大。
【更新菜单标题步骤】
-
1.把
【extern NSString * const YZUpdateMenuTitleNote;】
这行代码拷贝到自己控制器中,这个在YZPullDownMenu.h
中 -
2.在选中标题的方法中,发送以下通知
[[NSNotificationCenter defaultCenter] postNotificationName:YZUpdateMenuTitleNote object:self userInfo:@{@"title":cell.textLabel.text}]; -
3.1 postNotificationName:通知名称 =>
【YZUpdateMenuTitleNote】
-
3.2 object:谁发送的通知 =>【self】(当前控制器)
-
3.3 userInfo:选中标题信息 => 可以多个key,多个value,没有固定的,因为有些界面,需要勾选很多选项,key可以随意定义。
-
3.4 底层会自动判定,当前userInfo有多少个value,如果有一个就会直接更新菜单标题,有多个就会更新,满足大部分需求。
-
3.5 发出通知,会自动弹回下拉菜单
5.1 可以参考YZSortViewController中代码
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
_selectedCol = indexPath.row;
// 选中当前
YZSortCell *cell = [tableView cellForRowAtIndexPath:indexPath];
// 更新菜单标题
[[NSNotificationCenter defaultCenter] postNotificationName:YZUpdateMenuTitleNote object:self userInfo:@{@"title":cell.textLabel.text}];
}
源码
点击这下载源代码
网友评论
[self clear];
[[NSNotificationCenter defaultCenter] removeObserver:_observer];
因为是 uiview 不会自动调用 dealloc 方法
你bug不解决搞一堆学生来膜拜你算怎么回事
2016-09-29 13:14:18.794 Matt[4059:190721] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 9223372036854775807 beyond bounds [0 .. 2]'
*** First throw call stack:
(
0 CoreFoundation 0x000000010a47234b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x000000010991221e objc_exception_throw + 48
2 CoreFoundation 0x000000010a3a3f1b -[__NSArrayM objectAtIndex:] + 203
3 Matt 0x00000001091f72b0 __23-[YZPullDownMenu setup]_block_invoke + 240
4 Foundation 0x00000001094219fa -[__NSObserver _doit:] + 304
5 CoreFoundation 0x000000010a41019c __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
6 CoreFoundation 0x000000010a41009b _CFXRegistrationPost + 427
7 CoreFoundation 0x000000010a40fe02 ___CFXNotificationPost_block_invoke + 50
8 CoreFoundation 0x000000010a3d2ea2 -[_CFXNotificationRegistrar find:object:observer:enumerator:] + 2018
9 CoreFoundation 0x000000010a3d1f3b _CFXNotificationPost + 667
10 Foundation 0x00000001093da13b -[NSNotificationCenter postNotificationName:object:userInfo:] + 66
11 Matt 0x00000001091d26b1 -[YZAllCourseViewController tableView:didSelectRowAtIndexPath:] + 657
12 UIKit 0x000000010c34796d -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1848
13 UIKit 0x000000010c347b81 -[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 330
14 UIKit 0x000000010c1fd8bb _runAfterCACommitDeferredBlocks + 320
15 UIKit 0x000000010c1ea53f _cleanUpAfterCAFlushAndRunDeferred
试问 如果当前控制中有别的子控制器,但是不打算放到下拉中,这种情况考虑了吗
NSInteger col = [self.controllers indexOfObject:note.object];
// 获取对应按钮
UIButton *btn = self.menuButtons[col];
这里经常会有bug,导致数组越界。难道是因为用的通知引起的?