在移動端平常開發中,列表**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,打算重新開始一個文章論述,若是有問題的話,歡迎評論區留言,咱們一塊兒討論!
若是您喜歡個人這篇文章,歡迎您給我點個贊,謝謝!