Menu
Woocommerce Menu

UICollectionView及其新功能drag,引用计数

0 Comment


援用计数是一个回顾而使得的处理对象生命周期的措施。不管是OC依然Swift语言,其内部存款和储蓄器管理办法都以基于援用计数的。曾经有四个面试官问作者:iOS内存管理的规律是怎样?我现场懵逼了,不知道她问的是哪些看头,后来想了须臾间,不便是援用计数吗。

UICollectionView是大家常说的联谊视图,它在iOS
6中引进,是iOS开拓者中最受接待的UI成分之一。其布局灵活、可变,可用以显示存序数据项集,最常见的用途是以临近于网格的花样表现item,除了这一个之外还足以经过子类化UICollectionViewLayout类,精准地调控可视化成分布局,并动态更换布局。因而,能够兑现网格、仓库、圆形、动态变化等方式布局,以及别的任何你能够设想出的布局。

图片 1

何以是引用计数?引用计数的法规引用计数可以使得的处理对象的生命周期,当咱们创设一个新指标的时候,他(该对象所在的内部存款和储蓄器块)的援用计数为1,当有一个新的指针指向这一个目的时,大家将其引用计数加1,当某些指针不在指向这么些指针式,大家将其行使计数减1,当对象的引用计数变为0时,表达那块内部存款和储蓄器不在被别的指针指向,这一年系统就能够将对象销毁,回收内部存款和储蓄器。进而实现管理内部存款和储蓄器的目标。

图片 2CollectionView.png

提起其规律、全体用过它的童鞋都会说他在js和Native之间搭建了三个桥梁。通过那几个桥、使他们相互通讯。但具体怎么通讯呢?这一个桥如何工作?十有八九说却不清。

图片 3

UICollectionView将数据源和用来展现数据的视觉元素进行了严峻的分离。下图彰显了UICollectionView与有关对象关联:

如图,给appdelegate.m 关闭arc的意况下大家举办测验,首先大家看率先句
NSObject *ob = [[NSObject alloc]init];
那句话干了怎么样事呢?先看侧面,意思是在堆上开拓一块内部存储器,用于存放NSObjec的八个实例,再看左侧,在栈上成立了贰个指针,该指针存款和储蓄的是堆上实例的内部存款和储蓄器地址,此时该块内部存款和储蓄器的referencecount
= 1。 这NSObject *ob1 = ob; 又做了什么样事吧?
那句话同样在栈上创设了贰个指南针存了堆上实例的内部存款和储蓄器地址,可是为何referencecount未有扩张吗?别急,大家看看上边这句话:
NSObject *ob2 = [ob retain];
那句话做了怎么样吧?同样在栈上创设了一个指南针,存的是堆上的内部存款和储蓄器地址,不一样的是有三个[ob
retain]方法推行了,关键就在这么些 retain方法,因为那么些 方法的成效是
ob指针指向的内部存款和储蓄器块发新闻说:喂,老兄,你的引用计数要加1啊,于是,内部存款和储蓄器块的引用计数就加了1。正因为ob1尚未retain的经过,所以不会潜移暗化想其引用计数。

图片 4UICollectionView.png

(请忽略脑图的对准、能连上就行。由左右向中档)

这里要了解一个根本难题,援用计数是内部存储器块的性格,并不是指针的,所
以,指向同一块内部存储器的指针的引用计数在平等时刻永世都该是一样的。

在那之中,data source提供用于显示数据的视图对象,collection view
layout提供视图布局音信,而collection
view肩负将数据和布局音信统一后呈现到显示屏上。须求注意的是,在成立UICollectionView时,必需传递三个UICollectionViewLayout对象,这里的UICollectionViewLayout是一个抽象基类abstract
base
class
,不能够间接选取,必需接纳其子类。例如,在创设网格布局时一般采用UICollectionViewFlowLayout具体concrete类。

图片 5JS调用Native

本条时候我们只要调用[ob release];或者[ob1 release];或者[ob2
release];起到的效果与利益其实是一律的,他们皆以报告内部存款和储蓄器块:喂,老兄,你的援用计数要减一啊。假使大家不给ob大概ob1仍旧ob2置空的话,那四个指针依旧存在的,只要内部存款和储蓄器块的援用计数不为0的话,大家调用[ob
retainCount]或[ob1 retainCount]或[ob2
retainCount]的结果是同样的,一旦内部存款和储蓄器块援用计数为0,该对象在堆上的内部存款和储蓄器就可以被系统释放,大家在调用
[***
retainCount]就能有野指针崩溃(指针指向的内部存款和储蓄器地址已经被假释了),所以要马上给指针置空。

上面表格列出了UIKit中与聚焦视图相关的类,并依照分级扮演的剧中人物进行分拣:

  • 调用方时会扭转二个id。
  • 将调用的callback与id(callbackId)绑定备用。
  • 再将艺术名与id(callbackId)发给注册方。
  • 注册方通过艺术名、寻觅相应的响应措施。
  • handler实践完毕后透过id(responseId)寻觅调用方对应的callback再次回到。
  • responseId代表被调用方发起、callbackId代表调用方发起、值都同样。

到那边,基本上援引计数就理清了。假诺合驾驭错的地点,接待各位同学指正。

用途 类/协议 描述
集合视图和集合视图控制器 UICollectionView UICollectionViewController UICollectionView派生自UIScrollView,定义集合视图内容区域,将dataSource的数据与layout提供的布局信息合并后呈现到屏幕上。 UICollectionViewController为集合视图提供了控制器级别支持,UICollectionViewController的使用是可选的。
内容控制 UICollectionViewDataSource协议 UICollectionViewDelegate协议 dataSource为集合视图提供数据,是UICollectionView中最重要、必须提供的对象。要实现dataSource中的方法,必须创建一个遵守UICollectionViewDataSource协议的对象。 通过UICollectionViewdelegate对象可以监听集合视图状态、自定义视图。例如,使用delegate跟踪item是否高亮、选中。与数据源对象不同,代理对象不是必须实现。
呈现视图 UICollectionReusableView UICollectionViewCell UICollectionView中显示的所有视图都必须是UICollectionReusableView类的实例,该类支持回收机制(循环使用视图,而非创建新的视图),以便提高性能,特别是在滑动屏幕时。 UICollectionViewCell用来显示主要数据,也是可重用视图。
布局 UICollectionViewLayout UICollectionViewLayoutAttributes UICollectionViewUpdateItem 使用UICollectionViewLayout的子类为集合视图内元素提供位置、大小、视觉属性等布局信息。 在布局过程中,layout对象创建UICollectionViewLayoutAttributes实例,用以告知特定item如何布局。 当collection view的数据源发生插入、删除、移动变化时,UICollectionView会创建UICollectionViewUpdateItem类的实例,并发送给layoutprepareForCollectionViewUpdates:方法,layout会为即将到来的布局变化作出准备。你不需要创建该类的实例。
Flow layout UICollectionViewFlowLayout UICollectionViewDelegateFlowLayout协议 UICollectionViewFlowLayout类是用于实现网格或其它基于行布局的具体类,可以直接使用,也可以将其与UICollectionViewDelegateFlowLayout代理结合使用,以便自定义布局。
留神有好几区别
  • js是通过重定向通告oc管理逻辑。参数先存在js中、然后经过oc调用js中_fetchQueue方法被oc获取。
  • oc是由此平素调用_handleMessageFromObjC况兼传递了参数通报js处理逻辑。

注意:上面的UICollectionViewLayoutUICollectionViewReusableView类必须子类化才得以行使,另外类能够直接选取。

正文

  • ###### WebViewJavascriptBridge的原理本质上也是说道拦截。

  • 其一库、具体的用法小编就不写了、反正写也是copy别的教学帖子。而且、在JSCore以及WKWebView已经极度成熟的及时。WebViewJavascriptBridge用到的地方并不是那么多。

  • 自个儿相比较关注的是他怎么着以注册以及调用这种写法来兑现的合计拦截。所以笔者也并不是每行源码都贴出来、只是贴一些注重的功效性代码
  • 实际笔者原先没用过JSBridge、15年出道的时候就已经是JSCore广泛的时代了。
  • 从零最早一行一行读、有意思味无妨一块儿。
  • ###### 随手下了叁个新式的、2017-12-19:当前版本号6.0.2。

[self.bridge registerHandler:@"getUserId" handler:^(id data, WVJBResponseCallback responseCallback) { if (responseCallback) { // 反馈给JS responseCallback(@{@"userId": @"123456"}); }}];

没什么难点、方法名、js传进来的ballback(参数、回调block)继续看.

#import "WebViewJavascriptBridge.h"- registerHandler:(NSString *)handlerName handler:(WVJBHandler)handler { _base.messageHandlers[handlerName] = [handler copy];}
  • _base:WebViewJavascriptBridge所持有的WebViewJavascriptBridgeBase对象。
  • messageHandlers:字典。存款和储蓄了注册的艺术名、ballback。

接下来、线索断了。相当于说、ios那边主动做的政工、已经没了。

哪怕在注册的时候将艺术名、block。存款和储蓄起来备用。

既然如此是备用、搜索那么些函数messageHandlers、大家得以窥见。

图片 6

  • 浅蓝部分:WebView已经WKWebview的登记事件、正是地点大家说的那么。
  • 普鲁士蓝部分:看写法就驾驭是js文件。内部确实也是js端的挂号格局。
  • 乙亥革命部分:没错青莲部分正是刚刚我们采纳的这么些字典、具体的用途了。

另外,UICollectionView自iOS 6引进以来,其效果也是不断丰硕的:

– flushMessageQueue:(NSString *)messageQueueString;
 #import "WebViewJavascriptBridgeBase.h" - flushMessageQueue:(NSString *)messageQueueString{ //省略掉其他代码之后 ...... WVJBHandler handler = self.messageHandlers[message[@"handlerName"]]; if  { NSLog(@"WVJBNoHandlerException, No handler for message from JS: %@", message); continue; } handler(message[@"data"], responseCallback); }
  • messageQueueString:字符串。自己的格式应该大致是
 "[{"handlerName":"getUserId","data":null,"callbackId":"cb_2_1513740848071"}]"

是个字符串形的json、每部含有多个参数。除了callbackId、大家应当都很好驾驭。

  • message[@”data”]: 大家报了名时候的参数。
  • responseCallback:同理可得是大家报了名时候的回调函数。
 //也是在该方法中、生成了这个responseCallback WVJBResponseCallback responseCallback = NULL; NSString* callbackId = message[@"callbackId"]; if (callbackId) { responseCallback = ^(id responseData) { if (responseData == nil) { responseData = [NSNull null]; } WVJBMessage* msg = @{ @"responseId":callbackId, @"responseData":responseData }; [self _queueMessage:msg]; }; } else { responseCallback = ^(id ignoreResponseData) { // Do nothing };

在大家接触回调的时候、大家responseCallback(@{@”userId”:
@”123456″});当中@{@”userId”:
@”123456″}。就是其一responseData。通过与callbackId关联成一个json。调用_queueMessage方法管理。

此间callbackId已经更名称为responseId。然后会再进入此大方法三遍。步入

 if (responseId) { WVJBResponseCallback responseCallback = _responseCallbacks[responseId]; responseCallback(message[@"responseData"]); [self.responseCallbacks removeObjectForKey:responseId]; } 

然后径直回调给js。这一次的回调、才是实在的返还给js。

 - _queueMessage:(WVJBMessage*)message { if (self.startupMessageQueue) { [self.startupMessageQueue addObject:message]; } else { [self _dispatchMessage:message]; } } - _dispatchMessage:(WVJBMessage*)message { NSString *messageJSON = [self _serializeMessage:message > pretty:NO]; [self _log:@"SEND" json:messageJSON]; messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\\" withString:@"\\\\"]; ******对json字符串进行一系列格式化处理***** messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\u2029" withString:@"\\u2029"]; NSString* javascriptCommand = [NSString stringWithFormat:@"WebViewJavascriptBridge._handleMessageFromObjC;", messageJSON]; if ([[NSThread currentThread] isMainThread]) { [self _evaluateJavascript:javascriptCommand]; } else { dispatch_sync(dispatch_get_main_queue(), ^{ [self _evaluateJavascript:javascriptCommand]; }); } }
  • message:

     {"responseId":"cb_3_1513741962583","responseData":{"userId":"123456"}};
    
  • javascriptCommand:

     WebViewJavascriptBridge._handleMessageFromObjC('{\"responseId\":\"cb_3_1513741962583\",\"responseData\":{\"userId\":\"123456\"}}');
    
  • _evaluateJavascript:方法底层是让webview去注入这段js函数

  • 至于_handleMessageFromObjC的实现正是属于WebViewJavascriptBridge_js文本中的范畴了。一会从js端切入的时候再去看。

于是说这段代码、正是oc重返给js的回调函数准确。

重新寻找、很鲜明了、是阻止公约并且剖断复合供给未来一直调用的。没什么太绕的事物。

图片 7

简易的标明了弹指间

 - webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { if (webView != _webView) { return YES; } NSURL *url = [request URL]; __strong WVJB_WEBVIEW_DELEGATE_TYPE* strongDelegate = _webViewDelegate; if ([_base isWebViewJavascriptBridgeURL:url]) { //js通过Bridge发起的url if ([_base isBridgeLoadedURL:url]) { //注入js(WebViewJavascriptBridge_js) [_base injectJavascriptFile]; } else if ([_base isQueueMessageURL:url]) { //js主动调启oc NSString *messageQueueString = [self _evaluateJavascript:[_base webViewJavascriptFetchQueyCommand]]; //去调用刚才分析的那个方法--(通过注册的方法名、调用对应的block) [_base flushMessageQueue:messageQueueString]; } else { //控制台报错 [_base logUnkownMessage:url]; } //拦截 return NO; } else if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:shouldStartLoadWithRequest:navigationType:)]) { //正常回调给webView的VC return [strongDelegate webView:webView shouldStartLoadWithRequest:request navigationType:navigationType]; } else { return YES; } }
  • OC将艺术名、block积累到字典。
  • OC接收到js调用的url、将block抽出。传入data/callback并调用该block。
  • OC在章程管理达成时。通过js传入的callbackId、以及我们的再次来到值作为参数、调用bridgejs文件中的_handleMessageFromObjC方法。将回到值callback给js中的钦定ballback。

  • 内需专心一点的是、JSBridge在发起呼吁的时候、并非将参数、callbackId等直接作为url发送出来。而是径直伸手*https://wvjb_queue_message/*(这或多或少应当算是内部蛮不错的地点了。相当多个人也只是领会其使用的是钻探拦截)
  • 参数通过bridgejs生成、何况赢得。具体这一步怎样兑现、上边深入分析js中调用Native的时候再来看(因为未来自家也没吧~)。
 //app.html bridge.callHandler('getUserId','参数不需要的话可以省略不谢',function{ log(response.userId) }) //WebViewJavascriptBridge_JS function callHandler(handlerName, data, responseCallback) { if (arguments.length == 2 && typeof data == 'function') { responseCallback = data; data = null; } _doSend({ handlerName:handlerName, data:data }, responseCallback); }

进展了有个别参数管理(js中过多都会基于传入参数数量的不等、内部进行更上一层楼管理)、处理终结直接丢给_doSend函数

function _doSend(message, responseCallback) { if (responseCallback) { var callbackId = 'cb_'+(uniqueId++)+'_'+new Date().getTime(); responseCallbacks[callbackId] = responseCallback; message['callbackId'] = callbackId; } sendMessageQueue.push; messagingIframe.src = CUSTOM_PROTOCOL_SCHEME + '://' + QUEUE_HAS_MESSAGE; }

此地大家看来了一个很明白的参名字callbackId

  • 正是说js的callback函数在那边会被保存起来。以callbackId为键保存在responseCallbacks那一个字典中、今后得以依赖callbackId获取、实现回调。
  • callbackId也作为新的参数、增添进了message字典中。

ok、线索又断了。剩下三个sendMessageQueue以及messagingIframe

  • messagingIframe:

其一相应比较便于驾驭。iframe是叁个内嵌的网页标签。你既然修改了对应的src、webView自然会接收一个重定向的央求。

  • sendMessageQueue

既是修改了iframe的src、让webVIew拦截了商事。sendMessageQueue自然便是为着提供参数而留存的了。

切实、大家来找找看(搜索sendMessageQueue)。

//WebViewJavascriptBridge_JSfunction _fetchQueue() { var messageQueueString = JSON.stringify(sendMessageQueue); sendMessageQueue = []; return messageQueueString;}//#import "WebViewJavascriptBridgeBase.h"- (NSString *)webViewJavascriptFetchQueyCommand { return @"WebViewJavascriptBridge._fetchQueue();";} - webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { ***省略*** //js主动调启oc NSString *messageQueueString = [self _evaluateJavascript:[_base webViewJavascriptFetchQueyCommand]]; //去调用刚才分析的那个方法--(通过注册的方法名、调用对应的block) [_base flushMessageQueue:messageQueueString]; ***省略*** }
  • _fetchQueue负担提供刚才封装的Message(含有callbackID那三个)
  • webViewJavascriptFetchQueyCommand负责在oc中注入js。调用_fetchQueue
  • webView重定向时、调用webViewJavascriptFetchQueyCommand获取参数、并且传递给flushMessageQueue去执行oc中登记格局的block。
  • iOS 9中为汇聚视图增加了交互式重新排序功效。
  • iOS
    第10中学为汇集视图增多了预加载cell数据作用,那在得到cell内容特别耗费时间的情事下十一分有效。
  • iOS 11增添了系统范围的拖放操作drag and
    drop
    ,让客户能够长足简单的将文件、图像和文件从二个app移动到另贰个app。
对呀、那就到位了。注册-调用-回调、一个闭环。具体能够翻回到再看一遍、会醒来。决定画个图。图已经身处最上面了

先看js文件呢、照旧想先从注册看起。既然大家是iOS开拓、js那边就从配置遇到伊始看代码吧。毕竟比非常多个人照旧会很好奇js中的bridge实例从哪来的。

 function setupWebViewJavascriptBridge { if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); } if (window.WVJBCallbacks) { return window.WVJBCallbacks.push; } window.WVJBCallbacks = [callback]; var WVJBIframe = document.createElement; WVJBIframe.style.display = 'none'; WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__'; document.documentElement.appendChild(WVJBIframe); setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0) }setupWebViewJavascriptBridge(function { <!-- 操作bridge --> }

这段呢、是本身从网络copy来的。基本全部教学帖子都那样用。通过调用setupWebViewJavascriptBridge方法、并传到一个callback函数、来收获bridge对象。

  • ###### 啥是callback?

实在就是大家block或者闭包、block本质上约等于个代码块而已。只可是js不爱整那么多花花事罢了。因为这几个bridge对象是在加载完大家iOS本地的bridge_js文件之后才会扭转。生成完丢进callBack还给您。

  • ###### 曾几何时加载的bridge_js文件?

事先我们深入分析代码的时候曾经提到了、iframe修改src会触发webView的代办。方法中第四行的WVJBIframe对象、正是触发加载bridge_js(wvjbscheme://__
BRIDGE_LOADED __)的iframe。

  • ###### 哪天回到的bridge对象?

艺术中的1-3行。或许看着有一些别扭、大家得以调治一下各样。

 if (window.WebViewJavascriptBridge) { callback(WebViewJavascriptBridge); return ; } if (window.WVJBCallbacks) { window.WVJBCallbacks.push; return; } window.WVJBCallbacks = [callback];

WebViewJavascriptBridge对象是在bridge_js内部被定义以及贯彻的。

当今大家就透过那篇小说,对UICollectionView张开全面包车型客车就学。

就是说:

1、借使有WebViewJavascriptBridge间接回到。2、不然每一次调用时将callback放入数组。等变化了bridge、再遍历再次来到。

 bridge.registerHandler('testJavascriptHandler', function(data, responseCallback) { var responseData = { 'Javascript Says':'Right back atcha!' }; if(responseCallback) { responseCallback(responseData); }; });

备感和oc注册格局的代码一样(其实注册和调用、两端的方法样式都是同等的)。接着看中间、其实那边的落到实处逻辑。也和oc同样。

 function registerHandler(handlerName, handler) { messageHandlers[handlerName] = handler; }

注册字典@{方法名:handler函数};

搜索messageHandlers

 function _dispatchMessageFromObjC(messageJSON) { var handler = messageHandlers[message.handlerName]; if  { console.log("WebViewJavascriptBridge: WARNING: no handler for message from ObjC:", message); } else { handler(message.data, responseCallback); } }
  • 依附message.handlerName收取对应的handler、然后把responseCallback丢进去实行。
  • responseCallback哪来的?和OC中的达成均等将callbackId、responseData一齐返还给oc的回调block。

继续往回找

 function _handleMessageFromObjC(messageJSON) { _dispatchMessageFromObjC(messageJSON);}

-_handleMessageFromObjC:那就很熟谙了。在此之前大家看看此间、然后说留到js那边深入分析。今后合计她做了什么样?

那篇小说将应用纯代码创造一个UICollectionView,用来读书会集视图。效果如下:

获得OC发来的messageJSON。里面有responseId/handlerName以及responseData。然后通过responseId将js中对应的callback调起/试行钦定已经注册函数。

然后、最终七个办法。

 - sendData:data responseCallback:(WVJBResponseCallback)responseCallback handlerName:(NSString*)handlerName { //封装message@{callbackId/handlerName/data} [self _queueMessage:message]; } - callHandler:(NSString *)handlerName data:data responseCallback:(WVJBResponseCallback)responseCallback { [_base sendData:data responseCallback:responseCallback handlerName:handlerName]; }

callHandler发起调用、sendData发送数据。和js调用oc的时候简直大同小异。

图片 8CollectionViewDragAndDrop.gif

嗯、本来感到调用的法子不一样样。可是以往总的来讲和js调用oc的点子基本同样。图也就不画了、直接去最上边看就行了。
  • responseId以及callbackId互斥。注册方发起指向调用方、后者表示调用方发起指向被调用方。
  • 对应的。handlerName也只是在存在callbackId的时候才存在、并且施行handler。因为倘若存在responseId、那个responseCallback就能直接被实施、完成回调、不会持续向下了。

打开Xcode,点击File > New > Project…,选择iOS > Application
> Single View App模板,点击NextProduct
Name
CollectionViewLanguageObjective-C,点击Next;选用文件地点,点击Create创造工程。

最后

本文首要是谐和的求学与计算。借使文内部存储器在破绽、万望留言斧正。若是不吝赐教四哥特别多谢。

为视图调整器增多UICollectonView,进入ViewController.m,在接口部分增加以投注明:

@interface ViewController ()@property (strong, nonatomic) UICollectionView *collectionView;@property (strong, nonatomic) UICollectionViewFlowLayout *flowLayout;@end

在促成都部队分最初化UICollectionViewFlowLayoutUICollectionView对象。

- (UICollectionViewFlowLayout *)flowLayout { if (!_flowLayout) { // 初始化UICollectionViewFlowLayout对象,设置集合视图滑动方向。 _flowLayout = [[UICollectionViewFlowLayout alloc] init]; _flowLayout.scrollDirection = UICollectionViewScrollDirectionVertical; } return _flowLayout;}- (UICollectionView *)collectionView { if (!_collectionView) { // 设置集合视图内容区域、layout、背景颜色。 _collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:self.flowLayout]; _collectionView.backgroundColor = [UIColor whiteColor]; // 设置代理。// _collectionView.dataSource = self;// _collectionView.delegate = self; } return _collectionView;}

最后增加self.collectionView到视图调控器。

- viewDidLoad { [super viewDidLoad]; // 添加collection view。 [self.view addSubview:self.collectionView];}

UICollectionView行使了视图回收机制以增加质量。当视图被滑出显示器外时,从视图层级结构中移除的视图不会一贯删除,而是置于重用队列中。当UICollectionView来得新的剧情时,将从录取队列中拿走视图、填充新的从头到尾的经过。为方便回收和重用,UICollectionView显示的有所视图必得派生自UICollectionReusableView

UICollectionView帮忙二种不一致档案的次序的可选择视图,每个视图都有特定的用处:

  • 聚拢视图单元格UICollectionViewCell:突显集合视图的入眼内容。cell必得是UICollectionViewCell类的实例。cell暗许支持管理自身高亮highlight选中selection状态。
  • 补给视图Supplementary
    View
    :展现关于section的信息。和cell没有差异于supplementary
    view也是数额驱动的,但与cell不等的是supplementary
    view的施用不是必得的,layout垄断(monopoly)supplementary
    view的职责和是不是接纳。比如,流式布局UICollectionViewFlowLayout能够选拔性增添页眉section
    header
    页脚section footer补给视图。
  • 装修视图Decoration
    View
    :由layout一心具有的装裱视图,且不受数据源的约束。比如,layout能够运用装饰视图自定义集结视图背景。
标签:

发表评论

电子邮件地址不会被公开。 必填项已用*标注

相关文章

网站地图xml地图