小萌做開發(fā)的時候彤灶,項目需求是:拖拽單元格隨意變換位置,變換位置之后仍然可以編輯其它批旺,界面需求如下圖所示幌陕。
小萌在網(wǎng)上找的例子自己使用的時候發(fā)現(xiàn)很多問題,下面發(fā)一種小萌親測可行的方案汽煮,以及補充小萌一直以來忽略的知識點搏熄。NSMutableArray的中removeObjectAtIndex和的removeObject的正確使用方法
下面主要代碼:
@interface AddController ()<UITableViewDelegate,UITableViewDataSource,UIImagePickerControllerDelegate,UINavigationControllerDelegate,UITextViewDelegate>
@property(nonatomic,strong)UITableView *myTableView;
@property(nonatomic,strong)NSMutableArray *dataArr;
/*****發(fā)文本******/
@property(nonatomic,strong)UIButton *textButton;
/******發(fā)圖片********/
@property(nonatomic,strong)UIButton *imageButton;
/******上傳圖片的時候用到********/
@property(nonatomic,strong)NSIndexPath *selePatch;
@end
- (void)viewDidLoad {
[super viewDidLoad];
self.dataArr = [NSMutableArray array];
[self.view addSubview:self.myTableView];
//這兩行很主要,開啟可移動
self.myTableView.allowsMultipleSelection=YES;
self.myTableView.editing=YES;
//發(fā)圖片按鈕
self.imageButton = [[UIButton alloc]initWithFrame:CGRectMake(SCREEN_WIDTH - 84, SCREEN_HEIGHT - iPhoneXTabBarHeight - 85, 64, 65)];
[self.imageButton setImage:[UIImage imageNamed:@"icon_editdetail_addimg"] forState:UIControlStateNormal];
[self.imageButton addTarget:self action:@selector(addimageAction:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.imageButton];
//發(fā)文本按鈕
self.textButton = [[UIButton alloc]initWithFrame:CGRectMake(SCREEN_WIDTH - 84*2, SCREEN_HEIGHT - iPhoneXTabBarHeight - 85, 64, 65)];
[self.textButton setImage:[UIImage imageNamed:@"icon_editdetail_addtype"] forState:UIControlStateNormal];
[self.textButton addTarget:self action:@selector(addtextAction:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.textButton];
//導(dǎo)航條右邊的保存按鈕暇赤,我是自定義的心例,不是自定義的朋友請修改
[self.navBar.titleRight setTitle:@"保存" forState:UIControlStateNormal];
[self.navBar.titleRight setTitleColor:UIColorFromRGB(0xFF4055) forState:UIControlStateNormal];
[self.navBar.titleRight addTarget:self action:@selector(saveAction) forControlEvents:UIControlEventTouchUpInside];
self.view.backgroundColor = UIColorFromRGB(0xf7f7f7);
}
#pragma mark -addimageAction 添加圖片 發(fā)圖片
- (void)addimageAction:(UIButton *)btn{
NSMutableDictionary *editDic = [NSMutableDictionary dictionary];
[editDic setValue:@"image" forKey:@"type"];
[editDic setValue:@"" forKey:@"content"];
[editDic setValue:@"" forKey:@"convertUrl"];
[self.dataArr addObject:editDic];
//刷新
[self.myTableView reloadData];
}
#pragma mark -addtextAction 添加文本 發(fā)文本
- (void)addtextAction:(UIButton *)btn{
NSMutableDictionary *editDic = [NSMutableDictionary dictionary];
[editDic setValue:@"text" forKey:@"type"];
[editDic setValue:@"" forKey:@"content"];
[self.dataArr addObject:editDic];
[self.myTableView reloadData];
}
//刪除
#pragma mark - deleAction 刪除
- (void)deleAction:(UIButton *)btn{
// //取出移動row數(shù)據(jù)
// NSDictionary *rowDic = self.dataArr[btn.tag - 3000];
// //從數(shù)據(jù)源中移除該數(shù)據(jù)
// [self.dataArr removeObject:rowDic];
//
//用下面這種,上面是小萌吃虧的地方removeObject和removeObjectAtIndex是有區(qū)別的鞋囊,看上面的鏈接
[self.dataArr removeObjectAtIndex:btn.tag - 3000];
NSLog(@"%@",self.dataArr);
[self.myTableView reloadData];
}
#pragma mark - saveAction 保存
- (void)saveAction{
if (self.dataArr.count == 0) {
CustomToastView *toast = [[CustomToastView alloc]initWithView:self.view text:@"保存的數(shù)據(jù)不能為空" duration:KDuration];
[toast show];
return ;
}
NSLog(@"%@",self.dataArr);
for (int i = 0; i<self.dataArr.count; i ++ ) {
NSMutableDictionary *cellDic = [NSMutableDictionary dictionary];
[cellDic addEntriesFromDictionary:self.dataArr[i]] ;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:i];
DescAndTextCell *vd =(DescAndTextCell *)[self.myTableView cellForRowAtIndexPath:indexPath];
[cellDic setValue:[NSString stringWithFormat:@"%d",i + 1] forKey:@"no"];
if ([cellDic[@"type"] isEqualToString:@"text"]) {
[cellDic setValue:vd.textCellView.text forKey:@"content"];
}
NSString *contents = cellDic[@"content"];
if (DT_IsEmpty(contents) == YES) {
CustomToastView *toast = [[CustomToastView alloc]initWithView:self.view text:@"保存的數(shù)據(jù)不能為空" duration:KDuration];
[toast show];
return ;
}
}
if (self.block) {
self.block(self.dataArr);
}
[self.navigationController popViewControllerAnimated:YES];
}
#pragma mark - tipAction 開啟了移動單元格點擊作用消失止后,需要其他的方法
- (void)tipAction:(UIButton *)btn{
NSDictionary *cellDic = self.dataArr[btn.indexP.section];
if ([cellDic[@"type"] isEqualToString:@"text"]) {
return ;
}
self.selePatch = btn.indexP;
// 類方法
LCActionSheet *sheet = [LCActionSheet sheetWithTitle:nil buttonTitles:@[@"拍照",@"從手機相冊選擇"] redButtonIndex:-1 clicked:^(NSInteger buttonIndex) {
if (buttonIndex == 0) {
[self takePhoto];
}else if(buttonIndex == 1){
[self localPhoto];
}
}];
[sheet show];
}
//必須把編輯模式改成None,默認的是delete
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellEditingStyleNone;
}
#pragma mark 排序當(dāng)移動了某一行時候會調(diào)用
//編輯狀態(tài)下溜腐,只要實現(xiàn)這個方法译株,就能實現(xiàn)拖動排序---右側(cè)會出現(xiàn)三條杠,點擊三條杠就能拖動
-(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
// 取出要拖動的模型數(shù)據(jù)
NSDictionary *goods = self.dataArr[sourceIndexPath.section];
//刪除之前行的數(shù)據(jù)
//[self.dataArr removeObject:goods];千萬別這樣做哦
[self.dataArr removeObjectAtIndex:sourceIndexPath.section];
// 插入數(shù)據(jù)到新的位置
[self.dataArr insertObject:goods atIndex:destinationIndexPath.section];
NSLog(@"%@",self.dataArr);
[self.myTableView reloadData];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return self.dataArr.count;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 1;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *indentifer = @"DescAndTextCell";
DescAndTextCell *cell = [tableView dequeueReusableCellWithIdentifier:indentifer];
if (cell == nil) {
cell = [[DescAndTextCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:indentifer];
}
NSDictionary *cellDic = self.dataArr[indexPath.section];
if ([cellDic[@"type"] isEqualToString:@"text"]) {
cell.moveButton.hidden = YES;
cell.textCellView.delegate = self;
cell.textCellView.tag = indexPath.section + 500;
cell.textCellView.hidden = NO;
cell.imageCellView.hidden = YES;
cell.textCellView.text = cellDic[@"content"];
}else{
cell.moveButton.hidden = NO;
cell.textCellView.hidden = YES;
cell.imageCellView.hidden = NO;
NSString *https = cellDic[@"convertUrl"];
NSLog(@"%@",https);
if (DT_IsEmpty(https) == NO) {
cell.photoLabel.hidden = YES;
cell.imageLabel.hidden = YES;
cell.photoImage.hidden = YES;
[cell.imageCellView sd_setImageWithURL:[NSURL URLWithString:https] placeholderImage:[UIImage imageNamed:@"icon-tong-default"]];
}else{
cell.photoLabel.hidden = NO;
cell.imageLabel.hidden = NO;
cell.photoImage.hidden = NO;
}
}
cell.deleButton.tag = indexPath.section + 3000;
[cell.deleButton addTarget:self action:@selector(deleAction:) forControlEvents:UIControlEventTouchUpInside];
cell.tipButton.indexP = indexPath;
[cell.tipButton addTarget:self action:@selector(tipAction:) forControlEvents:UIControlEventTouchUpInside];
cell.backgroundColor = [UIColor clearColor];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
return 0.000001;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
return 0.000001;
}
//失效
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
}
- (void)textViewDidEndEditing:(UITextView *)textView{
//取出移動row數(shù)據(jù)
NSDictionary *rowDic = self.dataArr[textView.tag - 500];
[rowDic setValue:textView.text forKey:@"content"];
}
#pragma mark - getter
- (UITableView *)myTableView{
if (!_myTableView) {
_myTableView = [[UITableView alloc]initWithFrame:CGRectMake(15, NavBarHeight, SCREEN_WIDTH - 30, SCREEN_HEIGHT-NavBarHeight) style:UITableViewStyleGrouped];
_myTableView.estimatedRowHeight = 0;
_myTableView.rowHeight = 130;
_myTableView.backgroundColor = UIColorFromRGB(0xf7f7f7);
_myTableView.estimatedSectionHeaderHeight = 0;
_myTableView.estimatedSectionFooterHeight = 0;
_myTableView.dataSource = self;
_myTableView.delegate = self;
_myTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
if (@available(iOS 11.0, *)) {
_myTableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
} else {
// Fallback on earlier versions
}
_myTableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);//iPhoneX這里是88
_myTableView.scrollIndicatorInsets = _myTableView.contentInset;
}
return _myTableView;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - 拍照
/*3:從相冊選擇*/
- (void)localPhoto
{
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
//資源類型為圖片庫
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
picker.delegate = self;
//設(shè)置選擇后的圖片可被編輯
picker.allowsEditing = NO;
[self presentViewController:picker animated:YES completion:^{
}];
}
/*4:拍照*/
- (void)takePhoto
{
UIImagePickerControllerSourceType sourceType = UIImagePickerControllerSourceTypeCamera;
//判斷是否有相機
if([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera]){
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
//設(shè)置拍照后的圖片可被編輯
picker.allowsEditing = NO;
//資源類型為照相機
picker.sourceType = sourceType;
[self presentViewController:picker animated:YES completion:^{
}];
}else {
// NSLog(@"該設(shè)備不支持拍照");
}
}
//再調(diào)用以下委托:
#pragma mark UIImagePickerControllerDelegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
//UIImage *image=[info objectForKey:UIImagePickerControllerEditedImage];
//上傳原圖
UIImage *imageOrigina=[info objectForKey:UIImagePickerControllerOriginalImage];
[picker dismissViewControllerAnimated:YES completion:^{
}];
}