• 下拉框选择效果的实现原理


    导航栏与下拉框的效果

    实现的效果是在导航栏中间出现下拉框选择的效果,当选择某一个时,则上面的字也相应进行修改(此实例代码可以看Coding.net的源代码),这边有把它单独提取出来进行测试,源代码下载;接下来将简单介绍一下此实现的方式及主要代码;

    1:因为我们是跟导航栏进行结合,所以这边用到的NavigationController,我们把这个页面的效果放在viewController中,弹出来的下拉列表这边是以表格的形式存在,每个则是表格的一行,行里面包括图标跟文字;

    首先看一下AppDelegate.m的代码:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        // Override point for customization after application launch.
        self.window.backgroundColor = [UIColor whiteColor];
        ViewController *loginVC = [[ViewController alloc] init];
        [self.window setRootViewController:[[UINavigationController alloc] initWithRootViewController:loginVC]];
        [self.window makeKeyAndVisible];
        return YES;
    }

    接着是ViewController.h及ViewController.m的代码:

    #import <UIKit/UIKit.h>
    #import "UIViewController+DownMenu.h"
    
    @interface ViewController : UIViewController
    
    
    @end
    #import "ViewController.h"
    
    @interface ViewController ()
    @property (nonatomic, assign) NSInteger curIndex;
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        _curIndex = 0;
        [self customDownMenuWithTitles:@[[DownMenuTitle title:@"冒泡广场" image:@"nav_tweet_all" badge:nil],
                                         [DownMenuTitle title:@"好友圈" image:@"nav_tweet_friend" badge:nil],
                                         [DownMenuTitle title:@"热门冒泡" image:@"nav_tweet_hot" badge:nil],
                                         [DownMenuTitle title:@"我的冒泡" image:@"nav_tweet_mine" badge:nil]]
                       andDefaultIndex:_curIndex
                              andBlock:^(id titleObj, NSInteger index) {
                                  [(DownMenuTitle *)titleObj setBadgeValue:nil];
                                  _curIndex = index;
                                  [self refreshFirst];
                              }];
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    -(void)refreshFirst
    {
        NSLog(@"%ld",_curIndex);
    }
    
    @end

    这边把一些内容封装到的UIViewController+DownMenu.h这个文件及实现里;

    2:UIViewController+DownMenu主要代码如下:

    #import <UIKit/UIKit.h>
    #import "UIDownMenuButton.h"
    @class DownMenuTitle;
    
    @interface UIViewController (DownMenu)
    - (UIDownMenuButton *)customDownMenuWithTitles:(NSArray *)titleList andDefaultIndex:(NSInteger)index andBlock:(void (^)(id titleObj, NSInteger index))block;
    - (UIDownMenuButton *)downMenuBtn;
    @end
    #import "UIViewController+DownMenu.h"
    
    @implementation UIViewController (DownMenu)
    - (UIDownMenuButton *)customDownMenuWithTitles:(NSArray *)titleList andDefaultIndex:(NSInteger)index andBlock:(void (^)(id titleObj, NSInteger index))block{
        UIDownMenuButton *navBtn = [[UIDownMenuButton alloc] initWithTitles:titleList andDefaultIndex:index andVC:self];
        navBtn.menuIndexChanged = block;
        self.navigationItem.titleView = navBtn;
        return navBtn;
    }
    - (UIDownMenuButton *)downMenuBtn{
        if (self.navigationItem.titleView || [self.navigationItem.titleView isKindOfClass:[UIDownMenuButton class]]) {
            UIDownMenuButton *navBtn = (UIDownMenuButton *)self.navigationItem.titleView;
            return navBtn;
        }else{
            return nil;
        }
    }
    @end

    注意:UIDownMenuButton这个就是上面每个行的封装,这边可以看到在其对它进行增加到nav里面;

    3:UIDownMenuButton主要代码如下:

    #import <UIKit/UIKit.h>
    #import "NSString+Common.h"
    
    @class DownMenuTitle;
    
    @interface UIDownMenuButton : UIButton <UITableViewDataSource, UITableViewDelegate>
    @property (nonatomic, assign) NSInteger curIndex;
    
    - (UIDownMenuButton *)initWithTitles:(NSArray *)titleList andDefaultIndex:(NSInteger)index andVC:(UIViewController *)viewcontroller;
    @property (nonatomic,copy) void(^menuIndexChanged)(id titleObj, NSInteger index);
    
    @end
    
    @interface DownMenuTitle : NSObject
    @property (nonatomic, strong) NSString *titleValue, *imageName, *badgeValue;
    + (DownMenuTitle *)title:(NSString *)title image:(NSString *)image badge:(NSString *)badge;
    @end
    #define kNavImageWidth (15.0+5.0)
    #define kDownMenu_ContentLeftPading 27.0
    #define kDownMenuCellHeight 50.0
    #define  kNavTitleFontSize 19
    #define kScreen_Bounds [UIScreen mainScreen].bounds
    #define kScreen_Height [UIScreen mainScreen].bounds.size.height
    #define kScreen_Width [UIScreen mainScreen].bounds.size.width
    #define kKeyWindow [UIApplication sharedApplication].keyWindow
    
    #define DEGREES_TO_RADIANS(angle) ((angle)/180.0 *M_PI)
    #define RADIANS_TO_DEGREES(radians) ((radians)*(180.0/M_PI))
    
    #import "UIDownMenuButton.h"
    #import "DownMenuCell.h"
    
    @interface UIDownMenuButton()
    
    @property (nonatomic, strong) NSArray *titleList;
    @property (nonatomic, assign) BOOL isShowing;
    @property (nonatomic, strong) UIView *mySuperView, *myTapBackgroundView;
    @property (nonatomic, strong) UITableView *myTableView;
    
    @end
    
    
    @implementation UIDownMenuButton
    
    - (UIDownMenuButton *)initWithTitles:(NSArray *)titleList andDefaultIndex:(NSInteger)index andVC:(UIViewController *)viewcontroller{
        self = [super init];
        if (self) {
            _titleList = titleList;
            _curIndex = index;
            _isShowing = NO;
            _mySuperView = viewcontroller.view;
           
            self.backgroundColor = [UIColor clearColor];
            [self setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
            [self setTitleColor:[UIColor blackColor] forState:UIControlStateHighlighted];
            [self.titleLabel setFont:[UIFont systemFontOfSize:kNavTitleFontSize]];
            [self.titleLabel setMinimumScaleFactor:0.5];
            [self addTarget:self action:@selector(changeShowing) forControlEvents:UIControlEventTouchUpInside];
            [self refreshSelfUI];
        }
        return self;
    }
    
    - (void)refreshSelfUI{
        NSString *titleStr = @"";
        DownMenuTitle *menuObj = [self.titleList objectAtIndex:self.curIndex];
        titleStr = menuObj.titleValue;
        CGFloat titleWidth = [titleStr getWidthWithFont:self.titleLabel.font constrainedToSize:CGSizeMake(kScreen_Width, 30)];
        CGFloat btnWidth = titleWidth +kNavImageWidth;
        self.frame = CGRectMake((kScreen_Width-btnWidth)/2, (44-30)/2, btnWidth, 30);
    
        self.titleEdgeInsets = UIEdgeInsetsMake(0, -kNavImageWidth, 0, kNavImageWidth);
        self.imageEdgeInsets = UIEdgeInsetsMake(0, titleWidth, 0, -titleWidth);
        [self setTitle:titleStr forState:UIControlStateNormal];
        [self setImage:[UIImage imageNamed:@"nav_arrow_down"] forState:UIControlStateNormal];
    }
    
    - (void)changeShowing{
        [kKeyWindow endEditing:YES];
        
        if (!self.myTableView) {
            //定义其显示的位置
            self.myTableView = [[UITableView alloc] initWithFrame:CGRectMake(0,64, kScreen_Width, 0) style:UITableViewStylePlain];
            [self.myTableView registerClass:[DownMenuCell class] forCellReuseIdentifier:kCellIdentifier_DownMenu];
            self.myTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
            self.myTableView.dataSource = self;
            self.myTableView.delegate = self;
            self.myTableView.alpha = 0;
            self.myTableView.scrollEnabled = NO;
        }
        if (!self.myTapBackgroundView) {
            self.myTapBackgroundView = [[UIView alloc] initWithFrame:kScreen_Bounds];
            self.myTapBackgroundView.backgroundColor = [UIColor clearColor];
            UITapGestureRecognizer *bgTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(changeShowing)];
            [self.myTapBackgroundView addGestureRecognizer:bgTap];
        }
        
        if (self.isShowing) {//隐藏
            CGRect frame = self.myTableView.frame;
            frame.size.height = 0;
            self.enabled = NO;
            [UIView animateWithDuration:0.3 animations:^{
                [self refreshSelfUI];
                self.myTapBackgroundView.backgroundColor = [UIColor colorWithWhite:0 alpha:0];
                self.myTableView.alpha = 0;
                self.myTableView.frame = frame;
                self.imageView.transform = CGAffineTransformRotate(self.imageView.transform, DEGREES_TO_RADIANS(180));
            } completion:^(BOOL finished) {
                [self.myTableView removeFromSuperview];
                [self.myTapBackgroundView removeFromSuperview];
                self.enabled = YES;
                self.isShowing = !self.isShowing;
            }];
        }else{//显示
            [[UIApplication sharedApplication].keyWindow addSubview:self.myTapBackgroundView];
            [[UIApplication sharedApplication].keyWindow addSubview:self.myTableView];
            [self.myTableView reloadData];
            CGRect frame = self.myTableView.frame;
            frame.size.height = kDownMenuCellHeight *[self.titleList count];
            self.enabled = NO;
            [UIView animateWithDuration:0.3 animations:^{
                self.myTapBackgroundView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.2];
                self.myTableView.alpha = 1.0;
                self.myTableView.frame = frame;
                self.imageView.transform = CGAffineTransformRotate(self.imageView.transform, DEGREES_TO_RADIANS(180));
            } completion:^(BOOL finished) {
                self.enabled = YES;
                self.isShowing = YES;
            }];
        }
    }
    
    #pragma mark Table M
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
        return [self.titleList count];
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        DownMenuCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_DownMenu forIndexPath:indexPath];
        DownMenuTitle *curItem =[self.titleList objectAtIndex:indexPath.row];
        cell.curItem = curItem;
        cell.backgroundColor = (indexPath.row == self.curIndex)? [UIColor colorWithHexString:@"0xf3f3f3"] : [UIColor whiteColor];
        return cell;
    }
    
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
        return kDownMenuCellHeight;
    }
    
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
        [tableView deselectRowAtIndexPath:indexPath animated:YES];
        self.curIndex = indexPath.row;
        [self changeShowing];
        if (self.menuIndexChanged) {
            self.menuIndexChanged([self.titleList objectAtIndex:_curIndex], _curIndex);
        }
    }
    
    - (void)setCurIndex:(NSInteger)curIndex{
        _curIndex = curIndex;
        [UIView animateWithDuration:0.3 animations:^{
            [self refreshSelfUI];
    //        [self.myTableView reloadData];
    //        [self.myTableView performSelector:@selector(reloadData) withObject:nil afterDelay:0.3];
        }];
    }
    
    - (void)dealloc
    {
        self.myTableView.delegate = nil;
    }
    
    @end
    
    
    @implementation DownMenuTitle
    + (DownMenuTitle *)title:(NSString *)title image:(NSString *)image badge:(NSString *)badge{
        DownMenuTitle *menuObj = [[DownMenuTitle alloc] init];
        menuObj.titleValue = title;
        menuObj.badgeValue = badge;
        menuObj.imageName = image;
        return menuObj;
    }
    @end

    其中refreshSelfUI这个方法里面是实现的选择时,对应文字跟箭头图标的变化;重点的内容在changeShowing这个方法,它有定义列表要显示的位置,列表的创建初始化,及背景模态的出现,显示及隐藏的内容,视图的创建及删除;最后一个是实体的赋值;

    4:表格单元行的布局DownMenuCell,主要代码如下:

    #define kCellIdentifier_DownMenu @"DownMenuCell"
    
    #import <UIKit/UIKit.h>
    #import "UIDownMenuButton.h"
    #import "UIColor+expanded.h"
    
    @interface DownMenuCell : UITableViewCell
    @property (strong, nonatomic) DownMenuTitle *curItem;
    @end
    #import "DownMenuCell.h"
    
    @implementation DownMenuCell
    
    - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
    {
        self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
        if (self) {
            // Initialization code
        }
        return self;
    }
    
    - (void)awakeFromNib
    {
        // Initialization code
    }
    
    - (void)setSelected:(BOOL)selected animated:(BOOL)animated
    {
        [super setSelected:selected animated:animated];
    
        // Configure the view for the selected state
    }
    - (void)layoutSubviews{
        [super layoutSubviews];
        if (!_curItem) {
            return;
        }
        self.imageView.frame = CGRectMake(27, (50.0-25.0)/2, 25, 25);
        self.textLabel.frame = CGRectMake(65, (50.0-25.0)/2, 150, 25);
        self.textLabel.backgroundColor = [UIColor clearColor];
        self.textLabel.textColor = [UIColor blackColor];
        self.textLabel.font = [UIFont systemFontOfSize:15];
        
        self.imageView.image = [UIImage imageNamed:_curItem.imageName];
        self.textLabel.text = _curItem.titleValue;;
    }
    @end
  • 相关阅读:
    selenium之css选择器高级用法
    常系数线性齐次递推新理解
    关于莫队本质的理解
    2021.5.8总结
    决策单调性优化dp
    字符串 复习
    5.1总结
    树分块 学习笔记
    莫反 复习
    P4570 [BJWC2011]元素
  • 原文地址:https://www.cnblogs.com/wujy/p/4712329.html
Copyright © 2020-2023  润新知