xamarin学习笔记B07(ios的UITableView)

来源:互联网 发布:sql loader 语法 编辑:程序博客网 时间:2024/06/06 01:30

UITableView简介

UITableView是表格控件,用来显示列表数据,它是UIScrollView的子类。类似于Android中的RecyclerView控件。

 

UITableView的使用

上代码再分析

public partial class ViewController : UIViewController,IUITableViewDataSource    {        //返回一个Cell        public UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)        {            var cell = tableView.DequeueReusableCell("abc");//从缓存池中取出一个Cell(如果没有会自动创建一个注册的Cell类型)            //if (cell == null)                //cell = new UITableViewCell(UITableViewCellStyle.Default, "abc");            cell.TextLabel.Text = $"第{indexPath.Section}组,第{indexPath.Row}行";            return cell;        }        //返回指定分组中的行数        public nint RowsInSection(UITableView tableView, nint section)        {            return 20;        }        public override void ViewDidLoad()        {            base.ViewDidLoad();            //1.创建表格并将表格添加到父容器中            UITableView tableView = new UITableView(this.View.Frame, UITableViewStyle.Plain);            this.View.AddSubview(tableView);            //2.注册可重用UITableViewCell            tableView.RegisterClassForCellReuse(typeof(UITableViewCell), "abc");            //也可不注册重用单元格,在GetCell()方法中手动去创建Cell也是一样的,请看GetCell方法中注释的部分            //3.设置表格的数据源对象(必须实现IUITableViewDataSource)            tableView.DataSource = this;        }    } 

上面的代码是表格的一个简单显示。显示一个表格主要有三步:

1.  创建表格并将它添加到父容器中。

2.  注册可重用的单元格。第一个参数用来告诉表格创建新的UITableViewCell时所用的Cell的类型,因为在刚开始缓存池中还没有缓存的单元格,通过var cell = tableView.DequeueReusableCell("abc");这句代码去缓存池中是取不到单元格的,所以系统会根据注册的单元格类型来创建新的Cell同时把abc这个标识赋给这个Cell。下次取Cell时就用这个abc。

3.  设置表格的数据源对象并实现IUITableViewDataSource接口。上例中数据源对象是当前控制器,那么这个控制器就必须要实现IUITableViewDataSource接口。这个接口有两个方法必须实现,RowsInSection()用来告诉表格在每一分组对应有多少行,默认是一个分组。GetCell()用来显示每一行,当一个Cell将要进入屏幕中时,就会通过此方法得到一个要显示的Cell对象。

运行结果如下图:


再来了解下单元格类UITableViewCell,从xamarin官网拿来一张图,如下:


上面是普通模式,下面是编辑模式。

可以看出,普通模式下,默认就维护着两个View,而编辑模式有三个。在ContentView中可以添加我们的UIImageView,UILabel等来显示数据。有ContentView的好处是,将来如果左滑移动时就移动这个ContentView就够了,不必一个个移动其中的UIImageView,UILabel等子控件。

 

接着了解一下单元格的自带的四种风格,还是从官网拿来的图:


再结合这段代码来分析

//返回一个Cell        public UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)        {            var cell = tableView.DequeueReusableCell("abc");//从缓存池中取出一个Cell(如果没有会自动创建一个注册的Cell类型)            cell.TextLabel.Text = $"第{indexPath.Section}组,第{indexPath.Row}行";            cell.ImageView = null;            cell.DetailTextLabel = null;            return cell;        } 

在UITableViewCell中默认就维护着三个视图对象,从上面的代码可知,有ImageView, TextLabel,DetailTextLabel三个View,在上图中的Subtitle风格中分别对应图片,黑色标题,灰色子标题。其它三种风格一看就明白,就不分析了。需要注意的是,例如设置单元格的风格为Default,那么它是没有DetailTextLabel的,虽然可以点出来这个属性,但使用会报空引用错误。

 

实际使用中默认的风格肯定是不够用的,那么就需要自定义单元格。

代码太多就不全部贴上了,上主要代码吧
//自定义的Table的单元格    public partial class BookCell : UITableViewCell    {        public const string ReuseID = "BookCell";//缓存用的标识        private UIImageView BookImageView { get; set; }        private UILabel BookNameLabel { get; set; }        private UILabel BookPriceLabel { get; set; }        private UILabel BookSummaryLabel { get; set; }        private Book _book;        public Book Book        {             set            {                _book = value;                BookImageView.Image = UIImage.FromBundle(_book.BookImageName);                BookNameLabel.Text = _book.BookName;                BookPriceLabel.Text = "¥" + string.Format("{0:N2}", _book.BookPrice);                if (string.IsNullOrEmpty(_book.BookSummary))                {                    BookSummaryLabel.Text = "";//这句必须写上,否则计算不对                    BookSummaryLabel.Hidden = true;                }                else                {                    BookSummaryLabel.Text = _book.BookSummary;                    BookSummaryLabel.Hidden = false;                }            }        }        //如果注册了重用单元格类BookCell,那么从缓存中取不到而新建时,会自动调用此构造方法来创建单元格        protected internal BookCell(IntPtr handle) : base(handle)        {            InitCell();        }        //如果不采用注册方式而采用手动创建BookCell,那么自己手动使用这个公开的构造方法即可        public BookCell() : base(UITableViewCellStyle.Default, ReuseID)        {            InitCell();        }        //由于是使用自己添加的控件而不是默认的控件,所以此构造方法就没意义了        //public BookCell(UITableViewCellStyle style, string reuseIdentifier) : base(style, reuseIdentifier)        //{        //    InitCell();        //}        private void InitCell()//初始化自定义的单元格的子控件        {            UIImageView bookImageView = new UIImageView();            this.ContentView.AddSubview(bookImageView);            BookImageView = bookImageView;            UILabel bookNameLabel = new UILabel();            this.ContentView.AddSubview(bookNameLabel);            bookNameLabel.Font = UIFont.SystemFontOfSize(22, UIFontWeight.Bold);            bookNameLabel.BackgroundColor = UIColor.Cyan;            BookNameLabel = bookNameLabel;            UILabel bookPriceLabel = new UILabel();            this.ContentView.AddSubview(bookPriceLabel);            bookPriceLabel.TextColor = UIColor.Red;            bookPriceLabel.Font = UIFont.SystemFontOfSize(20, UIFontWeight.Bold);            bookPriceLabel.BackgroundColor = UIColor.Cyan;            BookPriceLabel = bookPriceLabel;            UILabel bookSummaryLabel = new UILabel();            this.ContentView.AddSubview(bookSummaryLabel);            bookSummaryLabel.Font = UIFont.SystemFontOfSize(19, UIFontWeight.Regular);            bookSummaryLabel.BackgroundColor = UIColor.Cyan;            bookSummaryLabel.Lines = 0;//记得设置自动换行            BookSummaryLabel = bookSummaryLabel;            AddConstraint();//添加约束        }        //添加约束        private void AddConstraint()        {            BookImageView.MakeConstraints((ConstraintMaker obj) =>            {                obj.Left.EqualTo(this.ContentView.Left()).Offset(10);                obj.Top.EqualTo(this.ContentView.Top()).Offset(10);                obj.Width.EqualTo(new NSNumber(100));                obj.Height.EqualTo(new NSNumber(100));            });            BookNameLabel.MakeConstraints((ConstraintMaker obj) =>            {                obj.Left.EqualTo(BookImageView.Right()).Offset(10);                obj.Top.EqualTo(this.ContentView.Top()).Offset(10);                //宽和高会自动计算出来            });            BookPriceLabel.MakeConstraints((ConstraintMaker obj) =>            {                obj.Left.EqualTo(BookImageView.Right()).Offset(10);                obj.Bottom.EqualTo(BookImageView.Bottom());                //宽和高会自动计算出来            });            BookSummaryLabel.MakeConstraints((ConstraintMaker obj) =>            {                obj.Left.EqualTo(this.ContentView.Left()).Offset(10);                obj.Trailing.EqualTo(this.ContentView.Trailing()).Offset(-10);                obj.Top.EqualTo(BookImageView.Bottom()).Offset(5);                obj.Bottom.EqualTo(this.ContentView.Bottom()).Offset(-10);            });        }    }


然后在ViewController中使用这个自定义的单元格,上部分代码:

//每一个行即将显示在屏幕上时此方法被调用        public UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)        {            BookCell cell = (BookCell)tableView.DequeueReusableCell(BookCell.ReuseID);            //if(cell == null)            //{            //    cell = new BookCell();            //}            cell.Book = book;            return cell;        } //控制器的视图加载完毕后被调用        public override void ViewDidLoad()        {            base.ViewDidLoad();            //1.创建表格并将表格添加到父容器中            var tableView = new UITableView(this.View.Frame, UITableViewStyle.Plain);            this.View.AddSubview(tableView);            //2.注册可重用UITableViewCell            tableView.RegisterClassForCellReuse(typeof(BookCell), BookCell.ReuseID);                   //3.设置表格的数据源对象(必须实现IUITableViewDataSource)            tableView.DataSource = this;            //4.设置表格其它属性            tableView.SeparatorColor = UIColor.Red;        } 

最后显示结果如下图


代码和视频在我上传的CSDN资源中 http://download.csdn.net/download/junshangshui/10161426