美文网首页iOS开发iOS 知识点PerhapYs的OC学习日记
【iOS干货:快速集成搜索界面下拉菜单框架】

【iOS干货:快速集成搜索界面下拉菜单框架】

作者: 袁峥 | 来源:发表于2016-08-13 16:48 被阅读13206次

    前言

    这次推出的控件,比较常用,搜索界面下拉菜单,如果喜欢我的文章,可以关注我微博:袁峥Seemygo

    Demo效果:

    效果图.gif

    Demo演示:

    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}];
    }
    
    

    源码

    点击这下载源代码

    相关文章

      网友评论

      • Killer_HG:您好,我发现Demo下拉菜单数据过多的时候,YZSortViewController无法全部显示,滑动在底部就不能再滑了,我试着设置YZSortViewController里tableview的高度 但是没有效果,请问这个如何解决?谢谢
        Killer_HG:@juefeiye 不好用,他是一个tableviewcontroller,我的解决方案是在viewdidapper里更改tableview的frame
        juefeiye:设置内边距。。。
      • juefeiye:如果发现 数组越界的崩溃 大家 手动调用 移除监听那个方法
        [self clear];
        [[NSNotificationCenter defaultCenter] removeObserver:_observer];
        因为是 uiview 不会自动调用 dealloc 方法
        juefeiye:@沉默的冬天 你全文搜 [NSNotificationCenter defaultCenter] removeObserver。。他的view是不会调用这个方法的
      • 后青春期的诗大喵:只要生成一个新的实例,点一下就会崩溃,最开始生成的没有影响。
      • ChrisPaulss:我说一下我的看法,这个代码奔溃出现在获取列数,设置相应的标题的时候出现的,此时需要对症下药,咱们可以换一种方式,不必非要用indexOfObject这个方法去获取列,观察作者写的代码可以知道,没一列对应的控制器或者视图都是独立的,在点击选完数据的时候要发送一个通知,这时候在通知里在加一个索引字段,用于表示是哪一列,然后在接收通知的方法里拿出来判断一下,然后给col赋值为此索引,问题不就迎刃而解了吗。
        Killer_HG:老哥,稳!用你的思路改的~
      • f1c1714b61c3:怎么在父控制器中获取选择的信息
      • 一切都是幻觉:入坑了,点下拉菜单没反应
        你bug不解决搞一堆学生来膜拜你算怎么回事
      • Crayon丶_7ad1:这个有BUG啊。。。
      • 吴欧:首先 感谢作者分享。不过bug好多呀,在界面复用的情况下,使用通知其他界面也会收到消息,所以这种写法感觉有点牵强了,能有好的改良方法么。还有将viewcontroller加入subviewcontroller也有bug
        有bug的程序猿:有好的框架推荐么
      • Ausxin:这个 可以支持多选吗?
      • pluskok:请问这个控件初始化以后,后续能在更改title列数吗 ,例如点击 “小学0:详1” 后,“排序”和“更多”这两列暂时隐藏,点击“小学0:详0”后 ,“排序”和“更多”又显示出来。
      • 温州的柯:你的dealloc方法为什么不会走啊
      • 88c862862018:如果能增加一个类似饿了么/美团 那种多条件选择的下拉样式就更好了。
      • d1083172fea9:这个如果是三级的怎么搞
      • 旧城丶旧人:峥哥,这个多连续点击几次按钮,会出现一个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
        袁峥:@WammysHouse 你看下控制器是不是没有释放
        多鱼影视界:@袁峥Seemygo 请问一下 为什么会出现这种情况
        袁峥:@WammysHouse 角标越界了
      • 叫哥干嘛:你好 你这个把控制器放到childViewController中 ,来控制下拉的列数.
        试问 如果当前控制中有别的子控制器,但是不打算放到下拉中,这种情况考虑了吗
      • 村里竹竿:老师刚改名字了 :smile:
      • 抢手的哥: // 获取列
        NSInteger col = [self.controllers indexOfObject:note.object];

        // 获取对应按钮
        UIButton *btn = self.menuButtons[col];

        这里经常会有bug,导致数组越界。难道是因为用的通知引起的?
        抢手的哥:@峥吖 慢慢点没事,点快了就容易出这个错误,我在想是不是因为用的通知的原因,没有代理反应快
        抢手的哥:@峥吖 我打断点调试过,这里的note.object原本是子控制器,但是断点显示的不是,然后取索引取不出来,为nil,然后取button就会报错了
        袁峥:@抢手的哥 能把错误 发我吗
      • 小杂鱼:你好 我自定义一个导航栏 64的高度 然后YZPullDownMenu加载导航栏上 高度是44 但是我弹出子controller时候 子controller点不了 除非我把导航栏的高度变得足够高 请问有办法解决这个问题吗
        袁峥:@小杂鱼 我当前框架不支持喔,后续我搞搞
        小杂鱼:@峥吖 这个有办法解决吗 是超出父控件的原因 但是我的需求 是在导航栏上显示 大神能指点一下吗
        袁峥:@小杂鱼 可能超出父控件了
      • ca04a13f364c:感谢 非常好用
      • 65b88cd256bc:这个我需要,感谢
      • csqingyang:请教,在需要点击cell时切换其他菜单栏的数据源时,有什么好的方法?比如,点击了排序中的一个cell 之后,在更多中的数据源会变成其他的.我想到的方法:在子菜单对应的控制器中进行通知传值,但是前提是那个接收通知的菜单得先存在;又有一种:将数据写在 userdefaults 中 ,但是这样做未免太麻烦了.问一下,这种场景中,有什么好的解决方法?
        袁峥:@csqingyang 参照第一个控制器写
        csqingyang:@峥吖 比如第一列菜单 有:北京,上海,南京, 第二列菜单 用来展示各个城市之间的数据,选择北京时,就展示北京的数据,选择上海时,第二列就显示上海的数据.
        袁峥:@csqingyang 没太听到
      • Xcode丶终结者:大神很喜欢你的文章,就是发现更多里面的cheakView点不动 如果给cheakview的userInteractionEnabled 设置 NO效果更好 :kissing_heart:
        袁峥:@Xcode丶终结者 谢谢
      • 5a3830ede979:大神,希望继续出新作品!
      • 判若两人丶:原来是峰哥啊,哈哈
      • 老板娘来盘一血:铮哥,我要给你生猴子
      • KXuan:峥哥,真给力

      本文标题:【iOS干货:快速集成搜索界面下拉菜单框架】

      本文链接:https://www.haomeiwen.com/subject/setysttx.html