在移动端平常开发中,列表**UITableView**的使用频率很是高,而TableView里主要用的就是UITableViewCell,不论是自定义cell,仍是系统的cell,仍是后期为了优化列表,都离不开操做cell,那么UITableViewCell就有必要研究一下了;至于为何要整理一篇关于Cell的文章,由于,搜了一下关于cell的文章,基本都是把头文件里面的方法简单介绍一下,没有介绍编辑模式下,cell的一些问题;ios
[说明规定]: 一些简单语法,便于说明问题:
* A-->B 意思是: A继承B,B是A的父类;git
另外,不要以为本身平时经常使用,而后想固然觉得,本身对于这个"出镜率"极高的控件极为熟悉,曾经我也那么觉得,然而,毕竟咱们:github
遇到以下问题:猜猜看,多是什么缘由形成的?我在平时比较活跃的QQ交流群问了一下,而后石沉大海了......xcode
这只是其中在cell编辑多选中遇到一个问题;app
还有一个就是,当用xib布局cell的时候,tableView进入编辑模式,多选不能全选cell,都是一些奇葩的问题;框架
咱们知道,cell能够根据不一样的style显示不一样的类型;
好比下面的几种:ide
首先,OC中,全部的类都是对象,都是继承自NSObject,这个元类;每一个对象都有一个__isa__指针指向它的父类,实例对象的isa指针指向建立他的本类,类对象isa指向它的父类,元类指向它自己;这一块不作讨论;工具
不知你是否好奇,为何对象都有一个isa指针?其实,OC对象中isa指针,并非OC独有的,在Python中,也有相似的,isa分开来就是:布局
is a ,后面是省略的 kind of ,合起来就是 is a kind of ...翻译过来就是:是....的一类或者跟...是同一类的;优化
好理解,子类继承父类,即是 Son -> Father,B is A,就是B继承A;
固然以UI开头的属于UIKIt框架范畴,可是,全部的对象都是继承自NSObject;
UITableViewCell --> UIView --> UIResponder --> NSObject
经过获取cell内部私有的子类,咱们知道,除了TextLable,ContentView,ImageView等,还有重用标识符**reuseIdentifier**
cell内部的控件结构图以下:
Runtime获取一个类的中全部的私有属性:
[备注]:须要导入Runtime相关的头文件
#import <objc/runtime.h> #import <objc/message.h>_
unsigned int count; Ivar *ivarList = class_copyIvarList([cell class], &count); for (int i = 0; i < count; i++) { Ivar ivar = ivarList[i]; NSLog(@"%s", ivar_getName(ivar)); } free(ivarList);
2017-11-30 22:10:42.095 UITtableViewCell[66184:9589083] _tableView 2017-11-30 22:10:44.336 UITtableViewCell[66184:9589083] _layoutManager 2017-11-30 22:10:46.753 UITtableViewCell[66184:9589083] _target 2017-11-30 22:10:48.696 UITtableViewCell[66184:9589083] _editAction 2017-11-30 22:10:50.070 UITtableViewCell[66184:9589083] _accessoryAction 2017-11-30 22:10:51.967 UITtableViewCell[66184:9589083] _oldEditingData 2017-11-30 22:10:51.967 UITtableViewCell[66184:9589083] _editingData 2017-11-30 22:10:51.967 UITtableViewCell[66184:9589083] _rightMargin 2017-11-30 22:10:51.967 UITtableViewCell[66184:9589083] _indentationLevel 2017-11-30 22:10:51.967 UITtableViewCell[66184:9589083] _indentationWidth 2017-11-30 22:10:51.968 UITtableViewCell[66184:9589083] _reuseIdentifier 2017-11-30 22:10:51.968 UITtableViewCell[66184:9589083] _floatingContentView 2017-11-30 22:10:51.968 UITtableViewCell[66184:9589083] _lineBreakModeBeforeFocus 2017-11-30 22:10:51.968 UITtableViewCell[66184:9589083] _contentView 2017-11-30 22:10:51.968 UITtableViewCell[66184:9589083] _imageView 2017-11-30 22:10:51.968 UITtableViewCell[66184:9589083] _textLabel 2017-11-30 22:10:51.968 UITtableViewCell[66184:9589083] _detailTextLabel 2017-11-30 22:10:51.969 UITtableViewCell[66184:9589083] _backgroundView 2017-11-30 22:10:51.969 UITtableViewCell[66184:9589083] _selectedBackgroundView 2017-11-30 22:10:51.969 UITtableViewCell[66184:9589083] _multipleSelectionBackgroundView 2017-11-30 22:10:51.974 UITtableViewCell[66184:9589083] _selectedOverlayView 2017-11-30 22:10:51.974 UITtableViewCell[66184:9589083] _selectionFadeDuration 2017-11-30 22:10:51.974 UITtableViewCell[66184:9589083] _backgroundColor 2017-11-30 22:10:51.974 UITtableViewCell[66184:9589083] _separatorColor 2017-11-30 22:10:51.975 UITtableViewCell[66184:9589083] _separatorEffect 2017-11-30 22:10:51.975 UITtableViewCell[66184:9589083] _topShadowColor 2017-11-30 22:10:51.975 UITtableViewCell[66184:9589083] _bottomShadowColor 2017-11-30 22:10:51.975 UITtableViewCell[66184:9589083] _sectionBorderColor 2017-11-30 22:10:51.975 UITtableViewCell[66184:9589083] _floatingSeparatorView 2017-11-30 22:10:51.975 UITtableViewCell[66184:9589083] _topShadowAnimationView 2017-11-30 22:10:51.976 UITtableViewCell[66184:9589083] _bottomShadowAnimationView 2017-11-30 22:10:51.976 UITtableViewCell[66184:9589083] _badge 2017-11-30 22:10:51.976 UITtableViewCell[66184:9589083] _unhighlightedStates 2017-11-30 22:10:51.976 UITtableViewCell[66184:9589083] _highlightingSupport 2017-11-30 22:10:51.976 UITtableViewCell[66184:9589083] _selectionSegueTemplate 2017-11-30 22:10:51.976 UITtableViewCell[66184:9589083] _accessoryActionSegueTemplate 2017-11-30 22:10:51.977 UITtableViewCell[66184:9589083] _accessoryActionPreviewingSegueTemplateStorage 2017-11-30 22:10:51.977 UITtableViewCell[66184:9589083] _accessoryView 2017-11-30 22:10:52.008 UITtableViewCell[66184:9589083] _editingAccessoryView 2017-11-30 22:10:52.008 UITtableViewCell[66184:9589083] _customAccessoryView 2017-11-30 22:10:52.009 UITtableViewCell[66184:9589083] _customEditingAccessoryView 2017-11-30 22:10:52.009 UITtableViewCell[66184:9589083] _separatorView 2017-11-30 22:10:52.009 UITtableViewCell[66184:9589083] _topSeparatorView 2017-11-30 22:10:52.009 UITtableViewCell[66184:9589083] _topShadowView 2017-11-30 22:10:52.010 UITtableViewCell[66184:9589083] _editableTextField 2017-11-30 22:10:52.010 UITtableViewCell[66184:9589083] _lastSelectionTime 2017-11-30 22:10:52.010 UITtableViewCell[66184:9589083] _deselectTimer 2017-11-30 22:10:52.010 UITtableViewCell[66184:9589083] _textFieldOffset 2017-11-30 22:10:52.010 UITtableViewCell[66184:9589083] _indexBarWidth 2017-11-30 22:10:52.010 UITtableViewCell[66184:9589083] _separatorInset 2017-11-30 22:10:52.011 UITtableViewCell[66184:9589083] _backgroundInset 2017-11-30 22:10:52.011 UITtableViewCell[66184:9589083] _returnAction 2017-11-30 22:10:52.011 UITtableViewCell[66184:9589083] _selectionTintColor 2017-11-30 22:10:52.011 UITtableViewCell[66184:9589083] _accessoryTintColor 2017-11-30 22:10:52.011 UITtableViewCell[66184:9589083] _reorderControlImage 2017-11-30 22:10:52.012 UITtableViewCell[66184:9589083] _menuGesture 2017-11-30 22:10:52.012 UITtableViewCell[66184:9589083] _representedIndexPath 2017-11-30 22:10:52.012 UITtableViewCell[66184:9589083] _focusable 2017-11-30 22:10:52.013 UITtableViewCell[66184:9589083] _swipeToDeleteConfirmationView 2017-11-30 22:10:52.013 UITtableViewCell[66184:9589083] _swipeToDeleteCancelationGesture 2017-11-30 22:10:52.013 UITtableViewCell[66184:9589083] _clearBlendingView 2017-11-30 22:10:52.013 UITtableViewCell[66184:9589083] _swipeToDeleteDistancePulled 2017-11-30 22:10:52.013 UITtableViewCell[66184:9589083] _sectionCornerRadius 2017-11-30 22:10:52.014 UITtableViewCell[66184:9589083] _sectionBorderWidth 2017-11-30 22:10:52.014 UITtableViewCell[66184:9589083] _defaultMarginWidth 2017-11-30 22:10:52.014 UITtableViewCell[66184:9589083] _editControlFocusGuide 2017-11-30 22:10:52.014 UITtableViewCell[66184:9589083] _reorderControlFocusGuide 2017-11-30 22:10:52.014 UITtableViewCell[66184:9589083] _constants 2017-11-30 22:10:52.014 UITtableViewCell[66184:9589083] _tableCellFlags 2017-11-30 22:10:52.015 UITtableViewCell[66184:9589083] _isLayoutEngineSuspended
项目中,基本上都是多人协做开发,有些UI是复用的,团队中,又没有__codeReview__,每一个人对本身要求又不同,在平常开发中,因为咱们偷懒,能少写一点就少写一点,而文章出现的自定义cell正好是copy过来的,也没检查,当在非编辑模式下,显示正常;当在编辑模式下,就出问题了?
首先,在编辑模式下,正常的话,cell总体发生位移了,那么,只要涉及到控件位移的,第一就是打印frame,咱们看下,编辑时和非编辑状况下,cell的frame变化状况:
非编辑cell Frame:<UITableViewCell: 0x7f9bd2020600; frame = (0 0; 320 44)
编辑下cell Frame:<UITableViewCell: 0x7f9bd401ea00; frame = (0 0; 320 44);
咱们惊奇的发现,两种模式下,cell的frame竟然是一致的,那也就是说:
编辑状态下,cell的总体位移不是经过修改cell自己的frame实现的;
接下来,cell内部还有一个contentView,咱们打印它的frame:
非编辑cell Frame:<UITableViewCellContentView: 0x7f9fc31374a0; frame = (0 0; 320 44);
编辑下cell Frame:<UITableViewCellContentView: 0x7fb522c02070; frame = (0 0; 320 44);
我靠,contentView的frame也是一致的,奇怪,那tableView,编辑下,怎么实现cell的总体位移呢?
既然,cell的自己的frame和cell内部contentView的frame,在编辑和非编辑模式下,frame在打印出来,结果并无改变,而实际上,在编辑模式下,cell明显发生位移了,接下来,咱们看一下cell的的视图层级关系:
进入xcode,视图层级关系,以下:
经过视图层级,咱们能够看出,在编辑模式下,每个cell都动态添加了
UITableViewCellEditControl的控件,而这个editControl的并无add到contentView中,而是add在cell自己中,所以,若是自定义cell,布局相对cell自己,编辑模式,cell内部子控件就不会总体移动,必须相对于contentView;
其实,cell自己就是一个View,其内部又内置了一个容器view---ContentView,而ContView的文档说明以下:
If you want to customize cells by simply adding additional views, you should add them to the content view so they will be positioned appropriately as the cell transitions into and out of editing mode. 就是说,若是想自定义cell,建立的子控件,如lable,imgView等,建议最好把子控件添加到ContentView中,这时候,在cell动画的时候,子控件也会随着ContView一块动画;
行啊,UI显示是没问题,可是,若是cell涉及动画,或者编辑模式下,多选,总体cell往右移动,这时候,若是子控件没有添加到contentView中,就会出现文章一开始的问题
这篇文章,原本想经过cell的frame来探究编辑模式下,系统如何实现cell的总体移动,可是,frame竟然是一致的,可是,经过层级关系,咱们也知道,contentView在编辑状态下,frame改变了;
所以,建议:咱们在平常开发中,尤为是团队开发中,在自定义tableVIewcell的时候,布局相对contentView布局,不要像以下这样布局:如下代码就是罪魁祸首!
[self.videoCoverImgView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(weakSelf).offset(15*X_WidthScale); make.top.equalTo(weakSelf).offset(15*Y_HeightScale); make.width.offset(130*X_WidthScale); make.height.offset(74*Y_HeightScale); }];
[点击获取文章涉及代码]:https://github.com/lucyios/UITableViewCell.git
cell的重用机理及尝试模仿写一个cell,打算重新开始一个文章论述,若是有问题的话,欢迎评论区留言,咱们一块儿讨论!
若是您喜欢个人这篇文章,欢迎您给我点个赞,谢谢!