精华内容
下载资源
问答
  • 微信程序实现点赞气泡效果博客的图片资源,现已上传至仓库。博客链接https://blog.csdn.net/Aurora_____/article/details/109775569
  • 小气泡功能在app中的两种实现方案

    千次阅读 2015-07-23 16:59:04
    看到别人的app有小气泡感觉很好玩,并且他们的宽高都不超过所在单元格的宽高,其实它也没有什么神奇我们可以用两种方案来实现:控件方案和多视图方案。 第一种方案:控件法。已经实现一个页面有一个气泡的情况。...

    看到别人的app有小气泡感觉很好玩,并且他们的宽高都不超过所在单元格的宽高,其实它也没有什么神奇我们可以用两种方案来实现:控件方案和多视图方案。
    第一种方案:控件法。已经实现一个页面有一个气泡的情况。可以抽象出一个类,调用它就可以了,理论上也可以实现多气泡的情况。可以通过申请一个小气泡对象,制定小黑条的宽度,预置显示的内容。通过self.buttonH5.buttonPressed = ^(NSInteger tag)来实现点击小黑框内容的页面跳转。
    实际页面:
    这里写图片描述

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        UITableViewCell *cell = nil;
        if (indexPath.section == 1) {
        .
        .
        .
                 if (![[self.dictData valueForKey:@"consigneeTel"]  isEqualToString:@""])
    //        if (2 == [[self.dictData valueForKey:@"quickType"] longValue])
            {
                //普通发单
    
    //            if (1 == [[self.dictData valueForKey:@"quickType"] longValue])
                {
                    UIButton* buttonDetail =[UIButton buttonWithType:UIButtonTypeCustom];
                    buttonDetail.frame = CGRectMake(0, 0, 40 , 40);
                    UIImage *image1 = [UIImage imageNamed:@"prompt_fare_card"];
                    [buttonDetail setImage:image1 forState:UIControlStateNormal];
                    [buttonDetail.imageView sizeToFit];
                    [buttonDetail addTarget:self action:@selector(buttonDetail) forControlEvents:UIControlEventTouchUpInside];
                    [buttonDetail setCenter:CGPointMake(WINDOW_WIDTH-18, labelSuceessed.center.y)];
                    [contentCell addSubview:buttonDetail];
    
    
                    long lEstimated = [[self.dictData valueForKey:@"estimated"] longValue];
                    if(1 == lEstimated)
                    {
                        self.buttonH5 = [[ButtonDetailH5 alloc]initWithFrame:CGRectMake(0, 0, 257, 44)];
                        self.buttonH5.center = CGPointMake(WINDOW_WIDTH-15-self.buttonH5.bounds.size.width/2, buttonDetail.center.y-25);
    //                    float lDistance = [[self.dictData valueForKey:@"walkingDistance"] longValue];
    //                    lDistance = lDistance/1000;
                        _fFreight = [[self.dictData valueForKey:@"freight"] longValue];
                        _fFreight = _fFreight/100;
                        if(_distance >= 1000)
                        {
                            dDistance = dDistance/1000;
                            self.buttonH5.labelBut.text = [NSString stringWithFormat:@"实际配送%.2f公里,应付运费%.2f元", dDistance, _fFreight];
                        }
                        else if(_distance >= 0)
                        {
                            self.buttonH5.labelBut.text = [NSString stringWithFormat:@"实际配送%ld米,应付运费%.2f元", (long)dDistance, _fFreight];
                        }
                        else
                        {
                            self.buttonH5.labelBut.text = [NSString stringWithFormat:@"实际配送--公里,应付运费%.2f元", _fFreight];
                        }
    //                    self.buttonH5.labelBut.text = [NSString stringWithFormat:@"实际配送%.2f公里,应付运费%.2f元", lDistance, fFreight];
                    }
                    else
                    {
                        self.buttonH5 = [[ButtonDetailH5 alloc]initWithFrame:CGRectMake(0, 0, 230, 44)];
                        self.buttonH5.center = CGPointMake(WINDOW_WIDTH-15-self.buttonH5.bounds.size.width/2, buttonDetail.center.y-25);
                        self.buttonH5.labelBut.text = @"具体运费最终由实际配送里程决定";
    
                    }
                    self.buttonH5.hidden = YES;
                    __weak __typeof(self)safeSelf = self;
                    self.buttonH5.buttonPressed = ^(NSInteger tag){
                        //加载H5的位置
                        FeeWebViewController *feeWebViewController = [[FeeWebViewController alloc] init];
                        if(safeSelf.strWayBillld.length > 0)
                        {
                            feeWebViewController.waybillId = safeSelf.strWayBillld;
                            feeWebViewController.title = @"配送运费";
                            [safeSelf.navigationController pushViewController:feeWebViewController animated:YES];
                            safeSelf.buttonH5.hidden = YES;
                        }
                    };
                    [contentCell addSubview:self.buttonH5];
    
                }
           }
           .
           .
           .
        }
    }       
    
    -(void)buttonDetail{
    
        if (self.buttonH5.hidden==NO) {
              self.buttonH5.hidden = YES;
        }else{
             self.buttonH5.hidden = NO;
        }
    
    }

    下面是抽象出来的小气泡类。
    ButtonDetailH5.h

    #import <UIKit/UIKit.h>
    @interface ButtonDetailH5 : UIButton
    @property (strong, nonatomic) UIImageView *imageViewbut;
    @property (strong, nonatomic) UIImageView *imageViewbutIcon;
    @property (strong, nonatomic) UILabel *labelBut;
    @property (strong, nonatomic) UIButton* buttonBut;
    @property (copy, nonatomic) void(^buttonPressed)(NSInteger tag);
    -(instancetype)initWithFrame:(CGRect)frame;
    @end

    ButtonDetailH5.m

    
    #import "ButtonDetailH5.h"
    
    @implementation ButtonDetailH5
    -(instancetype)initWithFrame:(CGRect)frame{
        if (self = [super initWithFrame:frame]) {
            self.imageViewbut = [[UIImageView alloc]initWithFrame:CGRectMake(12, -2, frame.size.width, frame.size.height-5)];
            UIImage *image = [UIImage imageNamed:@"prompt_fare_box_card"];
            //UIEdgeInsets insets = UIEdgeInsetsMake(5.0f, 5.0f, 5.0f, 5.0f);
            NSInteger leftCapWidth = image.size.width * 0.5f;
            // 顶端盖高度
            NSInteger topCapHeight = image.size.height * 0.5f;
            // 重新赋值
            image = [image stretchableImageWithLeftCapWidth:leftCapWidth topCapHeight:topCapHeight];
            self.imageViewbut.image = image;
            [self addSubview:self.imageViewbut];
    
    
    
    
            self.imageViewbutIcon = [[UIImageView alloc]initWithFrame:CGRectMake(frame.size.width-7, frame.size.height-5 - 2, 8, 4)];
    
            self.imageViewbutIcon.image = [UIImage imageNamed:@"prompt_fare_arrow_card.png"];
            [self addSubview:self.imageViewbutIcon];
    
    
    
    
            self.labelBut = [[UILabel alloc]initWithFrame:self.imageViewbut.frame];
            self.labelBut.text = @"  实际配送125.565公里,应付运费134.34元";
            self.labelBut.font = [UIFont systemFontOfSize:12];
            self.labelBut.center = CGPointMake(self.labelBut.center.x+10, self.labelBut.center.y);
            self.labelBut.textColor = [UIColor whiteColor];
            self.labelBut.textAlignment = NSTextAlignmentLeft;
            [self addSubview:self.labelBut];
    
            self.buttonBut = [UIButton buttonWithType:UIButtonTypeCustom];
            [self.buttonBut setTitle:@"详情" forState:UIControlStateNormal];
            self.buttonBut.frame = CGRectMake(frame.size.width-40 + 15, -4, 44, 44);
            self.buttonBut.titleLabel.font = [UIFont systemFontOfSize:12];
            [self.buttonBut setTitleColor:[UIColor colorWithHex:0x007aff] forState:UIControlStateNormal];
            [self.buttonBut addTarget:self action:@selector(button:) forControlEvents:UIControlEventTouchUpInside];
            self.buttonBut.tag = 2;
    
            [self addSubview:self.buttonBut];
            self.tag = 1;
            [self addTarget:self action:@selector(button:) forControlEvents:UIControlEventTouchUpInside];
    
    
    
        }
        return self;
    }
    -(void)button:(UIButton* )sender{
        if (self.buttonPressed) {
            self.buttonPressed(sender.tag);
        }
    }
    
    
    @end
    

    第二种方案:多视图方案,对不同单元格斗加入2个uiview(一个显示长内容信息,另一个显示短内容信息),通过数据源控制uiview的显示和隐藏。又称多气泡法,有无气泡不确定。具体是一张表有很多记录,每个单元格都有可能有小气泡,也可能没有(本质是有只是把它隐藏了),点击小气泡会显示小黑条,每个小黑条显示的内容不长度不同,点击小黑条进入不同的h5页面,点击其它非气泡按钮,滚动表格,选择表格的行事件小黑条隐藏,点击气泡若以前有小黑条显示就隐藏小黑条并显示本气泡的小黑条,若没有只显示本气泡的小黑条。这种气泡我采用的是对每个cell建立一个带xib对象,增加相关控件。有气泡按钮过小增加透明按钮的处理,分解小黑条的按钮图片文字3个button。在表格加载函数中处理小气泡和小黑条的显示和指针记录。点击气泡时我记录了当前数据的行数,和显示UIVIEW。我定义两个UIVIEW为显示不同长度的小黑条。
    这里写图片描述

    实际页面:多个小气泡。
    这里写图片描述

    实际页面:多个小气泡之间的互斥,只能显示一个小黑条,并且滑动表格,小黑条消失,点击小黑条跳到html5页面。
    这里写图片描述
    实际页面:多个小气泡之间的互斥,只能显示一个小黑条,并且滑动表格,小黑条消失,点击小黑条由于没有计费策略所以跳到html5页面又跳回来。
    这里写图片描述

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if((self.arratData.count <= indexPath.section) || (0== self.arratData.count))
        {
            return nil;
        }
        UITableViewCell* cell = nil;
            UITableViewCell* cell = nil;
    //    NSString *consigneeAddressStr = nil;
        long lEstimated =  0;
        double lDistance = 1001.0;
        long lQuickType = 2;
        float fFreight = 0.0;
    //    NSString * fFreightStr = nil;
        double consigneeLogitude = 0.0;
        double consigneeLatitude = 0.0;
        if ([self.strType isEqualToString:@"lanshou"]) {
                static NSString *cellIdentifier = @"OrderWaitLanLanTableViewCell";
                OrderWaitLanLanTableViewCell *cellLanShou =(OrderWaitLanLanTableViewCell*)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    
                if (!cellLanShou) {
                    UINib* nib =[UINib nibWithNibName:@"OrderWaitLanLanTableViewCell" bundle:nil];
                    [tableView registerNib:nib forCellReuseIdentifier:cellIdentifier];
                    cellLanShou = (OrderWaitLanLanTableViewCell*)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
                }
                lQuickType = [[[self.arratData  objectAtIndex:indexPath.section]valueForKey:@"quickType"] longValue];
                lEstimated = [[[self.arratData  objectAtIndex:indexPath.section]valueForKey:@"estimated"] longValue];
                consigneeLogitude = [[[self.arratData  objectAtIndex:indexPath.section]valueForKey:@"consigneeLongitude"] doubleValue];
                consigneeLatitude = [[[self.arratData  objectAtIndex:indexPath.section]valueForKey:@"consigneeLatitude"] doubleValue];
                if((0 == consigneeLogitude) || (0 == consigneeLatitude))
                {
                    cellLanShou.labelPeiSongFei.text =[NSString stringWithFormat:@"运   费:  %.2f元 (预估)", [[[self.arratData  objectAtIndex:indexPath.section]valueForKey:@"freight"] floatValue]/100];
                }
                else
                {
                    cellLanShou.labelPeiSongFei.text = [NSString stringWithFormat:@"运   费:  %.2f元", [[[self.arratData  objectAtIndex:indexPath.section]valueForKey:@"freight"] floatValue]/100];
                }
                UIImage *image = [UIImage imageNamed:@"prompt_fare_box_card"];
                NSInteger leftCapWidth = image.size.width * 0.5f;
                // 顶端盖高度
                NSInteger topCapHeight = image.size.height * 0.5f;
                // 重新赋值
                image = [image stretchableImageWithLeftCapWidth:leftCapWidth topCapHeight:topCapHeight];
    
                if((1 == lQuickType) && (1 == lEstimated) && (consigneeLatitude > 0) && (consigneeLogitude > 0))
                {
                    fFreight = [[[self.arratData  objectAtIndex:indexPath.section]valueForKey:@"freight"] longValue];
                    fFreight = fFreight/100;
                    lDistance = [[[self.arratData  objectAtIndex:indexPath.section]valueForKey:@"walkingDistance"] integerValue];
                    if(lDistance >= 0)
                    {
                        fFreight = [[[self.arratData  objectAtIndex:indexPath.section]valueForKey:@"freight"] longValue];
                        fFreight = fFreight/100;
                        if(lDistance >= 1000)
                        {
                            lDistance = lDistance/1000;
                            [cellLanShou.contentDisplayBtn setTitle:[NSString stringWithFormat:@"  实际配送%.2f公里,应付运费%.2f元", lDistance, fFreight] forState:UIControlStateNormal];
                        }
                        else
                        {
                            [cellLanShou.contentDisplayBtn setTitle:[NSString stringWithFormat:@"  实际配送%ld米,应付运费%.2f元", (long)lDistance, fFreight] forState:UIControlStateNormal];
                        }
                    }
                    else
                    {
                        [cellLanShou.contentDisplayBtn setTitle:[NSString stringWithFormat:@"  实际配送--公里,应付运费%.2f元", fFreight] forState:UIControlStateNormal];
                    }
    //                [[self.arratData  objectAtIndex:indexPath.section] setValue:@"" forKey:@"walkingRouteDistance"];
                    [cellLanShou.contentDisplayBtn setBackgroundImage:image forState:UIControlStateNormal];
                    cellLanShou.contentBtn.row = indexPath.section;
                    cellLanShou.contentBtn.contentUIView = cellLanShou.contentDetailView;
                    cellLanShou.contentBtn.contentDisplayButton = cellLanShou.contentDisplayBtn;
                    [cellLanShou.contentBtn addTarget:self action:@selector(buttonPressedContent:) forControlEvents:UIControlEventTouchUpInside];
                    cellLanShou.detailBackgroundBtn.contentUIView = cellLanShou.contentDetailView;
                    cellLanShou.detailBackgroundBtn.isShortBtn = NO;
                }
                else
                {
                    cellLanShou.contentShortBtn.contentDisplayButton = nil;
                    [cellLanShou.contentDisplayShortBtn setBackgroundImage:image forState:UIControlStateNormal];
                    cellLanShou.contentShortBtn.contentUIView = cellLanShou.contentShortDetailView;
                    cellLanShou.contentShortBtn.row = indexPath.section;
                    [cellLanShou.contentShortBtn addTarget:self action:@selector(buttonPressedContent:) forControlEvents:UIControlEventTouchUpInside];
                    cellLanShou.detailBackgroundBtn.contentUIView = cellLanShou.contentShortDetailView;
                    [cellLanShou.contentDisplayShortBtn setTitle:@"  具体运费最终由实际配送里程决定" forState:UIControlStateNormal];
                    cellLanShou.detailBackgroundBtn.isShortBtn = YES;
                }
                cellLanShou.detailBackgroundBtn.row = indexPath.section;
                [cellLanShou.detailBackgroundBtn addTarget:self action:@selector(buttonPressedDetail:) forControlEvents:UIControlEventTouchUpInside];
                if(2 == lQuickType)
                {
                    cellLanShou.contentDetailView.hidden = YES;
                    cellLanShou.contentShortDetailView.hidden = YES;
                    cellLanShou.detailBackgroundBtn.hidden = YES;
                    cellLanShou.detailBtn.hidden = YES;
                }
                else
                {
                    cellLanShou.detailBackgroundBtn.hidden = NO;
                    cellLanShou.detailBtn.hidden = NO;
                    if((_iRow >= 0) && !_bHidden && (_iRow == indexPath.section))
                    {
                        if(cellLanShou.detailBackgroundBtn.isShortBtn)
                        {
                            cellLanShou.contentShortDetailView.hidden = NO;
                            cellLanShou.contentDetailView.hidden = YES;
                        }
                        else
                        {
                            cellLanShou.contentShortDetailView.hidden = YES;
                            cellLanShou.contentDetailView.hidden = NO;
                        }
                    }
                    else
                    {
                        cellLanShou.contentShortDetailView.hidden = YES;
                        cellLanShou.contentDetailView.hidden = YES;
                    }
    
                }
                NSString *quickTypeIconUrl = [[[self.arratData  objectAtIndex:indexPath.section]valueForKey:@"courierRankIconUrl"] toString];
                [self loadIcon:cellLanShou.imageViewPeiSongDengJi withWayQuickTypeIconUrl:quickTypeIconUrl withTableViewcell:cellLanShou];
    
                quickTypeIconUrl = [[[self.arratData  objectAtIndex:indexPath.section]valueForKey:@"quickTypeIconUrl"] toString];
                [self loadOrderTypeIcon:cellLanShou.imageViewOrderType withWayQuickTypeIconUrl:quickTypeIconUrl withTableViewcell:cellLanShou];
                cell = cellLanShou;
            }
    .
    .
    .
    }
    -(void)hiddenDetail
    {
        if((nil == _contentHVView) || (_iRow < 0))
        {
            return;
        }
        if(!(_contentHVView.hidden))
        {
            _contentHVView.hidden = YES;
    
            _iRow = -1;
            _bHidden = YES;
        }
    }
    
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        [self hiddenDetail];
        .
        .
        .
    }
    
    -(void)viewWillDisappear:(BOOL)animated{
        [super viewWillDisappear:YES];
        self.imageViewIconIcon.hidden = YES;
        self.labelTitle.hidden = YES;
            self.buttonRightItem.hidden = YES;
        self.imageViewNavView.hidden = YES;
        _viewImageControlBG = nil;
        [self.remindLabel removeFromSuperview];
        [self hiddenDetail];
    }
    
    // 滚动时,触发该函数
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
        [self hiddenDetail];
    }
    
    
    -(void)buttonPressedDetail:(UIButtonValue*)sender{
    
        if((nil == sender) || (nil == sender.contentUIView))
        {
            return;
        }
        sender.contentUIView.hidden = !(sender.contentUIView.hidden);
        if(!(sender.contentUIView.hidden))
        {
    
            if((nil != self.tableView) && (self.arratData.count > 0 ) && (sender.row < self.arratData.count) && (_iRow < self.arratData.count))
            {
                if((_iRow != sender.row) && (_iRow >= 0))
                {
                    _contentSecondHVView = _contentHVView;
                    _contentSecondHVView.hidden = YES;
                    _contentHVView = sender.contentUIView;
                    _contentHVView.hidden = NO;
                    _iRow = sender.row;
                    _bHidden = NO;
                }
                else
                {
                    _iRow = sender.row;
                    _contentHVView = sender.contentUIView;
                    _contentHVView.hidden = NO;
                    _bHidden = NO;
    //                [self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:sender.row]] withRowAnimation:UITableViewRowAnimationNone];
                }
            }
            else
            {
                _iRow = sender.row;
                _contentHVView = sender.contentUIView;
                _contentHVView.hidden = NO;
                _bHidden = NO;
            }
    
        }
        else
        {
            _contentHVView.hidden = YES;
            _iRow = -1;
            _bHidden = YES;
    
        }
    }
    
    
    -(void)buttonPressedContent:(UIButtonValue*)sender{
    
        if((nil == sender) || (nil == sender.contentUIView))
        {
            return;
        }
        if(!(sender.contentUIView.hidden))
        {
    //        sender.contentUIView.hidden = YES;
            _contentHVView = sender.contentUIView;
    //        [self.tableView reloadData];
            //跳转到运费模版页面
            FeeWebViewController *feeWebViewController = [[FeeWebViewController alloc] init];
            NSString *waybillIdStr = [[[self.arratData  objectAtIndex:sender.row]valueForKey:@"waybillId"] toString];
            if(waybillIdStr.length > 0)
            {
                feeWebViewController.waybillId = waybillIdStr;
                //        webViewController.type = WebViewTypePolicy;
                feeWebViewController.title = @"配送运费";
                [self.navigationController pushViewController:feeWebViewController animated:YES];
            }
    
        }
        else
        {
            sender.contentUIView.hidden = NO;
        }
    
    }
    
    展开全文
  • 这个跟上一篇是同一类,但是有点不同,那个是边框+小气泡三角,这个是渐变背景+小气泡三角,而且我还换了一个实现手法。 1 .down_tip{position:relative;width:300px;height:50px; 2 background: #f9d835; /...

         这个跟上一篇是同一类,但是有点不同,那个是边框+小气泡三角,这个是渐变背景+小气泡三角,而且我还换了一个实现手法。

        

     1 .down_tip{position:relative;width:300px;height:50px;
     2         background: #f9d835; /* Old browsers */
     3         /* IE9 SVG, needs conditional override of 'filter' to 'none' */
     4         background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIxJSIgc3RvcC1jb2xvcj0iI2Y5ZDgzNSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmMzk2MWMiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
     5         background: -moz-linear-gradient(top,  #f9d835 1%, #f3961c 100%); /* FF3.6+ */
     6         background: -webkit-gradient(linear, left top, left bottom, color-stop(1%,#f9d835), color-stop(100%,#f3961c)); /* Chrome,Safari4+ */
     7         background: -webkit-linear-gradient(top,  #f9d835 1%,#f3961c 100%); /* Chrome10+,Safari5.1+ */
     8         background: -o-linear-gradient(top,  #f9d835 1%,#f3961c 100%); /* Opera 11.10+ */
     9         background: -ms-linear-gradient(top,  #f9d835 1%,#f3961c 100%); /* IE10+ */
    10         background: linear-gradient(top,  #f9d835 1%,#f3961c 100%); /* W3C */
    11         
    12         filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#f9d835',endColorstr='#f3961c'); /* IE6-8 */
    13         filter: none\9\0;/*ie9*/ 
    14         color:#FFFFFF;line-height:50px;text-align:center;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;}
    15     .down_tip:after{position:absolute;z-index:-1;bottom:-15px;left:30px;display:block;content:'.';width:0;height:0;border-top:15px solid #f3961c;border-left:15px solid transparent;border-right:15px solid transparent;}
    

    <div class="down_tip">看我没有用图片啊,你相信吗?</div>


    这个是用after伪类实现的,在div后面添加内容content:'.',然后模拟小气泡的

    这个效果我只在现代浏览器里面实现。

    需要介绍几个地方:

    1.ie9写这么多兼容。。。是啊,我也不想,这么一大坨是用来解决,在ie9下面border-radius和背景渐变色不能共存的bug,我原以为ie9没bug啦,没想到这么多,这个我是记不住的,所以借助一个神器:http://www.colorzilla.com/gradient-editor/,下面有个ie sup.port勾选就可以啦

    2.这里我实现小三角是用三边来实现的,原理呢就是:一个矩形可以是有四个三角拼成,也可以又三个三角拼成,理解不了的自己画一下就ok啦。

     

    参考资料:http://www.ruanyifeng.com/blog/2010/04/css_speech_bubbles.html

    http://cssshare.com/solutions/border/border.html

     

    如有转载,请注明出处,尊重别人的劳动!

    转载于:https://www.cnblogs.com/different/archive/2012/06/07/2540989.html

    展开全文
  • 转载地址: [简书地址]...   ... * @author 麦子, 16-08-15 16:08:05 ... 图片的处理。 如果是GIF的话,用的是第三方的,我们这边不处理。 如果是静态图片的话,重新设置Frame的参数。



      转载地址: [简书地址](http://www.jianshu.com/users/23d0ae412e19/latest_articles)

     


      

    /**
     *  @author 麦子, 16-08-15 16:08:05
     *
     *  
     
         图片的处理。 如果是GIF的话,用的是第三方的,我们这边不做处理。 如果是静态图片的话,重新设置Frame的参数。 
     
     
         然后就是调整Cell的高度问题。
     
     
         网络图片也是一样。 对于图片的规格的话, 都是以最大的为主, 然后其他的会相应的缩小比列。 控制比列的大小。同时也设置了一个最大的宽度和高度。 
     
     
     */
    
    @interface BubblePhotoView()
    
    @property (nonatomic,strong) FLAnimatedImageView *imageV;
    
    @end
    
    
    
    @implementation BubblePhotoView
    
    
    + (instancetype)BubblePhotoView
    {
        BubblePhotoView *bubbleView = [[self alloc]init];
        return bubbleView;
    }
    
    
    - (instancetype)initWithFrame:(CGRect)frame{
        
        self = [super initWithFrame:frame];
        if (self) {
            
            _imageV = [[FLAnimatedImageView alloc]initWithFrame:self.bounds];
            _imageV.contentMode = UIViewContentModeScaleAspectFill;
            _imageV.layer.cornerRadius = 6;
            _imageV.layer.masksToBounds = true;
            [self addSubview:_imageV];
            
            self.backgroundColor = [UIColor clearColor];
        }
        return self;
    }
    
    
    
    - (void)setMessage:(TalkMessage *)message{
      
        _message = message;
        
        if (message.isSend) { // 发送
            
            if (message.isGif) { //如果是动态图片
                
                FLAnimatedImage *animationImage = [FLAnimatedImage animatedImageWithGIFData:[NSData dataWithContentsOfFile:_message.photoAddress]];
                _imageV.animatedImage = animationImage;
                
            }else{
            
                _imageV.image = [UIImage imageWithContentsOfFile:_message.photoAddress];
            }
            
            // 重画处理
            [self setNeedsDisplay];
            
            
        }else{ //  收取网络图片
            
            UIImage *placeholderImage = [UIImage imageNamed:@"placeholderImage"];
            [_imageV sd_setImageWithURL:[NSURL URLWithString:@"http://img.hb.aicdn.com/b617afdf7a972b26c438293c762c9f50b7eed0b6146a5-6bQadP_fw580"] placeholderImage:placeholderImage completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
                
                  [self setNeedsDisplay];
                
            }];
            
        }
        
    }
    
    
    #define KMargin 5
    
    - (void)layoutSubviews{
    
        [super layoutSubviews];
    
        if (_message.isGif) {
            
            _imageV.frame = self.bounds;
            
        }else{
            _imageV.frame = CGRectMake(KMargin, KMargin, self.frame.size.width-2*KMargin, self.frame.size.height-2*KMargin);
        }
    
    }
    
    
    - (void)drawRect:(CGRect)rect{
    
        if (!_message.isGif) { // 不是GIF就进行画气泡, GIF不在自己代码这边控制。
            
            [UIImage drawImage:_imageV.image atFrame:rect isSender:_message.flag];
        }
    
    }
    
    
    
    
    //  改变图片处理方式:微信方式:长>宽  ,图片长为固定最大长度,宽按比例缩放,长<宽,图片宽为最大宽度,长按比例缩放
    
    #define KBubbleImageMaxWidth 145
    #define KBubbleImageMaxHeight 145
    
    + (CGSize)photoWithSize:(TalkMessage *)message{
        
        CGSize imageSize = message.size;
    
        if (imageSize.width == 0 || imageSize.height == 0) {
            
            if (message.localPhotoFlag){ // 表示本地图片
                UIImage *photo = [UIImage imageWithContentsOfFile:message.photoAddress];
                imageSize = photo.size;
                if (imageSize.width>imageSize.height){
                    imageSize.height *= KBubbleImageMaxWidth/imageSize.width;
                    imageSize.width = KBubbleImageMaxWidth;
                }else{
                    
                    imageSize.width *= KBubbleImageMaxHeight/imageSize.height;
                    imageSize.height = KBubbleImageMaxHeight;
                }
            }else{ //正常接口不会走这步,demo使用网络图片才会走这步
                imageSize.width = KBubbleImageMaxWidth;
                imageSize.height = KBubbleImageMaxHeight;
            }
        }else{
            //返回服务器图片尺寸
            if (imageSize.width>imageSize.height){
                imageSize.height *= KBubbleImageMaxWidth/imageSize.width;
                imageSize.width = KBubbleImageMaxWidth;
            }else{
                imageSize.width *= KBubbleImageMaxHeight/imageSize.height;
                imageSize.height = KBubbleImageMaxHeight;
            }
        }
        return imageSize;
    }
    
    
    @end
    



    case MessageBubbleTypePhoto:{ // 显示图片
                
                BubblePhotoView *photoView = [BubblePhotoView BubblePhotoView];
                photoView.message = message;
                [self.bubbleImageV addSubview:photoView];
                
                
                CGSize size = [BubblePhotoView photoWithSize:message];
                //注意self.bubbleImageV是在内部bubble的size.width上增加间距定的frame
                if (_message.flag) {
                    self.bubbleImageV.frame = CGRectMake(CGRectGetMinX(self.avateImageV.frame)-(size.width+KSenderLeftBubbleImageMargin+KSenderRightBubbleImageMargin),KTopBubbleImageMargin,size.width+KSenderLeftBubbleImageMargin+KSenderRightBubbleImageMargin,size.height+2*KTopBubbleImageMargin);
                    
                    photoView.frame = CGRectMake(KSenderLeftBubbleImageMargin,KTopBubbleImageMargin, size.width, size.height);
                }else{
                    self.bubbleImageV.frame = CGRectMake(CGRectGetMaxX(self.avateImageV.frame),KTopBubbleImageMargin,size.width+KReceiverLeftBubbleImageMargin+KReceiverRightBubbleImageMargin,size.height+2*KTopBubbleImageMargin);
                    
                    photoView.frame = CGRectMake(KReceiverLeftBubbleImageMargin,KTopBubbleImageMargin, size.width, size.height);
                }
                
                
                self.bubbleImageV.bubbleImage = nil;
            
                break;
            }
    



    //  计算cell的高度
    
    + (CGFloat)cellHeight:(id)obj{
        
        CGFloat avaterImageHeight = 45;
        CGFloat bubbleViewHeight = 0;
        
        
        TalkMessage *message = (TalkMessage *)obj;
        switch (message.messageBubbleType) {
            case  MessageBubbleTypeText:{
            
                  bubbleViewHeight = [TalkCell BubbleTextViewSize:message].height;
                  bubbleViewHeight += KTopMargin*2;
                  break;
                }
            case MessageBubbleTypePhoto:{
               
                bubbleViewHeight = [BubblePhotoView photoWithSize:message].height;
                bubbleViewHeight += KTopMargin*2;
                
                break;
               }
            default:
                break;
        }
    
        if (bubbleViewHeight<avaterImageHeight) {
            bubbleViewHeight = avaterImageHeight;
        }
    
        return KTopMargin+bubbleViewHeight+KTopMargin;;
    }
    



    cell高度设置 


    - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
    
        id  obj = [_array objectAtIndex:indexPath.row];
        
        if ([obj isKindOfClass:[TalkMessage class]]) {
            
            return CGSizeMake(self.view.bounds.size.width,  [TalkCell cellHeight:obj]);
        }
        return CGSizeMake(self.view.bounds.size.width,30);;
    }
    






    展开全文
  • 以前遇到textarea上面有三角气泡,总是把三角气泡单独切下来,然后再绝对定位上去。今天,切页面我就换了一个方法,用纯css上! 其实原理很简单:就是让两个三角叠起来,上面的三角往一侧错一下位,就刚好...

     

         以前遇到textarea上面有小三角气泡,总是把小三角气泡单独切下来,然后再绝对定位上去。今天,切页面我就换了一个方法,用纯css上!

        其实原理很简单:就是让两个小三角叠起来,上面的小三角往一侧错一下位,就刚好露出下面小三角的边,为此上下三角的颜色是不同的,而且需要上面的小三角盖住下面的三角。所以,上面的小三角为白色,下面的小三角是你想要的边框颜色。也就是border-color不同。为了能达到这个效果,要求两个小三角要一样大小,也就是border-width要一样。

         下面直接上代码:

       

    1 /*右侧气泡 兼容firefox chrome safari ie6,7,8,9*/
    2  .right_tip{position:relative;width:300px;height:50px;border:3px solid #D7E0EF;color:#000;line-height:50px;text-align:center;}
    3  .right_tip .icon1{position:absolute;top:7px;right:-23px;width:0;height:0;font-size:0;line-height:0;border-width:10px;border-color:transparent transparent transparent #D7E0EF;border-style:solid;_border-style:dashed dashed dashed solid;}
    4  .right_tip .icon2{position:absolute;top:7px;right:-19px;width:0;height:0;font-size:0;line-height:0;border-width:10px;border-color:transparent transparent transparent #ffffff;border-style:solid;_border-style:dashed dashed dashed solid;}
    5 
    6 <div class="right_tip">看我没有用图片啊,你相信吗?<em class="icon1"></em><em class="icon2"></em></div>

    需要解释几个地方:

    1.width和height设置为0,是因为要解决ie6下面空标签的bug

    2.font-size和line-height设置为0,是因为要解决ie6下面边框bug

    3._border-style:dashed dashed dashed solid,是因为要解决ie6下面border无法透明的bug,那怎么判断应该给哪个边设置dashed,哪个应该设置为solid?这个很好判断,只要让它跟你的border-color对应就行,哪个边是transparent的,hack对应的就是dashed

    4.这两个em也可以换成span,一定要注意他们的是并列的关系,而不是包含关系,不然会在chrome和safari里面出现上面的三角完全盖住下面三角的bug,这个要写他们的hack比较麻烦,而且firefox和ie系列的偏移量也有小问题不一致,所以,介于此我果断换了结构,把原来嵌套的结构换成并列的

     

    1.demo{position:relative;width:530px;}  
    2textarea{overflow:auto;width:500px;height:100px;resize:none;border:1px solid #e8e8e8;} 
    3.icon1{position:absolute;top:10px;right:20px;right:18px\9;width:0;height:0;font-size:0;border-width:9px 0 9px 9px;border-style:solid;_border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #eeeeee;} 
    4.icon2{position:absolute;top:-9px;right:1px;_right:0px;width:0;height:0;font-size:0;border-width:9px 0 9px 9px;border-style:solid;_border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #ffffff;}
    5 
    6 <div class="demo">
    7    <textarea name="" id="" ></textarea>
    8    <span class="icon1"><span class="icon2"></span></span>
    9 </div>


     参考资料:http://www.zhangxinxu.com/wordpress/2010/03/%E7%BA%AFcss%E5%AE%9E%E7%8E%B0%E5%90%84%E7%B1%BB%E6%B0%94%E7%90%83%E6%B3%A1%E6%B3%A1%E5%AF%B9%E8%AF%9D%E6%A1%86%E6%95%88%E6%9E%9C/

     如有转载,请注明出处,尊重别人的劳动!

    转载于:https://www.cnblogs.com/different/archive/2012/06/07/2537439.html

    展开全文
  • 在开发过程中,我们可能会经常遇到这样的需求样式:这张图是截取京东消息通知的弹出框,我们可以看到右上方有个三角形的气泡效果,这只是其中一种,三角形的方向还可以是上、下、左、右。通过截图可以发现,气泡由正...
  • 下载直接解压文件用浏览器打开BubblesDemo.html即可(PS:该Demo使用...如果想更换图片,需要使用Photoshop切图放入img目录,为了方便伙伴们切出合适的图,我在demo下的img目录中放入了一个psd文件)
  • 安卓开发之图片气泡聊天框

    千次阅读 2017-03-29 11:21:40
    安卓开发之图片气泡聊天框
  • 对于有些图标等按钮 在美工设计的按钮下可以通过拉伸效果处理所需效果,最熟悉的莫过于微信聊天的 椭圆背景,也是通过这个这个原理进行背景图片。  如对该图片拉伸,如何操作? 首先找到要...
  • 源码BubbleDemo,支持照片和图片上添加气泡框特效,可在照片或图片上添加一个气泡框。目前支持三种类型 : ellipse, shout 和 thought。可以任意移动气泡以及箭头的位置,并且气泡大小可以随着文字的输入而改变。 ...
  • 一代开源git地址: https://github.com/jgilfelt/android-viewbadger 讲解地址: ...二代: ...一代是应该只能在控件之上悬浮,我可以在文字按钮图片上,但是不可以在linearLayout上所...
  • 字体附近的三角图标的制作方法,字体图标的使用 问题转化:如何一个字体图标 使用after伪元素 位置:在需要加图标的li后面 统一类名arrow-icon 转义出对应的字体图标 声明字体图标 www.iconfont.cn阿里...
  • ![图片说明](https://img-ask.csdn.net/upload/201708/25/1503648589_954355.png) 如图显示,气泡图大的过大小的过怎么平均一下大小显示
  • 一脚下去差点没从坑里爬起来,然后由于某个原因,去研究了 微信程序里面地图 callout 这个属性 callout呢,是在标记的点上面显示 一个 气泡,作为提示用 最后展示下 效果 可以展示 顶部气泡以及监听被点击 (此...
  • } /** * 得到mask的图像 ... * @param BubbleImage 气泡原始图 * @param edge 拉伸角度 * @param maskframe 蒙版大小 * * @return 返回蒙版图像 */ -(UIImage *)getMaskImageWithBubbleImage:(UI...
  • &lt;!DOCTYPE html&gt; &lt;html style="height: 100%"&gt; &lt;head&gt; &lt;meta charset="utf-8"&gt; &lt;/head&gt; &...
  • 需求: 实现将文字转换为图片图片为聊天框形式。 ...方案二:使用canvas绘制图片,使用StaticLayout自动换行绘制文字,聊天框采取气泡形状图片背景,图片自适应文字。 方案一 1.学习...
  • 在IM应用当中,我们的聊天页面再熟悉不过了,在聊天页面中每条消息都有一个背景气泡,但是在微信中呢,图片的背景气泡却没有,而是图片本身成为了一个气泡的样式,我们来看看微信的样式是怎么样的,今天就来实现这样...
  • I want to design a widget of shape of a chat bubble where one corner is pinned and its height should adjust to the lines of the text? For now I'm using ClipRRect widget with some borderRadius....
  • 需要根据这些小图片进行拆分,并从中拆分出表情。这个的实现很简单,利用背景图片偏移的属性,偏移单个图片的宽度即可。以下是实例代码: /** * 连体的表情图片 **/ .totalEmoji { background: url(...
  • 程序label气泡content文字换行 一直以为label上的文字只能横着写一排(怪丑的) 换行很简单,拼接上"\n" 完美解决。 附上例子: label: { anchorX: -18, anchorY: -22, content: item.name + ‘\n’ + item.size...
  • 这两天在一个电子商城的商品评论功能,想到模仿微信或者iphone中的气泡聊天方式,气泡聊天是iphone内置的控件,不对开发者开放,android中更是没有提供类似的控件。于是先在百度google上搜了一下有没有类似的...
  • 赞找其他博客: https://blog.csdn.net/programarqin/article/details/103684178
  • (此图片来源于网络,如有侵权,请联系删除! )   实现细节: 1.JS:   drawImage:function(data){[/align] var that = this var p10= data[0][0]; /* 三阶贝塞尔曲线起点坐标值*/ var p11= data[0][1]; /* 三阶...
  • 只有一个 html 文件, 可以自己替换 背景图片 和小球图片。(显示为白色 不是代码有问题,只是没有背景图片,和小球图片
  • QT自定义ToolTip 实现气泡+图片+文字显示效果 说明 工程文件源码地址 实现效果 实现思路 存在的问题 暂时解决方案 其他问题 实现代码 说明 QT自带的tooltip显示效果不好看,不能显示类型气泡或者其他不规则形状的...
  • 微信程序实现点赞气泡效果

    千次阅读 2020-11-19 13:52:33
    微信程序实现点赞气泡效果 先上代码: <view class="listImg"> <block wx:for="{{8}}" wx:key="index"> <image class="heart_img {{number == index?'active': ''}}" src="../../style...
  • R可视化:图片为背景的气泡地图

    千次阅读 2019-01-31 11:36:00
    作者:噜啦啦啦啦 统计学出身 R语言中文社区专栏作者知乎ID:https://www.zhihu.com/people/shen-chang-43前言关于气泡地图bu...
  • 自定义SeekBar, 能改变尺寸、颜色、滑块图片、刻度图片、刻度文字和气泡指示器,当滑动时显示带有进度的气泡指示器
  • 一个可自适应大小的聊天气泡Flutter组件 引用方式 dependencies: smart_bubble: ^1.0.1 https://pub.dev/packages/smart_bubble/admin https://github.com/50Death/Smart-Bubble-Widget 实现原理 气泡由背景(气泡...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,931
精华内容 3,572
关键字:

做小气泡的图片