zoukankan      html  css  js  c++  java
  • [iOS微博项目

    A.NavigationBar标题按钮
    1.需求
    • 在“首页”的导航栏中部设置一个“首页”文字+箭头按钮
    • 统一设置样式
    • 根据实际文本长度调整宽度
    • 消除系统自带的点击高亮效果
    • 点击按钮,箭头上下颠倒
     
    NavigationTitleButton
     
    2.思路
    • 使用UIButton,设置文本和图片
    • 在initWithFrame统一样式
    • 创建一个继承UIButton的自定义类,重写文本和图片的绘图方法,互换位置
    • 设置一个标识成员变量,判断当前的按钮状态(弹出 or 缩回)
     
    3.实现
    (1)自定义继承UIButton的类 HVWNavigationBarTitleButton
     1 //
     2 //  HVWNavigationBarTitleButton.m
     3 //  HVWWeibo
     4 //
     5 //  Created by hellovoidworld on 15/2/2.
     6 //  Copyright (c) 2015年 hellovoidworld. All rights reserved.
     7 //
     8 
     9 #import "HVWNavigationBarTitleButton.h"
    10 
    11 @implementation HVWNavigationBarTitleButton
    12 
    13 /** 重写initWithFrame, 统一设置按钮的样式 */
    14 - (instancetype)initWithFrame:(CGRect)frame {
    15     if (self = [super initWithFrame:frame]) {
    16         // 设置字体
    17         self.titleLabel.font = HVWNavigationTitleFont;
    18         [self setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    19        
    20         // 文本右对齐
    21         [self.titleLabel setTextAlignment:NSTextAlignmentRight];
    22        
    23         // 取消图标高亮效果
    24         [self setAdjustsImageWhenDisabled:NO];
    25        
    26         // 图片居中
    27         [self.imageView setContentMode:UIViewContentModeCenter];
    28        
    29     }
    30    
    31     return self;
    32 }
    33 
    34 /** 重写iamge的绘图方法 */
    35 - (CGRect)imageRectForContentRect:(CGRect)contentRect {
    36     CGFloat height = contentRect.size.height;
    37     CGFloat width = height;
    38     CGFloat x = self.size.width - width;
    39     CGFloat y = 0;
    40     return CGRectMake(x, y, width, height);
    41 }
    42 
    43 /** 重写title的绘图方法 */
    44 - (CGRect)titleRectForContentRect:(CGRect)contentRect {
    45     CGFloat height = contentRect.size.height;
    46     // 文本宽度 = 按钮整体宽度 - 图片宽度
    47     CGFloat width = self.height - height;
    48     CGFloat x = 0;
    49     CGFloat y = 0;
    50     return CGRectMake(x, y, width, height);
    51 }
    52 
    53 @end
     
    (2)在“首页”控制器设置“标题按钮”:
    HVWHomeViewController.m:
     1 - (void)viewDidLoad {
     2     [super viewDidLoad];
     3    
     4     // 添加导航控制器按钮
     5     // 左边按钮
     6     self.navigationItem.leftBarButtonItem = [UIBarButtonItem itemWithImage:@"navigationbar_friendsearch" hightlightedImage:@"navigationbar_friendsearch_highlighted" target:self selector:@selector(searchFriend)];
     7    
     8     // 右边按钮
     9     self.navigationItem.rightBarButtonItem = [UIBarButtonItem itemWithImage:@"navigationbar_pop" hightlightedImage:@"navigationbar_pop_highlighted" target:self selector:@selector(pop)];
    10    
    11     // 设置标题按钮
    12     HVWNavigationBarTitleButton *titleButton = [[HVWNavigationBarTitleButton alloc] init];
    13     titleButton.height = 35;
    14     titleButton.width = 100;
    15     [titleButton setTitle:@"首页" forState:UIControlStateNormal];
    16     [titleButton setImage:[UIImage imageWithNamed:@"navigationbar_arrow_down"] forState:UIControlStateNormal];
    17     // 设置背景图片
    18     [titleButton setBackgroundImage:[UIImage resizedImage:@"navigationbar_filter_background_highlighted"] forState:UIControlStateHighlighted];
    19    
    20     // 监听按钮点击事件,替换图标
    21     [titleButton addTarget:self action:@selector(titleButtonClickd:) forControlEvents:UIControlEventTouchUpInside];
    22    
    23     self.navigationItem.titleView = titleButton;
    24 }
    25  
    26 /** 标题栏按钮点击事件 */
    27 - (void) titleButtonClickd:(UIButton *) button {
    28     self.titleButtonExtended = !self.titleButtonExtended;
    29    
    30     if (self.isTitleButtonExtended) {
    31         [button setImage:[UIImage imageWithNamed:@"navigationbar_arrow_up"] forState:UIControlStateNormal];
    32     } else {
    33         [button setImage:[UIImage imageWithNamed:@"navigationbar_arrow_down"] forState:UIControlStateNormal];
    34     }
    35 }
    36  
    37 #mark:有希望依赖图片缓存,使用"=="判断当前按钮图片来决定按钮状态的,发现使用currentImage和新建一个UIImage(同一张图片)出来的地址并不一致!所以不能采用。
    38 -(void)titleButtonClick:(UIButton *)titleButton
    39 {
    40     UIImage *titleImage=[UIImage imageWithName:@"navigationbar_arrow_down"];
    41    
    42     if (titleButton.currentImage==titleImage) {
    43         //换成箭头向上
    44         [titleButton setImage:[UIImage imageWithName:@"navigationbar_arrow_up"] forState:UIControlStateNormal];
    45     }else
    46     {
    47         //换成箭头向下
    48         [titleButton setImage:[UIImage imageWithName:@"navigationbar_arrow_down"] forState:UIControlStateNormal];
    49     }
    50 }
     
    B.导航栏标题按钮弹出框
    1.需求
    点击导航栏标题按钮弹出一个框
    点击框外的其他地方,隐藏此框
     
    HVWPopMenu
     
    2.思路
    因为框的范围涉及到了导航栏,所以不能放在导航栏下的内容界面控制器上,要放在导航栏上
    在框和导航栏的夹层放置一个全屏的(透明/半透明)的UIButton,用来监听框外点击
    封装此功能,可以作为一个弹出菜单控件
     
    (1)简单尝试直接在窗口上添加一个UIImageView
    HVWHomeViewController:
     1 /** 标题栏按钮点击事件 */
     2 - (void) titleButtonClickd:(UIButton *) button {
     3     self.titleButtonExtended = !self.titleButtonExtended;
     4    
     5     if (self.isTitleButtonExtended) {
     6         [button setImage:[UIImage imageWithNamed:@"navigationbar_arrow_up"] forState:UIControlStateNormal];
     7        
     8         // 弹出框
     9         UIView *window = [[UIApplication sharedApplication] keyWindow];
    10         UIImageView *popView = [[UIImageView alloc] init];
    11         popView.size = CGSizeMake(200, 200);
    12         popView.centerX = window.width * 0.5;
    13         popView.y = 55;
    14         popView.image = [UIImage resizedImage:@"popover_background"];
    15         [self.navigationController.view addSubview:popView];
    16        
    17     } else {
    18         [button setImage:[UIImage imageWithNamed:@"navigationbar_arrow_down"] forState:UIControlStateNormal];
    19     }
    20 }
     
    Image(77)
     
    (2)点击其他区域,隐藏弹出框
    使用一个全屏透明/半透明UIButton夹在弹出框和底层的控件之间,监听点击事件
     1 /** 标题栏按钮点击事件 */
     2 - (void) titleButtonClickd:(UIButton *) button {
     3     self.titleButtonExtended = !self.titleButtonExtended;
     4    
     5     if (self.isTitleButtonExtended) {
     6         [button setImage:[UIImage imageWithNamed:@"navigationbar_arrow_up"] forState:UIControlStateNormal];
     7        
     8         UIView *window = [[UIApplication sharedApplication] keyWindow];
     9        
    10         // 中间辅助覆盖层(帮助隐藏弹出框)
    11         UIButton *coverLayer = [UIButton buttonWithType:UIButtonTypeCustom];
    12         coverLayer.frame = window.bounds;
    13         coverLayer.backgroundColor = [UIColor blackColor];
    14         coverLayer.alpha = 0.2;
    15         [window addSubview:coverLayer];
    16         [coverLayer addTarget:self action:@selector(coverLayerClicked:) forControlEvents:UIControlEventTouchUpInside];
    17        
    18         // 弹出框
    19         UIImageView *popView = [[UIImageView alloc] init];
    20         self.popView = popView;
    21         popView.size = CGSizeMake(200, 200);
    22         popView.centerX = window.width * 0.5;
    23         popView.y = 55;
    24         popView.userInteractionEnabled = YES;
    25        
    26         popView.image = [UIImage resizedImage:@"popover_background"];
    27         [window addSubview:popView];
    28        
    29     } else {
    30         [button setImage:[UIImage imageWithNamed:@"navigationbar_arrow_down"] forState:UIControlStateNormal];
    31     }
    32 }
    33 
    34 /** 辅助覆盖层点击事件 */
    35 - (void) coverLayerClicked:(UIButton *) button {
    36     if (self.isTitleButtonExtended) {
    37         [button removeFromSuperview];
    38         [self.popView removeFromSuperview];
    39         [self titleButtonClickd:self.titleButton];
    40     }
    41 }
     
    popView
     
     
    (3)由于弹出框功能可能在多处用到,而且让控制器负责创建不合适,所以封装成一个类
    封装成“弹出菜单”类HVWPopMenu(继承UIView)
    内部包含:
    背景图片
    遮盖UIButton
    一个内容界面 (如tableViewController),作为背景图片的子控件
     
     1 //
     2 //  HVWPopMenu.h
     3 //  HVWWeibo
     4 //
     5 //  Created by hellovoidworld on 15/2/2.
     6 //  Copyright (c) 2015年 hellovoidworld. All rights reserved.
     7 //
     8 
     9 #import <UIKit/UIKit.h>
    10 
    11 typedef enum {
    12     PopMenuArrowLeft,
    13     PopMenuArrowMid,
    14     PopMenuArrowRight
    15 } PopMenuArrow;
    16 
    17 @class HVWPopMenu;
    18 @protocol HVWPopMenuDelegate <NSObject>
    19 
    20 @optional
    21 - (void) popMenuDidHideMenu:(HVWPopMenu *) popMenu;
    22 
    23 @end
    24 
    25 @interface HVWPopMenu : UIView
    26 
    27 /** 背景兼内容容器 */
    28 @property(nonatomic, strong) UIImageView *backgroundContainer;
    29 
    30 #pragma mark - 成员属性
    31 /** 遮盖夹层 */
    32 @property(nonatomic, strong) UIButton *coverLayer;
    33 
    34 /** 内容控件 */
    35 @property(nonatomic, strong) UIView *contentView;
    36 
    37 /** 箭头位置 */
    38 @property(nonatomic, assign) PopMenuArrow popMenuArrow;
    39 
    40 /** 遮盖夹层透明标识 */
    41 @property(nonatomic, assign, getter=isDimCoverLayer) BOOL dimCoverLayer;
    42 
    43 /** 代理 */
    44 @property(nonatomic, weak) id<HVWPopMenuDelegate> delegate;
    45 
    46 
    47 #pragma mark - 初始化方法
    48 - (instancetype) initWithContentView:(UIView *) contentView;
    49 + (instancetype) popMenuWithContentView:(UIView *) contentView;
    50 
    51 #pragma mark - 使用方法
    52 /** 弹出 */
    53 - (void) showMenuInRect:(CGRect) rect;
    54 
    55 /** 隐藏 */
    56 - (void) hideMenu;
    57 
    58 
    59 @end
     
      1 //
      2 //  HVWPopMenu.m
      3 //  HVWWeibo
      4 //
      5 //  Created by hellovoidworld on 15/2/2.
      6 //  Copyright (c) 2015年 hellovoidworld. All rights reserved.
      7 //
      8 
      9 #import "HVWPopMenu.h"
     10 
     11 @implementation HVWPopMenu
     12 
     13 #pragma mark - 初始化方法
     14 - (instancetype) initWithContentView:(UIView *) contentView {
     15     if (self = [super init]) {
     16         self.contentView = contentView;
     17     }
     18    
     19     return self;
     20 }
     21 
     22 + (instancetype) popMenuWithContentView:(UIView *) contentView {
     23     return [[self alloc] initWithContentView:contentView];
     24 }
     25 
     26 /** 初始化子控件 */
     27 - (instancetype)initWithFrame:(CGRect)frame {
     28     self = [super initWithFrame:frame];
     29     if (self) {
     30         // 中间辅助覆盖层(帮助隐藏弹出框)
     31         UIButton *coverLayer = [UIButton buttonWithType:UIButtonTypeCustom];
     32         self.coverLayer = coverLayer;
     33         [self setDimCoverLayer:YES];
     34         [coverLayer addTarget:self action:@selector(coverLayerClicked) forControlEvents:UIControlEventTouchUpInside];
     35         [self addSubview:coverLayer];
     36        
     37         // 添加背景容器
     38         UIImageView *backgroundContainer = [[UIImageView alloc] init];
     39         self.backgroundContainer = backgroundContainer;
     40         backgroundContainer.userInteractionEnabled = YES;
     41         [self setPopMenuArrow:PopMenuArrowMid];
     42         [self addSubview:backgroundContainer];
     43     }
     44    
     45     return self;
     46 }
     47 
     48 /** 遮盖夹层点击事件 */
     49 - (void) coverLayerClicked {
     50     [self hideMenu];
     51 }
     52 
     53 #pragma mark - 使用方法
     54 /** 弹出 */
     55 - (void) showMenuInRect:(CGRect) rect {
     56     // 准备添加到当前主窗口上
     57     UIView *window = [[UIApplication sharedApplication] keyWindow];
     58     self.frame = window.bounds;
     59     [window addSubview:self];
     60    
     61     self.coverLayer.frame = window.bounds;
     62     self.backgroundContainer.frame = rect;
     63    
     64     // 添加内容控件
     65     if (self.contentView) {
     66         CGFloat topMargin = 12;
     67         CGFloat leftMargin = 5;
     68         CGFloat bottomMargin = 8;
     69         CGFloat rightMargin = 5;
     70        
     71         self.contentView.x = leftMargin;
     72         self.contentView.y = topMargin;
     73         self.contentView.width = self.backgroundContainer.width - leftMargin - rightMargin;
     74         self.contentView.height = self.backgroundContainer.height - topMargin - bottomMargin;
     75        
     76         [self.backgroundContainer addSubview:self.contentView];
     77     }
     78 }
     79 
     80 /** 隐藏 */
     81 - (void) hideMenu {
     82     if ([self.delegate respondsToSelector:@selector(popMenuDidHideMenu:)]) {
     83         [self.delegate popMenuDidHideMenu:self];
     84     }
     85    
     86     [self removeFromSuperview];
     87 }
     88 
     89 #pragma mark - 特性设置
     90 /** 设置遮盖夹层是否透明 */
     91 - (void)setDimCoverLayer:(BOOL)dimCoverLayer {
     92     if (dimCoverLayer) { // 需要半透明模糊效果的
     93         self.coverLayer.backgroundColor = [UIColor blackColor];
     94         self.coverLayer.alpha = 0.2;
     95     } else { // 全透明
     96         self.coverLayer.backgroundColor = [UIColor clearColor];
     97         self.coverLayer.alpha = 1.0;
     98     }
     99 }
    100 
    101 
    102 /** 设置弹出菜单顶部箭头位置:左、中、右 */
    103 - (void)setPopMenuArrow:(PopMenuArrow)popMenuArrow {
    104     _popMenuArrow = popMenuArrow;
    105    
    106     switch (popMenuArrow) {
    107         case PopMenuArrowLeft:
    108             self.backgroundContainer.image = [UIImage resizedImage:@"popover_background_left"];
    109             break;
    110         case PopMenuArrowMid:
    111             self.backgroundContainer.image = [UIImage resizedImage:@"popover_background"];
    112             break;
    113         case PopMenuArrowRight:
    114             self.backgroundContainer.image = [UIImage resizedImage:@"popover_background_right"];
    115             break;
    116         default:
    117             break;
    118     }
    119 }
    120 
    121 @end
     
     1 //  HVWHomeViewController.m
     2 /** 标题栏按钮点击事件 */
     3 - (void) titleButtonClickd:(UIButton *) button {
     4     self.titleButtonExtended = !self.titleButtonExtended;
     5    
     6     if (self.isTitleButtonExtended) {
     7         [button setImage:[UIImage imageWithNamed:@"navigationbar_arrow_up"] forState:UIControlStateNormal];
     8        
     9         // 添加弹出菜单
    10         UITableView *tableView = [[UITableView alloc] init];
    11         HVWPopMenu *popMenu = [HVWPopMenu popMenuWithContentView:tableView];
    12         popMenu.delegate = self;
    13         popMenu.dimCoverLayer = YES; // 模糊遮盖
    14         popMenu.popMenuArrow = PopMenuArrowMid; // 中部箭头
    15        
    16         // 弹出
    17         [popMenu showMenuInRect:CGRectMake(50, 55, 200, 300)];
    18        
    19     } else {
    20         [button setImage:[UIImage imageWithNamed:@"navigationbar_arrow_down"] forState:UIControlStateNormal];
    21     }
    22 }
    23 
    24 #pragma mark - HVWPopMenuDelegate
    25 - (void)popMenuDidHideMenu:(HVWPopMenu *)popMenu {
    26     UIButton *titleButton = (UIButton *)self.navigationItem.titleView;
    27     [self titleButtonClickd:titleButton];
    28 }
     
     
  • 相关阅读:
    大话设计模式之代理模式
    大话设计模式之装饰者模式
    策略模式与简单工厂模式
    一个简单的使用Quartz和Oozie调度作业给大数据计算平台执行
    oozie JAVA Client 编程提交作业
    HashMap分析及散列的冲突处理
    cmp排序hdoj 1106排序
    定义member【C++】cstddef中4个定义
    目录启动CXF启动报告LinkageError异常以及Java的endorsed机制
    算法代码[置顶] 机器学习实战之KNN算法详解
  • 原文地址:https://www.cnblogs.com/hellovoidworld/p/4270174.html
Copyright © 2011-2022 走看看