ios tableview 插入 刪除 移動

gif圖片.gif
最近專案中要用到tableview 插入 刪除 移動的功能,以前開發的時候沒用到這類的工能,基本上時從零開始,期間遇到不少坑
下面我們一步一步來看看這個功能怎麼實現的
1,插入功能 簡單 剛開始 初始化一個數據源的可變陣列,在點選新增內容按鈕的時候 在點選事件裡面為資料來源陣列新增資料然後你可以relodata 然後功能就實現啦
if (sender.tag==501) { NSMutableDictionary *tempDict = [NSMutableDictionary dictionary]; [tempDict setObject:@"0" forKey:@"type"]; [self.dataSouce addObject:tempDict]; [self.data_souceaddObject:tempDict]; [comTableView reloadData]; NSLog(@"昂起值%@",self.dataSouce); }
因為我點選點選新增按鈕的時候的 是分新增文字或者圖片倆種,所以我在給資料來源添加了一個字典進去,type值 就是分開哪個是文字哪個是圖片,
在reloadData的時候 你會遇到複用問題,這裡就不闡述 複用的概念啦,就是你在reloaddata的時候 你新增到文字上的內容沒了,或者你新增的多張圖片瞬間變成同一張了,
解決的辦法是,你把新增的文字或者圖片存放到字典裡然後把剛開始儲存在陣列中的字典覆蓋掉,然後在reloadData的時候把存好的內容在重新賦值回去,cellForRowAtIndexPath裡這樣寫
NSDictionary *dict = self.dataSouce[indexPath.row]; if ([dict[@"type"]isEqualToString:@"0"]) { self.cell.comImage.hidden = YES; CreateWeakSelf; self.cell.textViewInputCompletion = ^(NSString *text){ NSMutableDictionary *temp=[[NSMutableDictionary alloc]init]; [temp setObject:@"0" forKey:@"type"]; [temp setObject:text forKey:@"str"]; [weakSelf.dataSouce replaceObjectAtIndex:indexPath.row withObject:temp]; [weakSelf.data_soucereplaceObjectAtIndex:indexPath.row withObject:temp]; }; self.cell.comTextView.text =[dict objectForKey:@"str"];
2,刪除
這個比較簡單 就是刪除你原來資料來源數組裡面先對應的index就行,
-(void)delegateAction:(UIButton *)sender{ NSLog(@"index的值為%@",sender.additionalMark); NSString *str = [NSString stringWithFormat:@"%@",sender.additionalMark]; NSInteger i = [str integerValue]; //NSUInteger i= sender.additionalMark; [self.dataSouce removeObjectAtIndex:i]; [self.data_souceremoveObjectAtIndex:i]; [comTableView reloadData]; }
這裡我遇到的問題是,剛開始我是初始化一個 NSIndexpath 然後 在cellforrowindexptath裡面 把indexpath賦值給我初始化的NSIndexpath 拿indexpate.row作為刪除的數組裡index下標的,問題是當你在reloadData的時候,賦值給NSindexpath 永遠是最下面cell,所以後來解決辦法是 當你點選刪除按鈕的時候 把當前要剷除cell的 indexpath 賦值,然後問題就解決啦
self. cell.deleageBtn.additionalMark = [NSString stringWithFormat:@"%ld",indexPath.row];
3,移動
我是直接百度的,具體的沒有去深研究,大概就是 給當前的cell新增長按手勢,當你觸發手勢的時候,會把當前的cell進行一個快照,說白了就是你拖到的不是實際的cell,而是照片,當你拖動的時候,然後再把資料來源的中的資料進行重新排序,然後在reloadta一下 就ok啦 我把程式碼直接貼上吧
#pragma mark 建立cell的快照 - (UIView *)customSnapshoFromView:(UIView *)inputView { // 用cell的圖層生成UIImage,方便一會顯示 UIGraphicsBeginImageContextWithOptions(inputView.bounds.size, NO, 0); [inputView.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); // 自定義這個快照的樣子(下面的一些引數可以自己隨意設定) UIView *snapshot = [[UIImageView alloc] initWithImage:image]; snapshot.layer.masksToBounds = NO; snapshot.layer.cornerRadius = 0.0; snapshot.layer.shadowOffset = CGSizeMake(-5.0, 0.0); snapshot.layer.shadowRadius = 5.0; snapshot.layer.shadowOpacity = 0.4; return snapshot; } #pragma mark 長按手勢方法 - (void)longPressGestureRecognized:(id)sender { UILongPressGestureRecognizer *longPress = (UILongPressGestureRecognizer *)sender; UIGestureRecognizerState state = longPress.state; CGPoint location = [longPress locationInView:comTableView]; NSIndexPath *indexPath = [comTableView indexPathForRowAtPoint:location]; static UIView*snapshot = nil; switch (state) { // 已經開始按下 case UIGestureRecognizerStateBegan: { // 判斷是不是按在了cell上面 if (indexPath) { sourceIndexPath = indexPath; UITableViewCell *cell = [comTableView cellForRowAtIndexPath:indexPath]; // 為拖動的cell新增一個快照 snapshot = [self customSnapshoFromView:cell]; // 新增快照至tableView中 __block CGPoint center = cell.center; snapshot.center = center; snapshot.alpha = 0.0; [comTableView addSubview:snapshot]; // 按下的瞬間執行動畫 [UIView animateWithDuration:0.25 animations:^{ center.y = location.y; snapshot.center = center; snapshot.transform = CGAffineTransformMakeScale(1.05, 1.05); snapshot.alpha = 0.98; cell.alpha = 0.0; } completion:^(BOOL finished) { cell.hidden = YES; }]; } break; } // 移動過程中 case UIGestureRecognizerStateChanged: { // 這裡保持數組裡面只有最新的兩次觸控點的座標 [self.touchPoints addObject:[NSValue valueWithCGPoint:location]]; if (self.touchPoints.count > 2) { [self.touchPoints removeObjectAtIndex:0]; } CGPoint center = snapshot.center; // 快照隨觸控點y值移動(當然也可以根據觸控點的y軸移動量來移動) center.y = location.y; // 快照隨觸控點x值改變數移動 CGPoint Ppoint = [[self.touchPoints firstObject] CGPointValue]; CGPoint Npoint = [[self.touchPoints lastObject] CGPointValue]; CGFloat moveX = Npoint.x - Ppoint.x; center.x += moveX; snapshot.center = center; NSLog(@"%@---%f----%@", self.touchPoints, moveX, NSStringFromCGPoint(center)); NSLog(@"%@", NSStringFromCGRect(snapshot.frame)); // 是否移動了 if (indexPath && ![indexPath isEqual:sourceIndexPath]) { // 更新陣列中的內容 [self.dataSouce exchangeObjectAtIndex: indexPath.row withObjectAtIndex:sourceIndexPath.row]; // 把cell移動至指定行 [comTableView moveRowAtIndexPath:sourceIndexPath toIndexPath:indexPath]; // 儲存改變後indexPath的值,以便下次比較 sourceIndexPath = indexPath; } break; } // 長按手勢取消狀態 default: { // 清除操作 // 清空陣列,非常重要,不然會發生座標突變! [self.touchPoints removeAllObjects]; [comTableView reloadData]; UITableViewCell *cell = [comTableView cellForRowAtIndexPath:sourceIndexPath]; cell.hidden = NO; cell.alpha = 0.0; // 將快照恢復到初始狀態 [UIView animateWithDuration:0.25 animations:^{ snapshot.center = cell.center; snapshot.transform = CGAffineTransformIdentity; snapshot.alpha = 0.0; cell.alpha = 1.0; } completion:^(BOOL finished) { sourceIndexPath = nil; [snapshot removeFromSuperview]; snapshot = nil; [comTableView reloadData]; }]; break; } } }
大概功能差不多已經實現,不過實際開發的時候,還會有許多問題需要考慮,比如修改文字內容的時候,你要實時更新資料來源中的內容,返回到上一個介面的時候,在重新進入的時候,你還需要tableview展示你剛才新增的內容以便修改,,,,,期間我遇到的問題很多,還有很多細節問題,我就不一一闡述啦 如果開發中你們需要這樣的功能,遇到什麼問題可以私信給我,盡力幫助你們
最後附上demo
不麻煩的話可以 給個 star
你們的star 是我進步的動力
有什麼問題可以私信我,
歡迎叨擾,
非誠勿擾 謝謝