zoukankan      html  css  js  c++  java
  • 自定义PopView

    改代码是参考一个Demo直接改的,代码中有一些漏洞,如果发现其他的问题,可以下方直接留言

    .h文件

    #import <UIKit/UIKit.h>
    typedef void(^PopoverBlock)(NSInteger index);
    @interface CustomPopView : UIView
    //@property(nonatomic,copy)void(^block)(int index);
    //-(void)setDataArr:(NSArray *)titleArr withView:(id *)view withBlock:(void(^)(NSString *a))block;
    @property (nonatomic, copy) NSArray *menuTitles;
    @property(nonatomic,copy)void(^PopoverHiddenBlock)(BOOL isHidden );
    - (void)showFromView:(id)aView selected:(PopoverBlock)selected;
    @end
    
    
    @interface PopoverArrow : UIView
    
    @end
    

     .m文件

    #import "CustomPopView.h"
    // 字体大小
    #define kPopoverFontSize 14.f
    
    // 十六进制颜色
    #define UIColorFromRGB(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]
    
    #define SCREEN_W [UIScreen mainScreen].bounds.size.width
    #define SCREEN_H [UIScreen mainScreen].bounds.size.height
    
    // 箭头高度
    #define kArrowH 8
    // 箭头宽度
    #define kArrowW 15
    //每行的高度
    #define CELL_HEIGHT 38
    //
    #define Identifier @"cell"
    
    
    // 边框颜色
    #define kBorderColor UIColorFromRGB(0xE1E2E3)
    @interface CustomPopView () <UITableViewDelegate, UITableViewDataSource>
    {
        PopoverBlock _selectedBlock;
        UIView *_backgroundView;
        PopoverArrow *_arrowView;
    }
    
    @property (nonatomic, retain) UITableView *tableView;
    
    @end
    
    @implementation CustomPopView
    - (instancetype)initWithFrame:(CGRect)frame
    {
        if (!(self = [super initWithFrame:frame])) return nil;
        
        self.backgroundColor = [UIColor clearColor];
        
        // 箭头
        _arrowView = [PopoverArrow new];
        [self addSubview:_arrowView];
    
        // tableView放在箭头底下, 用于箭头挡住tableView边框
        [self insertSubview:self.tableView belowSubview:_arrowView];
        return self;
    }
    
    - (void)layoutSubviews
    {
        [super layoutSubviews];
        
        // 设置tableView默认的分割线起终点位置
        if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {
            [self.tableView setSeparatorInset:UIEdgeInsetsZero];
        }
        if ([self.tableView respondsToSelector:@selector(setLayoutMargins:)]) {
            [self.tableView setLayoutMargins:UIEdgeInsetsZero];
        }
        
        self.tableView.layer.cornerRadius  = 5.f;
        self.tableView.layer.borderColor   = kBorderColor.CGColor;
        self.tableView.layer.borderWidth   = 1.f;
    }
    
    #pragma mark -- getter
    
    - (UITableView *)tableView
    {
        if (_tableView) return _tableView;
        
        _tableView = [UITableView new];
        
        _tableView.delegate        = self;
        _tableView.dataSource      = self;
        _tableView.rowHeight       = CELL_HEIGHT;
        _tableView.backgroundColor = [UIColor whiteColor];
        _tableView.showsVerticalScrollIndicator = NO;
        [_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:Identifier];
        _tableView.tableFooterView = UIView.new;
        
        return _tableView;
    }
    
    #pragma mark -- delegate
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return self.menuTitles.count;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Identifier];
        cell.textLabel.font   = [UIFont systemFontOfSize:kPopoverFontSize];
        cell.textLabel.text   = [self.menuTitles objectAtIndex:indexPath.row];
        return cell;
    }
    
    - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
            [cell setSeparatorInset:UIEdgeInsetsZero];
        }
        if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
            [cell setLayoutMargins:UIEdgeInsetsZero];
        }
    }
    
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        [UIView animateWithDuration:0.25 animations:^{
            self.alpha = 0;
        } completion:^(BOOL finished) {
            [_backgroundView removeFromSuperview];
            _backgroundView = nil;
            
            if (_selectedBlock) {
                _selectedBlock(indexPath.row);
            }
            
            [self removeFromSuperview];
        }];
    }
    
    #pragma mark -- private
    // 点击透明层隐藏
    - (void)hide
    {
        [UIView animateWithDuration:0.25 animations:^{
            self.alpha = 0;
        } completion:^(BOOL finished) {
            [_backgroundView removeFromSuperview];
            _backgroundView = nil;
            if(self.PopoverHiddenBlock){
                self.PopoverHiddenBlock(YES);
            }
            [self removeFromSuperview];
        }];
    }
    
    #pragma mark -- public
    
    /*!
     *  @author lifution
     *
     *  @brief 显示弹窗
     *
     *  @param aView    箭头指向的控件
     *  @param selected 选择完成回调
     */
    - (void)showFromView:(id)aView selected:(PopoverBlock)selected
    {
        if (selected) _selectedBlock = selected;
        //aView只能传两种参数,一种是UIView 另一种UIBarButtonItem
        if(!([aView isKindOfClass:[UIView class]] || [aView isKindOfClass:[UIBarButtonItem class]])){
            return;
        }
        UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
        // 背景遮挡
        _backgroundView = UIView.new;
        _backgroundView.frame = keyWindow.bounds;
        _backgroundView.backgroundColor = [UIColor blackColor];
        _backgroundView.alpha = 0.2;
        _backgroundView.userInteractionEnabled = YES;
        [_backgroundView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hide)]];
        [keyWindow addSubview:_backgroundView];
        // 刷新数据更新contentSize
        [self.tableView reloadData];
        
        // 获取触发弹窗的按钮在window中的坐标
        CGRect triggerRect ;
        if([aView isKindOfClass:[UIView class]]){
            UIView *view = (UIView *)aView;
              triggerRect = [view convertRect:view.bounds toView:keyWindow];
        }else{
            UIView *bgView = [aView valueForKey:@"_view"];
            triggerRect = [bgView convertRect:bgView.bounds toView: keyWindow];
        }
        // 箭头指向的中心点
        
        CGFloat arrowCenterX = CGRectGetMaxX(triggerRect)-CGRectGetWidth(triggerRect)/2;
        
        // 取得标题中的最大宽度
        CGFloat maxWidth = 0;
        for (id obj in self.menuTitles) {
            if ([obj isKindOfClass:[NSString class]]) {
                CGSize titleSize = [obj sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:kPopoverFontSize]}];
                if (titleSize.width > maxWidth) {
                    maxWidth = titleSize.width;
                }
            }
        }
        
        CGFloat curWidth  = ((maxWidth+80)>SCREEN_W-30)?SCREEN_W-30:(maxWidth+80);
        CGFloat curHeight = CELL_HEIGHT*self.menuTitles.count+kArrowH;
        CGFloat curX      = arrowCenterX-curWidth/2;
        CGFloat curY      = CGRectGetMaxY(triggerRect)+10;
        
        // 如果箭头指向点距离屏幕右边减去5px不足curWidth的一半的话就重新设置curX
        if ((SCREEN_W-arrowCenterX-5)<curWidth/2) {
            curX = curX-(curWidth/2-(SCREEN_W-arrowCenterX-5));
        }
        // 如果箭头指向点距离屏幕左边加上5px不足curWidth的一半的话就重新设置curX
        if (arrowCenterX+5<curWidth/2) {
            curX = curX+(curWidth/2-arrowCenterX)+5;
        }
        
        //如果高度大于10行,则最高按10计算
        if(curHeight>CELL_HEIGHT*10+kArrowH){
            curHeight = CELL_HEIGHT*10+kArrowH;
        }
        
        self.frame           = CGRectMake(curX, curY - 18, curWidth, curHeight);
        _arrowView.frame     = CGRectMake(arrowCenterX-curX-kArrowW/2, 0, kArrowW, kArrowH+1);
        // 箭头高度 +1 遮挡住tableView的边框
        self.tableView.frame = CGRectMake(0, kArrowH, curWidth,curHeight - kArrowH );
        [keyWindow addSubview:self];
        
        self.alpha = 0;
        [UIView animateWithDuration:0.3 animations:^{
            self.alpha = 1;
        }];
    }
    
    @end
    
    // 箭头
    @implementation PopoverArrow
    
    - (instancetype)initWithFrame:(CGRect)frame
    {
        if (!(self = [super initWithFrame:frame])) return nil;
        
        self.backgroundColor = [UIColor clearColor];
        
        return self;
    }
    
    // Only override drawRect: if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    - (void)drawRect:(CGRect)rect {
        [super drawRect:rect];
        // Drawing code
        CGSize curSize = rect.size;
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextSetLineWidth(context, 1);
        CGContextSetStrokeColorWithColor(context, kBorderColor.CGColor);
        CGContextSetFillColorWithColor(context, UIColor.whiteColor.CGColor);
        CGContextBeginPath(context);
        CGContextMoveToPoint(context, 0, curSize.height);
        CGContextAddLineToPoint(context, curSize.width/2, 0);
        CGContextAddLineToPoint(context, curSize.width, curSize.height);
        CGContextDrawPath(context, kCGPathFillStroke);
    }
    
    @end
    

     使用:

    view = [CustomPopView new];
    view.menuTitles = @[@"1",@"2",@"3"]; 
    UIBarButtonItem *item = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addBtnClick:)];
    self.navigationItem.rightBarButtonItem = item;
    
    -(void)addBtnClick:(UIBarButtonItem *)item{
        [view showFromView:item selected:^(NSInteger index) {
            
        }];
    }
    
    
    
  • 相关阅读:
    Django xadmin
    Linux 目录
    服务器的组件
    C# 判断数字的小方法
    Eclipse快捷键
    安卓资源与ID不对应的问题
    Java中Runnable和Thread的区别
    View的setOnClickListener的添加方法
    如何实现消息框风格的Activity
    安卓开发的在线调试
  • 原文地址:https://www.cnblogs.com/hualuoshuijia/p/9983821.html
Copyright © 2011-2022 走看看