iOS 微信右上角下拉菜单效果之CMPopTipView,各种角度各种位置

早之前在项目中写了一个类似微信右上角下拉的菜单封装,但是是写死的,当时根本

没有考虑到去其他地方弹出这个东西,虽然看起来弹个窗出来很简单,但是你位子不确

定之后弹出来是有点麻烦的,反正我总是觉得,我们能想到的,老外早就想到了,多给自己弄点工具库,多看看源码,指不定哪天我也搞出一个库来,世界

上有项目经理这种东西,那就没有什么需求是不可能的,各位手头上多准备点工具还是非常有必要的。

先看图:

需求是这样的,点击分类的按钮,竟然不Push到另一个VC去,非要弹个窗出来

但是像我这样的读书人这么有素质的,心里肯定是这么想的

OK,废话不多说,各位看官,七龙珠我已经搜集起了,你们只要看神龙就行了

CMPopTipView:https://github.com/chrismiles/CMPopTipView

Show   Time(UITableView,UICollectionView,UIImageView,UILabel都可弹)

哎呦,这妹子不错吧

Demo介绍

首先,新建一个工程,把Button创建出来,点击事件加上,先看属性

@interface ViewController () <CMPopTipViewDelegate,UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout,UITableViewDelegate,UITableViewDataSource>

@property (nonatomic,strong) CMPopTipView *roundRectButtonPopTipView;

@property (nonatomic,strong) NSMutableArray       *dataSource; //!< collectionView的数据源
@property (nonatomic,strong) GroupList            *list;       //!< 请求回来的数据
@property (nonatomic,strong) UICollectionView     *collectionView;
@property (nonatomic,strong) UIImageView          *imageView;
@property (nonatomic,strong) UIImageView          *imageView1;
@property (weak,  nonatomic) IBOutlet UILabel     *middleLabel;
@property (nonatomic,strong) NSMutableArray	      *visiblePopTipViews; //!< 可见的PopView
@property (nonatomic,strong) id				      currentPopTipViewTarget;  //!< 当前的按钮
@property (nonatomic,strong) UITableView          *tableView;
@property (nonatomic,strong) NSMutableArray       *tableDataSource;
@property (nonatomic,strong) UIButton             *gotoCartButton; // NVBar的按钮

@end

所有非NavigationItemButton的点击事件

注:该方法可以获取到已加载数据的CollectionView的理论高度

height  =
self.collectionView.collectionViewLayout.collectionViewContentSize.height;

- (IBAction)click:(UIButton *)sender
{
    // 先dismiss之前的所有popView
    [self dismissAllPopTipViews];
    // 当检测到是和之前一样的按钮,由于已经清空,那么不进行任何操作,也把容器清空,下次再点就可以下一波操作了
    if (sender == self.currentPopTipViewTarget) {
        self.currentPopTipViewTarget = nil;
    }
    else
    {
        // 没有pop的时候,先计算出collectionView的高度
        CGFloat height;
        if (sender.tag == 1000) {
            self.dataSource = [[NSMutableArray alloc] initWithArray:self.list.data.role];
            [self.collectionView reloadData];

        }
        else if (sender.tag == 1003)
        {
            self.dataSource = [[NSMutableArray alloc] initWithArray:self.list.data.list];
            [self.collectionView reloadData];

        }
        // 算高度
        height  = self.collectionView.collectionViewLayout.collectionViewContentSize.height;

        NSString *title = nil;
        NSString *msg = nil;
        CMPopTipView *popView;
        switch (sender.tag) {
            case 1000:
                self.collectionView.frame = CGRectMake(0, 0, 300, height);
                self.collectionView.alwaysBounceVertical = YES;
                // 加载自定义View
                popView = [[CMPopTipView alloc] initWithCustomView:self.collectionView];
                break;
            case 1001:
                msg = @"这是一个简单的Demo,希望大家看明白,能用在自己的项目中";
                title = @"博主是逗逼";
                // 加载title和Msg的混合
                popView = [[CMPopTipView alloc] initWithTitle:title message:msg];
                break;
            case 1002:
                self.imageView.frame = CGRectMake(0, 0, 350, 300);
                popView = [[CMPopTipView alloc] initWithCustomView:self.imageView];
                break;
            case 1003:
                self.collectionView.frame = CGRectMake(0, 0, 300, height>400?400:height);
                self.collectionView.alwaysBounceVertical = YES;
                popView = [[CMPopTipView alloc] initWithCustomView:self.collectionView];
                break;
            case 1004:
                msg = @"With groups, Xcode stores in the project a reference to each individual file.";
                title = @"博主我爱你";
                popView = [[CMPopTipView alloc] initWithTitle:title message:msg];
                break;
            case 1005:
                self.imageView1.frame = CGRectMake(0, 0, 350, 300);
                popView = [[CMPopTipView alloc] initWithCustomView:self.imageView1];
                break;

            default:
                break;
        }
        popView.delegate = self;
        popView.cornerRadius = 5;
        // 是否有阴影
        //popView.hasShadow = YES;
        // 是否有梯度
        //popView.hasGradientBackground = NO;
        popView.backgroundColor = [UIColor colorWithRed:arc4random() % 256 / 255.0 green:arc4random() % 256 / 255.0 blue:arc4random() % 256 / 255.0 alpha:1];
        popView.textColor = [UIColor colorWithRed:arc4random() % 256 / 255.0 green:arc4random() % 256 / 255.0 blue:arc4random() % 256 / 255.0 alpha:1];
        // 0是Slide  1是pop  2是Fade但是有问题,用前两个就好了
        popView.animation = arc4random() % 1;
        // 立体效果,默认是YES
        popView.has3DStyle = arc4random() % 1;
        // 是否点击任意位子就影藏
        //popView.dismissTapAnywhere = YES;
        // 是否自定影藏
        //[popView autoDismissAnimated:YES atTimeInterval:5.0];

        [popView presentPointingAtView:sender inView:self.view animated:YES];
        [self.visiblePopTipViews addObject:popView];
        self.currentPopTipViewTarget = sender;
    }

}

代理方法和销毁PopView的方法

// 点击的时候取消PopView
- (void)dismissAllPopTipViews
{
    while ([self.visiblePopTipViews count] > 0) {
        CMPopTipView *popTipView = [self.visiblePopTipViews objectAtIndex:0];
        [popTipView dismissAnimated:YES];
        [self.visiblePopTipViews removeObjectAtIndex:0];
    }
}
// PopView的代理,当Pop消失的时候调用
- (void)popTipViewWasDismissedByUser:(CMPopTipView *)popTipView
{
    [self dismissAllPopTipViews];
    self.currentPopTipViewTarget = nil;
    NSLog(@"消失了");
    self.roundRectButtonPopTipView = nil;
}

下面是CMPopTipView的初始化属性,大家可自行修改测试

例如圆角cornerRadius是默认10,如果不需要圆角就可以去掉

// 默认值
//- (id)initWithFrame:(CGRect)frame
//{
//    if ((self = [super initWithFrame:frame])) {
//        // Initialization code
//        self.opaque = NO;
//
//        _topMargin = 2.0;
//        _pointerSize = 12.0;
//        _sidePadding = 2.0;
//        _borderWidth = 1.0;
//
//        self.textFont = [UIFont boldSystemFontOfSize:14.0];
//        self.textColor = [UIColor whiteColor];
//        self.textAlignment = NSTextAlignmentCenter;
//        self.backgroundColor = [UIColor colorWithRed:62.0/255.0 green:60.0/255.0 blue:154.0/255.0 alpha:1.0];
//        self.has3DStyle = YES;
//        self.borderColor = [UIColor blackColor];
//        self.hasShadow = YES;
//        self.animation = CMPopTipAnimationSlide;
//        self.dismissTapAnywhere = NO;
//        self.preferredPointDirection = PointDirectionAny;
//        self.hasGradientBackground = YES;
//        self.cornerRadius = 10.0;
//    }
//    return self;
//}

然后,我们再看看给UINavigationBar上面的UIBarButtonItem的方法调用

其他逻辑方法都基本一致,只是调用的最终弹窗方法不同

popView presentPointingAtBarButtonItem: animated:

// 点击了NavigationController上的按钮
- (void)gotoCart:(UIButton *)sender
{
    [self dismissAllPopTipViews];
    if (sender == self.currentPopTipViewTarget) {
        self.currentPopTipViewTarget = nil;
    }
    else
    {
        CGFloat height;
        [self.tableView reloadData];
        height  = self.tableView.contentSize.height;
        self.tableView.frame = CGRectMake(0, 0, 100, height);
        self.tableView.backgroundColor = [UIColor blackColor];
        self.tableView.alwaysBounceVertical = YES;
        CMPopTipView *popView = [[CMPopTipView alloc] initWithCustomView:self.tableView];
        popView.delegate = self;
        popView.cornerRadius = 5;
        popView.backgroundColor = [UIColor blackColor];
        popView.textColor = [UIColor whiteColor];
        // 0是Slide  1是pop  2是Fade但是有问题,用前两个就好了
        popView.animation = arc4random() % 1;
        // 立体效果,默认是YES
        popView.has3DStyle = arc4random() % 1;
        //        popView.dismissTapAnywhere = YES;
        //        [popView autoDismissAnimated:YES atTimeInterval:5.0];

        [popView presentPointingAtView:sender inView:self.view animated:YES];

        // 如果是原生的UIBarButtonItem,那么就调用这个方法
//        popView presentPointingAtBarButtonItem:<#(UIBarButtonItem *)#> animated:<#(BOOL)#>
        [self.visiblePopTipViews addObject:popView];
        self.currentPopTipViewTarget = sender;
    }
}

以上的主要方法差不多介绍完了,出来看效果

他默认的尖尖Point三角形底边和高度是相等的,这样的Point看起来就会比较矮小,各位

如果有兴趣跑起来Demo看看就一定会想改一下

来看看他的源码,这种View的显示肯定在drawRect:的方法里面完成的

只截图该方法里面的一部分代码,我们只要把他处理的X坐标修改就行了

CGRect bubbleRect = [self bubbleFrame];

	CGContextRef c = UIGraphicsGetCurrentContext(); 

    CGContextSetRGBStrokeColor(c, 0.0, 0.0, 0.0, 1.0);	// black
	CGContextSetLineWidth(c, self.borderWidth);

	CGMutablePathRef bubblePath = CGPathCreateMutable();

	if (_pointDirection == PointDirectionUp) {
        // 这里的原点是point的尖尖
		CGPathMoveToPoint(bubblePath, NULL, _targetPoint.x+_sidePadding, _targetPoint.y);
        // 注意这里的X轴是默认给的_pointer的宽度,这个pointer是个正三角形,但是我们要个等腰的,所有X轴加上_pointer/2,Y轴加上_pointer,OK
		CGPathAddLineToPoint(bubblePath, NULL, _targetPoint.x+_sidePadding+_pointerSize/2, _targetPoint.y+_pointerSize);

		CGPathAddArcToPoint(bubblePath, NULL,
							bubbleRect.origin.x+bubbleRect.size.width, bubbleRect.origin.y,
							bubbleRect.origin.x+bubbleRect.size.width, bubbleRect.origin.y+_cornerRadius,
							_cornerRadius);
		CGPathAddArcToPoint(bubblePath, NULL,
							bubbleRect.origin.x+bubbleRect.size.width, bubbleRect.origin.y+bubbleRect.size.height,
							bubbleRect.origin.x+bubbleRect.size.width-_cornerRadius, bubbleRect.origin.y+bubbleRect.size.height,
							_cornerRadius);
		CGPathAddArcToPoint(bubblePath, NULL,
							bubbleRect.origin.x, bubbleRect.origin.y+bubbleRect.size.height,
							bubbleRect.origin.x, bubbleRect.origin.y+bubbleRect.size.height-_cornerRadius,
							_cornerRadius);
		CGPathAddArcToPoint(bubblePath, NULL,
							bubbleRect.origin.x, bubbleRect.origin.y,
							bubbleRect.origin.x+_cornerRadius, bubbleRect.origin.y,
							_cornerRadius);
        // 这里也要改掉,不然自动关闭的时候就不是等腰三角形了
		CGPathAddLineToPoint(bubblePath, NULL, _targetPoint.x+_sidePadding-_pointerSize/2, _targetPoint.y+_pointerSize);
	}
	else {
        // 上面改了那么下面也要改掉
		CGPathMoveToPoint(bubblePath, NULL, _targetPoint.x+_sidePadding, _targetPoint.y);
		CGPathAddLineToPoint(bubblePath, NULL, _targetPoint.x+_sidePadding-_pointerSize/2, _targetPoint.y-_pointerSize);

		CGPathAddArcToPoint(bubblePath, NULL,
							bubbleRect.origin.x, bubbleRect.origin.y+bubbleRect.size.height,
							bubbleRect.origin.x, bubbleRect.origin.y+bubbleRect.size.height-_cornerRadius,
							_cornerRadius);
		CGPathAddArcToPoint(bubblePath, NULL,
							bubbleRect.origin.x, bubbleRect.origin.y,
							bubbleRect.origin.x+_cornerRadius, bubbleRect.origin.y,
							_cornerRadius);
		CGPathAddArcToPoint(bubblePath, NULL,
							bubbleRect.origin.x+bubbleRect.size.width, bubbleRect.origin.y,
							bubbleRect.origin.x+bubbleRect.size.width, bubbleRect.origin.y+_cornerRadius,
							_cornerRadius);
		CGPathAddArcToPoint(bubblePath, NULL,
							bubbleRect.origin.x+bubbleRect.size.width, bubbleRect.origin.y+bubbleRect.size.height,
							bubbleRect.origin.x+bubbleRect.size.width-_cornerRadius, bubbleRect.origin.y+bubbleRect.size.height,
							_cornerRadius);
		CGPathAddLineToPoint(bubblePath, NULL, _targetPoint.x+_sidePadding+_pointerSize/2, _targetPoint.y-_pointerSize);
	}

	CGPathCloseSubpath(bubblePath);

    CGContextSaveGState(c);
	CGContextAddPath(c, bubblePath);
	CGContextClip(c);

效果如下:

本次Demo地址:https://github.com/DeftMKJ/Pop 需要的小伙伴自行去尝试新的弹窗

貌似下载不了,说什么文件名太长了,反正不懂为什么,需要的同学可以像我拿或者直接

打开你的终端按以下操作clone一下

trainingvdi:~ MKJ$ cd ~/Desktop

trainingvdi:Desktop MKJ$ pwd

/Users/MKJ/Desktop

trainingvdi:Desktop MKJ$ mkdir hehe

trainingvdi:Desktop MKJ$ cd hehe/

trainingvdi:hehe MKJ$ pwd

/Users/MKJ/Desktop/hehe

trainingvdi:hehe MKJ$ git clone https://github.com/DeftMKJ/Pop.git

Cloning into ‘Pop‘...

remote: Counting objects: 361, done.

remote: Total 361 (delta 0), reused 0 (delta 0), pack-reused 361

Receiving objects: 100% (361/361), 407.47 KiB | 119.00 KiB/s, done.

Resolving deltas: 100% (142/142), done.

Checking connectivity... done.

然后打开你桌面的hehe文件夹就好了

OVER~~~~~~

时间: 2024-10-19 16:49:45

iOS 微信右上角下拉菜单效果之CMPopTipView,各种角度各种位置的相关文章

iOS下拉菜单效果实现

原文链接: iOS下拉菜单效果实现 简书主页:http://www.jianshu.com/users/37f2920f6848 Github主页:https://github.com/MajorLMJ iOS开发者公会-技术1群 QQ群号:87440292 iOS开发者公会-技术2群 QQ群号:232702419 iOS开发者公会-议事区   QQ群号:413102158

纯CSS实现的二级下拉菜单效果代码实例

纯CSS实现的二级下拉菜单效果代码实例:二级下拉是最为常用的效果之一,当前的此效果一般哟结合js实现,本章节介绍一个使用纯CSS实现的二级下拉菜单效果,希望能够给需要的朋友带来一定的帮助,不过此代码也有一点浏览器兼容问题,那就是在IE6中不兼容.代码如下: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="author" conten

SharePoint 2010 隐藏个人操作Personal Action的部分内容(右上角下拉菜单)

SharePoint 2010 隐藏个人操作Personal Action的部分内容(右上角下拉菜单) 最近有个需求是隐藏个人操作Personal Action的部分内容(右上角下拉菜单),研究了一下需要更改Welcome.ascx文件. 文件位置: C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\CONTROLTEMPLATES 在母版页中可以看到,母版页引用了这个ASP.NET控

点击弹出弹性下拉菜单效果

<html><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312" /><meta name="keywords" content="站长,网页特效,js特效,广告代码,zzjs,zzjs.net,sky,www.zzjs.net,站长特效 网" /><meta name="

三种方式实现下拉菜单效果

使用3种方式实现下拉菜单效果: html/css .js方法实现下拉菜单显示隐藏.jquery方法实现下拉菜单显示隐藏 先看效果图 第一种:html/css方式实现 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>下拉菜单的实现</title> <style type="text/css"> *{margin

下拉菜单效果

之前为大家介绍过有关HTML中的一些比较炫的效果,本篇为大家介绍一些,大家在网站中经常可以见到的一种下拉菜单效果,这种菜单效果一般分为两层,当我们的鼠标经过一级菜单时,隐藏的二级菜单就会显示出来,这样即保证了页面的美观,同时又不会使页面的模块减少,甚至可以增加模块数目. 一.废话不多说,下面我们来通过HTML+CSS为大家实现一下上面的效果,首先请大家先欣赏一下效果图: 1.界面布局代码: <body> <div id="var"> <ul> <

完美解决safari、微信浏览器下拉回弹效果。

完美解决safari.微信浏览器下拉回弹效果,只保留局部回弹效果. CSS代码 .box{ overflow: auto; -webkit-overflow-scrolling: touch; } HTML代码 <body class="box"> <div class="scroll" style="height:1500px"> </div> </body> JS代码 var overscrol

用JS控制下拉菜单效果

今天,突然想复习下之前学习做导航菜单的一些知识.之后觉得下拉菜单非常好玩儿,于是自己试着用JS调出了效果.网上有众多方法,但是感觉不是很对我的胃口,我喜欢HTML/CSS/JavaScript分离着写,用户体验重要,码农审美也很重要啊,O(∩_∩)O~ 在做下拉菜单的过程中,有以下心得: 1.this是个好东西,比如在鼠标事件中,它代表此时的鼠标事件对象本身,免去去用其他方式代表改对象的麻烦: 2.getElementsByTagName或者getElementById方法获得的是一个数组,需要

div模拟select下拉菜单效果

有些时候select下拉菜单直接用css调整样式,可能会有兼容性的问题,尤其是右侧的下拉三角,很难用css控制,那怎么办呢?可以采用div模拟select下拉菜单的效果.先直接上代码了: HTML的结构如下: <!doctype html> <html> <head> <meta charset="utf-8" /> <title>div模拟下拉菜单特效</title> <style type="t