看到别人的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; } }