iOS中tableview 中编辑,删除与多选中的问题(一)

本文探讨如何在iOS的tableview中实现自定义的编辑功能,包括多选和删除操作。当一级数据被选中时,二级数据自动全选;取消一级选择时,二级数据也取消选择。文章通过代码示例展示了如何处理这种联动选择,并在数据源中增加了标记来跟踪选择状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        通常情况下,一个tableview中,会存在编辑状态,比如说选中几个cell进行删除,或者添加一些section和cell。iOS中自带编辑状态,有删除,插入等,这里就不再叙述了,因为网上面一顿这些个东西。现在,与大家探讨一下,自定的方式来实现cell的选择,能够实现多选,取消选择,在这里我们要进行两级数据的处理,如果一级数据被选择了,二级数据全部被选中,如果一级数据取消选择,二级数据就会取消选择,如果二级数据全被选中,一级数据也就会被选中。那么我们在数据源里面添加一个一级数据被选中的标志位。代码如下:

using System;
using Foundation;
using System.Collections.Generic;

namespace Expland
{
	public class Data
	{
		public Data ()
		{
		}
		//一级标题
		public  string Title{ get; set;}
		//是否展开标志位
		public  bool ExplandFlag{ get; set;}
		//是否选中标志位
		public bool SelectedFlag{get;set;}
		//二级标题
		public  List<string> SecondTitle = new List<string> ();
	}
}

    添加一个全局变量,判断是否进入编辑状态,再添加一个全局变量list集合,存储被选中的路径,代码如下:

using System;
using Foundation;
using System.Collections.Generic;

namespace Expland
{
	public class GlobalVariable
	{
		public GlobalVariable ()
		{
		}
		//编辑状态标志位
		public static bool EditFlag{get;set;}
		//记录被选中的cell
		public static List<NSIndexPath> SelectIndexPath=new List<NSIndexPath>(){};
	}
}

       这里面的逻辑性比较强,比如说,我们点击一级标题,它的二级标题都会选中,我们应该怎么实现呢?我们是不是应该再GetCell方法里面,首先判断的是不是编辑状态,如果是编辑状态,在判断是不是一级标题选中,如果是的,cell 的图标就是被选中的图标。

using System;
using UIKit;
using Foundation;
using System.Collections.Generic;
using CoreAnimation;

namespace Expland
{
	public class MyTableViewSource:UITableViewSource
	{
		string cellReuseId="cellReuseId";
		string headerReuseId="headerReuseId";
		List<Data> Title;
		//构造函数,传递参数
		public MyTableViewSource (List<Data> Title)
		{
			this.Title = Title;
		}
		//每一行的内容
		public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
		{
			UITableViewCell cell = tableView.DequeueReusableCell (cellReuseId);
			if (cell == null) {
				cell = new UITableViewCell (UITableViewCellStyle.Default, cellReuseId);
				cell.ImageView.Image = UIImage.FromFile ("unhook");
				cell.ImageView.Hidden = true;
				cell.SelectionStyle = UITableViewCellSelectionStyle.None;
			}
			//如果在编辑状态下,显示图片(根据是否被选中)
			if (GlobalVariable.EditFlag) {
				cell.ImageView.Hidden = false;
				//被选中
				if (GlobalVariable.SelectIndexPath.FindIndex (v => (v.Row == indexPath.Row && v.Section == indexPath.Section)) == -1) {
					cell.ImageView.Image = UIImage.FromFile ("unhook");
				} else {
					cell.ImageView.Image = UIImage.FromFile ("hook");
				}
				//如果一级标题被选中,二级标题就会被选中
				if (Title [(int)indexPath.Section].SelectedFlag) {
					cell.ImageView.Image = UIImage.FromFile ("hook");
					if (GlobalVariable.SelectIndexPath.FindIndex (v => (v.Row == indexPath.Row && v.Section == indexPath.Section)) == -1) {
						GlobalVariable.SelectIndexPath.Add (indexPath);
					}
				}
			} else {
				cell.ImageView.Hidden = true;
			}
			cell.TextLabel.Text = Title [(int)indexPath.Section].SecondTitle [(int)indexPath.Row];
			return cell;
		}
		//每一个section的行数
		public override nint RowsInSection (UITableView tableview, nint section)
		{
			nint numberRows=0;
			if (Title [(int)section].ExplandFlag) {
				numberRows = Title [(int)section].SecondTitle.Count;
			} else {
				numberRows = 0;
			}
			return numberRows;
		}
		//section的个数
		public override nint NumberOfSections (UITableView tableView)
		{
			return Title.Count;
		}
		//section的高度
		public override nfloat GetHeightForHeader (UITableView tableView, nint section)
		{
			return 44f;
		}
		// 选中cell的操作,点击为奇数的添加到路径里面,图标改变,偶数删除路径,图标改变
		public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
		{
			UITableViewCell selectedCell = tableView.CellAt (indexPath);
			if (GlobalVariable.SelectIndexPath.FindIndex (v => (v.Row == indexPath.Row && v.Section == indexPath.Section)) == -1) {
				GlobalVariable.SelectIndexPath.Add (indexPath);
				selectedCell.ImageView.Image = UIImage.FromFile ("hook");
			} else {
				selectedCell.ImageView.Image = UIImage.FromFile ("unhook");
				GlobalVariable.SelectIndexPath.RemoveAll (v => (v.Section == indexPath.Section && v.Row == indexPath.Row));
			}
			//如果一个同一个二级标题都被选中,一级标题也会被选中
			int length=Title[(int)indexPath.Section].SecondTitle.Count;
			int selectLength= GlobalVariable.SelectIndexPath.FindAll (v => v.Section == indexPath.Section).Count;
			if (length == selectLength) {
				Title [(int)indexPath.Section].SelectedFlag = true;
				tableView.ReloadData ();
			} else {
				Title [(int)indexPath.Section].SelectedFlag = false;
				tableView.ReloadData ();
			}
		}
		//section的内容
		public override UIView GetViewForHeader (UITableView tableView, nint section)
		{
			MyTableViewHeader headerView =(MyTableViewHeader)tableView.DequeueReusableHeaderFooterView (headerReuseId);
			if (headerView == null) {
				headerView = new MyTableViewHeader (this,Title,section,tableView,headerReuseId);
			}
			headerView.Label.Text=Title[(int) section].Title;
			//数据重新加载的时候,展开图标的重新设置
			if (Title [(int)section].ExplandFlag) {
				headerView.ExplandButton.SetImage (UIImage.FromBundle ("arrowD"), UIControlState.Normal);
			} else {
				headerView.ExplandButton.SetImage (UIImage.FromBundle ("arrow"), UIControlState.Normal);
			}
			//若果在编辑状态下,显示图片(要根据是否选中现实对应的图标)
			if (GlobalVariable.EditFlag) {
				if (Title [(int)section].SelectedFlag) {
					headerView.SelectButton.SetImage (UIImage.FromFile ("hook"), UIControlState.Normal);
				} else {
					headerView.SelectButton.SetImage (UIImage.FromFile ("unhook"), UIControlState.Normal);
				}
			}
			return headerView;
		}
		//section的自定义类
		class MyTableViewHeader:UITableViewHeaderFooterView
		{
			public UIButton SelectButton{ get; set;}
			public UILabel Label{ get; set;}
			public UIButton ExplandButton{ get; set;}
			public MyTableViewHeader(MyTableViewSource myTabViSource,List<Data> Title,nint section,UITableView tableview,string headerReuseId)
			{
				SelectButton=new UIButton(new CoreGraphics.CGRect(5,10,20,25));
				Label=new UILabel(new CoreGraphics.CGRect(30,10,100,30));
				ExplandButton=new UIButton(new CoreGraphics.CGRect(340,14,20,20));
				ExplandButton.SetImage(UIImage.FromFile("arrow"),UIControlState.Normal);

				this.ContentView.AddSubviews(Label,ExplandButton,SelectButton);
				//选择按钮
				SelectButton.AddTarget(delegate(object sender, EventArgs e) {
					if(!Title[(int)section].SelectedFlag)
					{
						Title[(int)section].SelectedFlag=true;
						SelectButton.SetImage(UIImage.FromFile("hook"),UIControlState.Normal);
						//如果二级是展开的,二级全部选中
						tableview.ReloadData();
					}else{
						Title[(int)section].SelectedFlag=false;
						SelectButton.SetImage(UIImage.FromFile("unhook"),UIControlState.Normal);
					   //如果二级是展开的,二级全部取消选中
						for(int i=0;i<Title[(int)section].SecondTitle.Count;i++)
						{
							UITableViewCell cell=tableview.CellAt(NSIndexPath.FromRowSection((nint)i,section));
							cell.ImageView.Image=UIImage.FromFile("unhook");
							if (GlobalVariable.SelectIndexPath.FindIndex (v => (v.Row == i && v.Section == section)) != -1) {
								GlobalVariable.SelectIndexPath.RemoveAll(v => (v.Row == i && v.Section == section));
									}
						}
					}
				},UIControlEvent.TouchUpInside);
				//展开按钮的状态
				ExplandButton.AddTarget(delegate(object sender, EventArgs e) {
				    //判断状态
					if(!Title[(int)section].ExplandFlag){
						//标志位改变
						Title[(int)section].ExplandFlag=true;
						//图标的旋转
						UIButton explandButton=(UIButton)sender;
						myTabViSource.Rotate(explandButton);
						//数据插入
						int length=Title[(int)section].SecondTitle.Count;
						NSIndexPath[] arrayIndexPath=new NSIndexPath[length];
						for(int i=0;i<length;i++)
						{
							arrayIndexPath[i]=NSIndexPath.FromRowSection((nint)i,section);
						}
						tableview.InsertRows(arrayIndexPath,UITableViewRowAnimation.Automatic);
					}else{
						//标志位改变
						Title[(int)section].ExplandFlag=false;
						//图标的复位
						UIButton explandButton=(UIButton)sender;
						explandButton.SetImage (UIImage.FromBundle ("arrow"), UIControlState.Normal);
						myTabViSource.ReturnRotate(explandButton);
						//数据插入
						int length=Title[(int)section].SecondTitle.Count;
						NSIndexPath[] arrayIndexPath=new NSIndexPath[length];
						for(int i=0;i<length;i++)
						{
							arrayIndexPath[i]=NSIndexPath.FromRowSection((nint)i,section);
							//删除选中的cell的路径
							if (GlobalVariable.SelectIndexPath.FindIndex (v => (v.Row == i && v.Section == section)) != -1) {
								GlobalVariable.SelectIndexPath.RemoveAll(v => (v.Row == i && v.Section == section));
							}
						}
						tableview.DeleteRows(arrayIndexPath,UITableViewRowAnimation.Automatic);
					}
				},UIControlEvent.TouchUpInside);
			}
		}
		/// <summary>
		/// sectiond 的按钮点击,顺时针旋转
		/// </summary>
		/// <param name="btn">Button.</param>
		void Rotate(UIButton btn)
		{			
			CABasicAnimation ro = CABasicAnimation.FromKeyPath ("transform.rotation.z");	
			ro.To =new NSNumber (1.57f);
			ro.From =new NSNumber (0);
			ro.Duration = 0.1d;
			ro.Cumulative = false;
			ro.RepeatCount = 1;
			ro.RemovedOnCompletion = false;
			ro.FillMode = CAFillMode.Forwards.ToString();
			btn.Layer.AddAnimation (ro, "Rotation");
		}
		/// <summary>
		/// sectiond 的按钮点击,逆时针旋转
		/// </summary>
		/// <param name="btn">Button.</param>
		void ReturnRotate(UIButton btn)
		{			
			CABasicAnimation ro = CABasicAnimation.FromKeyPath ("transform.rotation.z");	
			ro.To =new NSNumber (0);
			ro.From =new NSNumber (1.57f);
			ro.Duration = 0.1d;
			ro.Cumulative = false;
			ro.RepeatCount = 1;
			ro.RemovedOnCompletion = false;
			ro.FillMode = CAFillMode.Forwards.ToString();
			btn.Layer.AddAnimation (ro, "Rotation");
		}
	}
}

using Foundation;
using System.Collections.Generic;
using UIKit;

namespace Expland
{
	public partial class ViewController : UIViewController
	{
		UITableView tableview;
		List<Data> Titile= new List<Data> () {
			new Data{Title="A",ExplandFlag=false,SelectedFlag=false,SecondTitle=new List<string>{"1","2","3","4"}},
			new Data{Title="B",ExplandFlag=false,SelectedFlag=false,SecondTitle=new List<string>{"1","2","3","4"}},
			new Data{Title="C",ExplandFlag=false,SelectedFlag=false,SecondTitle=new List<string>{"1","2","3","4"}},
			new Data{Title="D",ExplandFlag=false,SelectedFlag=false,SecondTitle=new List<string>{"1","2","3","4"}},
			new Data{Title="E",ExplandFlag=false,SelectedFlag=false,SecondTitle=new List<string>{"1","2","3","4"}},
			new Data{Title="F",ExplandFlag=false,SelectedFlag=false,SecondTitle=new List<string>{"1","2","3","4"}},

		};

		public ViewController (IntPtr handle) : base (handle)
		{ }

		public override void ViewDidLoad ()
		{
			base.ViewDidLoad ();
			//编辑状态赋初始值
			GlobalVariable.EditFlag=false;
			InitTableView ();
			InitNavigation ();
			//tableview的数据源
			this.tableview.Source = new MyTableViewSource (Titile);

		}
		//tableview初始化
		void InitTableView ()
		{
			tableview = new UITableView (new CoreGraphics.CGRect (0, 0, UIScreen.MainScreen.Bounds.Width, UIScreen.MainScreen.Bounds.Height));
			this.View.AddSubview(tableview);
		}

		//导航栏初始化
		void InitNavigation()
		{
			this.NavigationItem.Title = "首页";
			UIBarButtonItem editButton = new UIBarButtonItem("编辑",UIBarButtonItemStyle.Done,delegate {
				if(!GlobalVariable.EditFlag)
				{
					GlobalVariable.EditFlag=true;

				}else{
					GlobalVariable.EditFlag=false;
				}
				tableview.ReloadData();
			});
			this.NavigationItem.RightBarButtonItem = editButton;
		}
		public override void DidReceiveMemoryWarning ()
		{
			base.DidReceiveMemoryWarning ();
		}
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值