UITableView & UITableViewController
内容概要:
本文先讲解了UITableView概述,然后主要从应用方面讲解了UITableViewController(包括add、delete、move单元cell的操作,以及UITableViewDelegate和UITableViewDataSource的相关知识),然后讲解了UITableViewCell的相关知识,其中cell的重用机制在应用中最为重要,最后讲解了有关ScrollView的相关知识,并封装了一个支持"下拉刷新"和"上拉加载更多"的UITableView子类。
目录:
1.UITableView概述
(1.1) UITableView继承关系
(1.2) UITableView和UITableViewController的关系
(1.3)UITableView的2种header和footer
2.UITableViewController
(2.1)UITableViewController初始化方法
(2.2)UITableViewController常用设置
(2.3)编辑UITableView
(2.3.1) add (2.3.2) delete(2.3.3)move
(2.4) UITableViewDelegate方法、UITableViewDataSource方法
3. UITableViewCell
(3.1)UITableViewCell组成
(3.2)UITableViewCell初始化方法
(3.3)UITableViewCellStyle
(3.4) UITableViewCells复用机制
(3.5) UITableViewCell的contentView与cell的2种模式的关系
4. UITableViewController的下拉刷新上拉加载
(4.1)UIScrollView的几个关键概念
(a)contentSize(b)contentInset(c)contentOffset
(4.2)下拉刷新、上拉加载
(4.2.1)类的设计
(4.2.2)下拉刷新、上拉加载用到的属性、方法
(4.2.3)下拉刷新及其代码实现
(4.2.4)上拉加载及其代码实现
(4.2.5)github代码
5. reload
(5.1)刷新整个tableView
(5.2)刷新某个section
(5.3)刷新某个cell
6. MVVM模型在tableViewController中的使用
正文内容:
1.UITableView概述
(1.1) UITableView继承关系:UITableView:UIScrollView : UIView : UIResponder : NSObject
(1.2) UITableView和UITableViewController的关系:
UITableView属于MVC的View部分,另外它还需要自己的Model和Controller部分:(1)UITableView需要一个ViewController控制显示,UITableViewController负责此角色;(2)UITableView需要数据源data source(即Model部分),UITableViewController遵守UITableViewDataSource协议,因此UITableViewController也负责此角色;(3)UITableView需要代理通知其它对象关于UITableView的事件,这个代理需遵守UITableViewDelegate协议,因此UITableViewController也负责此角色。
UITableView和UITableViewController的关系可用如下图表示:

图1.2 UITableView和UITableViewController的关系
(https://github.com/SheronLv/Images/blob/master/UITableView/UITableView和UITableViewController的关系.png)
(1.3)UITableView的2种header和footer (a)2种header:table header和section header;(b)2种footer:table footer和section header。
2.UITableViewController
(2.1)UITableViewController初始化方法
UITableViewController的指定初始化方法是initWithStyle:
- (instancetype)initWithStyle:(UITableViewStyle)style;
其中UITableView的style 有两种:UITableViewStylePlain、UITableViewStyleGrouped。当UITableView创建时,必须指定它为这两种style中的一种,而且指定之后,不能再改变。
UITableViewController用Nib加载方式:
-(id)init{
return [self initWithNibName:@"NVShanHuiViewController" bundle:nil];
}
-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.dragRefresh = YES;
}
return self;
}
(2.2)UITableViewController常用设置:
//设置每行不可选:
self.tableView.allowsSelection = NO;
//设置分割线:
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;//UITableViewCellSeparatorStyleSingleLine
self.tableView.separatorColor = [UIColor blueColor];
//设置cell选中状态
cell.selectionStyle = UITableViewCellSelectionStyleNone;
// 清除tableview的选中状态
- (void)deselectTableView {
NSIndexPath *selected = [self.tableView indexPathForSelectedRow];
if(selected)
[self.tableView deselectRowAtIndexPath:selected animated:YES];
}
(2.3) 编辑UITableView:add、delete、move
(2.3.1) add
//“增加item”的按钮
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(, , self.view.bounds.size.width-, )];
UIButton *addButton = [[UIButton alloc] initWithFrame:CGRectMake(, , , )];
[addButton setTitle:@"add Item to section 1" forState:UIControlStateNormal];
[addButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[addButton addTarget:self action:@selector(addItem) forControlEvents:UIControlEventTouchUpInside];
[addButton.layer setMasksToBounds:YES];
[addButton.layer setBorderWidth:1.0];
addButton.backgroundColor = [UIColor colorWithRed: green: blue: alpha:0.1];
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGColorRef colorref = CGColorCreate(colorSpace,(CGFloat[]){ , , , 0.25 });
[addButton.layer setBorderColor:colorref];
[headerView addSubview:addButton];
self.tableView.tableHeaderView = headerView; // 点击按钮,为第1个Section添加row。此时会去执行cellForRowAtIndexPath中的对应IndexPath创建cell并添加
- (void)addItem {
NSInteger num = [self.dataArray[] count];
NSMutableArray *array = [NSMutableArray arrayWithArray:self.dataArray[]];
[array addObject:@"new"];
self.dataArray[] = array;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:num inSection:];
[self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];
}
(2.3.2)delete
//如果没有写此方法,就自动不会出现“delete”的操作;实现了此方法,就会自动出现“delete”的操作
- (void) tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
if(editingStyle == UITableViewCellEditingStyleDelete) {
[self changeDataArrayForDelete:indexPath];
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
-(void)changeDataArrayForDelete:(nonnull NSIndexPath *)indexPath {
if( indexPath.section == ) return;
NSInteger section = indexPath.section;
NSMutableArray *array = [NSMutableArray arrayWithArray:self.dataArray[section]];
[array removeObjectAtIndex:indexPath.row];
self.dataArray[section] = array;
}
(2.3.3)move
//设置为可编辑状态
[self.tableView setEditing:YES animated:YES]; // 移动时之行此dataSource方法,并不会触发相应的cellForRowAtIndexPath方法
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(nonnull NSIndexPath *)sourceIndexPath toIndexPath:(nonnull NSIndexPath *)destinationIndexPath {
[self changeDataArrayForMoveFromIndexPath:sourceIndexPath toIndexPath:destinationIndexPath];
} - (void)changeDataArrayForMoveFromIndexPath:(nonnull NSIndexPath *)sourceIndexPath toIndexPath:(nonnull NSIndexPath *)destinationIndexPath {
if(sourceIndexPath.section == || sourceIndexPath == destinationIndexPath){
return;
}
NSInteger sourceSection = sourceIndexPath.section;
NSMutableArray *array = [NSMutableArray arrayWithArray:self.dataArray[sourceSection]];
NSString *theString = [array objectAtIndex:sourceIndexPath.row];
[array removeObjectAtIndex:sourceIndexPath.row];
self.dataArray[sourceSection] = array; NSInteger destinationSection = destinationIndexPath.section;
array = [NSMutableArray arrayWithArray:self.dataArray[destinationSection]];
[array insertObject:theString atIndex:destinationIndexPath.row];
self.dataArray[destinationSection] = array;
}
(2.4) UITableViewDelegate方法、UITableViewDataSource方法
//UITableViewDelegate
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section;
- (nullable UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;
- (nullable UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath; //UITableViewDataSource
@required
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
@optional
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
- (nullable NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;
- (nullable NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section;
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath;
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath;
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath;
- (nullable NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView __TVOS_PROHIBITED;
3. UITableViewCell
(3.1)UITableViewCell组成:
UITableViewCell由contentView和Accessory indicator组成,其中contentView包含3个subView:imageView、textLabel和detailTextLabel,各view的包含关系如下图:

图3.1 UITableViewCell的组成元素
(3.2)UITableViewCell初始化方法:
UITableViewCell用如下指定初始化方法初始化UITableViewCell:
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(nullable NSString *)reuseIdentifier;
(3.3)UITableViewCellStyle
UITableViewCell的contentView包含3个subView:imageView、textLabel和detailTextLabel,上面代码中指定初始化的style决定了contentView中是否展示某个subView以及各个subView展示的位置,style一共有4种:
(1)UITableViewCellStyleDefault (2)UITableViewCellStyleSubtitle (3)UITableViewCellStyleValue1 (4)UITableViewCellStyleValue2
效果依次如下:

图3.3 UITableViewCellStyle的4种形式的效果图
(3.4) UITableViewCells复用机制
使用以下2种方法即使用cell的复用机制创建cell:
(1)- (nullable __kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier; // Used by the delegate to acquire an already allocated cell, in lieu of allocating a new one.
(2)- (__kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0); // newer dequeue method guarantees a cell is returned and resized properly, assuming identifier is registered
当用户滑动table时,一些cell会滑出屏幕,滑出屏幕的cells会被放入cell池中以供复用。当用上面两种方法创建cell时,data source会首先在cell池中查看是否有可供复用的cell存在,当存在时,就直接从cell池中取,当cell池中没有可用的cell时,才创建新的。
注意事项:
// 用(1)创建cell后,必须判断cell是否为nil。
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
// 用(2)创建cell前,必须要对cell进行注册:
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cellIdentifier_1"];
[self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([NVBankCardInfoCell class]) bundle:nil] forCellReuseIdentifier:@"cellIdentifier_2"];
(3.5) UITableViewCell的contentView与cell的2种模式的关系
UITableViewCell的subView要添加到cell.contentView里,因为:cell有两种模式:standard mode和editing mode, 如图所示:

图3.5 cell两种模式
contentView在这两种模式下会自动调整。
4. UITableViewController的下拉刷新上拉加载
(4.1)UIScrollView的几个关键概念:
UITableView继承自UIScrollView,UIScrollView有几个关键属性:contentSize、contentOffset、contentInset。
(a)contentSize是UIScrollView可以滑动的范围的大小;tabelview的contentsize是由它的下列方法共同实现的:
- (NSInteger)numberOfSections;
- (NSInteger)numberOfRowsInSection:(NSInteger)section;
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section;
它会自动计算所有的高度和来做为它的contentsize的height.
(b)contentInset的单位UIEdgeInsets定义如下:
typedef struct UIEdgeInsets {
CGFloat top, left, bottom, right; // specify amount to inset (positive) for each of the edges. values can be negative to 'outset'
} UIEdgeInsets;
比如设置contentInset如下:
self.tableView.contentInset = UIEdgeInsetsMake(5, 6, 7, 8);//top left bottom right
这句代码的意思是说,self.tableView的内容距离self.view的边缘的距离分别是top:50, left:60, bottom:70, right:80.
(c)contentOffset的单位是CGPoint。它不是用来设置contentView,是衡量scrollview当前显示区域顶点相对于self.view原点的偏移量.比如,下拉加载时,contentOffset.y就是负值(显示区域的顶点在原点之上);当往上滑动tableView则显示的内容是相对原点往下20个偏移量,那个它的contentOffset就是(0, 20),即contentOffset.y是正值(显示区域的顶点在原点之下).
(4.2)下拉刷新、上拉加载
(4.2.1)类的设计
LVTableViewController:实现下拉刷新、上拉加载功能的tableViewController;
LVRefreshHeaderView:下拉刷新时,展示各种下拉刷新状态的headerView;
LVLoadingCell:上拉加载Cell。
(4.2.2)下拉刷新、上拉加载用到的属性、方法:
(a) property:dragRefresh
BOOL型,在整个NVTableViewController初始化时设置是否启用下拉刷新功能。
如果设置了dragRefresh为YES,则NVTableViewController在加载视图(viewDidLoad)时会创建EGORefreshTableHeaderView的实例作为当前tableView的子视图。EGORefreshTableHeaderView随着手势的不同展示三种状态:正常状态、下拉状态、数据加载状态。
(b)- (UITableViewCell *)dequeueMoreCell;
返回可复用的载入更多的CELL:首先返回loading Cell,随后会调用[loadNext]方法
(c) -(void)loadNext;
需子类复写,当显示载入更多的CELL时会触发该方法,子类在该方法中进行网络请求需要加载的更多的数据。
(d)- (BOOL)refreshData;需子类复写,下拉刷新时子类中重新进行刷新的数据请求,父类会在scrollViewDidEndDecelerating:中根据[refreshData]的返回值设置刷新状态显示。
(4.2.3)下拉刷新及其代码实现

图4.2 下拉刷新三种状态
主要实现如下:
LVRefreshHeaderView里的主要代码:
typedef NS_ENUM(NSUInteger, LVPullRefreshState){
LVPullRefreshNormal = , //refreshHeaderView隐藏的状态
LVPullRefreshPulling, // 下拉状态
LVPullRefreshLoading, // 加载状态
};
- (void)setState:(LVPullRefreshState)aState {
switch (aState) {
case LVPullRefreshNormal:
self.statusLabel.text = @"下拉可以刷新...";
NSLog(@"下拉可以刷新...");
[self.indicatorView stopAnimating];
self.arrowImageView.hidden = NO;
break;
case LVPullRefreshPulling:
self.statusLabel.text = @"松开即可刷新...";
NSLog(@"松开即可刷新...");
[self setImageAnimated];
break;
case LVPullRefreshLoading:
self.statusLabel.text = @"加载中...";
NSLog(@"加载中...");
[self.indicatorView startAnimating];
self.arrowImageView.hidden = YES;
break;
default:
break;
}
}
LVTableViewController的主要代码:
#pragma mark Drag & Refresh
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if(!self.dragRefresh) {
return;
}
if(scrollView.isDragging) {
if(self.refreshHeaderView.state == LVPullRefreshPulling && scrollView.contentOffset.y > -65.0f && scrollView.contentOffset.y < 0.0f && !_reloading) {
//拉动距离小于65
[self.refreshHeaderView setState:LVPullRefreshNormal];
} else if(self.refreshHeaderView.state == LVPullRefreshNormal && scrollView.contentOffset.y < -65.0f && !_reloading) {
//拉动距离大于65
[self.refreshHeaderView setState:LVPullRefreshPulling];
}
}
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
if(!self.dragRefresh) {
return;
}
NSLog(@"c:%f",scrollView.contentOffset.y);
if (scrollView.contentOffset.y <= - 65.0f && !_reloading) {
_reloading = YES;
if([self refreshData]) {
[self.refreshHeaderView setState:LVPullRefreshLoading];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.2];
self.tableView.contentInset = UIEdgeInsetsMake(60.0f, 0.0f, 0.0f, 0.0f);
[UIView commitAnimations];
} else {
[self refreshFinished];
}
}
}
- (void)refreshFinished{
if (!self.dragRefresh) return;
if (_reloading) {
_reloading = NO;
[UIView animateWithDuration:. animations:^{
[self.tableView setContentInset:UIEdgeInsetsMake(0.0f, 0.0f, 0.0f, 0.0f)];
} completion:^(BOOL finished) {
[self.refreshHeaderView setState:LVPullRefreshNormal];
}];
}
}
- (BOOL)refreshData {
return NO;
}
(4.2.4)上拉加载及其代码实现
- (void)loadNext {
}
- (UITableViewCell *)dequeueMoreCell {
UITableViewCell * cell = [self dequeueLoadingCell];
cell.backgroundColor = [UIColor clearColor];
[self performSelector:@selector(loadNext) withObject:nil afterDelay:0.0];
return cell;
}
(4.2.5)github代码
https://github.com/SheronLv/LVTableViewController.git
其中包括了LVTableViewController实现了tableView的下拉刷新和上拉加载,MyBusinessTableViewController里面实现对tableViewController的一些验证,如有不当之处,欢迎提出批评指正。
5. reload
(5.1)刷新整个tableView
[self.tableView reloadData];
(5.2)刷新某个section
//一个section刷新
NSIndexSet *indexSet=[[NSIndexSet alloc]initWithIndex:];
[tableview reloadSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];
(5.3)刷新某个cell
//一个cell刷新
NSIndexPath *indexPath=[NSIndexPath indexPathForRow: inSection:];
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath,nil] withRowAnimation:UITableViewRowAnimationNone];
//或者:
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
6. MVVM模型在tableViewController中的使用
MVVM模型中的viewModel使用三个信号控制tableView中的显示,这三个信号分别是接口是否正在请求(loading信号)、接口请求成功(loadingSuccess信号)和接口请求失败(errorMsg信号)。关键代码如下所示:
(1)viewModel中的信号和数据请求
//数据请求情况
@property (nonatomic, assign) BOOL loading;
@property (nonatomic, assign) BOOL loadingSuccess;
@property (nonatomic, strong) NSString * errorMsg;
//数据请求
- (void)queryData {
self.loading = YES;
@weakify(self);
[[[NVNetworkClient client] queryData] subscribeNext:^(DataQueryed * data) {
@strongify(self);
//释放请求的data给外部使用
self.loading = NO;
self.loadingSuccess = YES;
} error:^(NSError * error) {
@strongify(self);
self.loading = NO;
self.loadingSuccess = NO;
self.errorMsg = [error nv_message];
}];
}
(2)tableViewController中初始化使用
-(void) viewDidLoad {
[super viewDidLoad];
self.viewModel = [[MyViewModel alloc] init];
[self bindEvent];
[self.viewModel queryData];
}
- (void)bindEvent{
//提示网络错误
@weakify(self);
[RACObserve(self.viewModel, errorMsg) subscribeNext:^(NSString * errorMsg) {
@strongify(self);
[self setShowLoading:NO];
if(errorMsg&&errorMsg.length>){
[self showSplash:dgErrorMsg];
}
[self.tableView reloadData];
[self refreshFinished];
}];
//请求成功
[RACObserve(self.viewModel, loadingSuccess) subscribeNext:^(NSNumber * loadingSuccess) {
@strongify(self);
if ([loadingSuccess boolValue] == YES) {
[self setShowLoading:NO];
[self.tableView reloadData];
[self refreshFinished];
}
}];
}
(3)tableView各delegate对viewModel的运用
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
if (self.viewModel.rcLoadingSuccess == YES) {
//返回正常需要的section个数
} else if (self.viewModel.loadingSuccess == NO && self.viewModel.errorMsg != nil) {
return ;
}
return ;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
if (正常情况) {
return 正常cell;
}
return ; // 包括特殊的没请求成功的情况,1个cell
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.section == && !self.viewModel.rcLoadingSuccess) {
return NVErrorPageViewHeight;
}
return 正常需要的高度;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
if (!self.viewModel.loadingSuccess) {
UITableViewCell * cell = [self dequeueEmptyWithAnnounceCell:@"网络不给力,下拉刷新重试!" hintMessage:nil emptyType:kNothing_Empty];
return cell;
}
if (正常情况) {
return 正常cell;
}
return [UITableViewCell new];
}
UITableView & UITableViewController的更多相关文章
- iOS UITableView , UITableViewController ,UITableViewCell实现全国各省市遍历,选择相应的地区
我们先看一下效果 代码如下 首先是第一个页面 rootTableViewController.h #import <UIKit/UIKit.h> #im ...
- iOS programming UITableView and UITableViewController
iOS programming UITableView and UITableViewController A UITableView displays a single column of dat ...
- iOS 开发快速导引:TableView 和 CoreData【草】
所有列表式的数据都是用 TableView 显示的 预览 待补充 原料 NSFetchedResultsController 用来操作 NSFetchRequst,有执行查询,监听变化,数据缓存等功能 ...
- iOS 底层框架的浅析
1.简介 IOS是由苹果公司为iPhone.iPod touch和iPad等设备开发的操作系统. 2.知识点 iPhone OS(现在叫iOS)是iPhone, iPod touch 和 iPad 设 ...
- IOS计划 分析
1.基本介绍 IOS苹果公司iPhone.iPod touch和iPad操作系统和其他设备的发展. 2.知识点 1.IOS系统 iPhone OS(现在所谓的iOS)这是iPhone, iPod to ...
- iOS底层框架浅析
1.简介 IOS是由苹果公司为iPhone.iPod touch和iPad等设备开发的操作系统. 2.知识点 iPhone OS(现在叫iOS)是iPhone, iPod touch 和 iPad 设 ...
- iOS UITableView 与 UITableViewController
很多应用都会在界面中使用某种列表控件:用户可以选中.删除或重新排列列表中的项目.这些控件其实都是UITableView 对象,可以用来显示一组对象,例如,用户地址薄中的一组人名.项目地址. UITab ...
- UITableView 和 UITableViewController
UITableView:显示有多行数据的一个列. 新建一个过程:Xcode -> File -> New -> Project...,然后选择iOS -> Applicatio ...
- iOS学习笔记之UITableViewController&UITableView
iOS学习笔记之UITableViewController&UITableView 写在前面 上个月末到现在一直都在忙实验室的事情,与导师讨论之后,发现目前在实验室完成的工作还不足以写成毕业论 ...
随机推荐
- BZOJ3941 : [Usaco2015 Feb]Fencing the Herd
若所有点同侧则表明将各个点带入直线解析式ax+by-c后得到的值均同号等价于最大值和最小值同号考虑CDQ分治,每一步分治的过程中求出上下凸壳,然后三分答案即可时间复杂度$O(n\log^2n)$ #i ...
- 使用jQuery操作Cookies的实现代码
Cookie是由服务器端生成,发送给User-Agent(一般是浏览器),浏览器会将Cookie的key/value保存到某个目录下的文本文件内,下次请求同一网站时就发送该Cookie给服务器(前提是 ...
- lvs原理和实战
lvs-dr原理 lvs-nat原理: 当我们的网站流量越来越大时一台web服务器已经无法满足需求了,我们该如何解决呢??把服务器连接起来实现负载均衡或许是个不错的办法..下面我就来看看怎么实现吧 ...
- 写sql语句连接的时候注意的一个小细节
我在写权限的查询的时候,用到了sql语句的链接写一下出错的时候的代码 $sqlpid="select auth_name from sw_auth where auth_level=0&qu ...
- java 处理xml格式数据
1.单个xml文件 package lia.meetlucene; import java.io.*; import javax.xml.parsers.DocumentBuilder; import ...
- nodejs安装和环境搭建
环境下载 根据系统类型,系统位数选择需要的版本下载.下载地址:https://nodejs.org/en/download/ msi:开发环境,包含运行环境,开发文档等,所以我们下载.msi. exe ...
- Powershell连接Office 365各组件的方法
参考: http://www.exchangecn.com/office365/20150108_540.html 1. 适用于 IT 专业人员 RTW 的 Microsoft Online Serv ...
- 《GK101任意波发生器》升级固件发布(版本:1.0.2build955)
一.固件说明: 硬件版本:0,logic.3 固件版本:1.0.2.build955 编译日期:2015-12-14 ====================================== 二. ...
- 《GK101任意波发生器》升级固件发布(版本:1.0.2build690)
一.固件说明: 硬件版本:0,logic.3 固件版本:1.0.2.build690 编译日期:2015年4月24日 ====================================== 二. ...
- java类的继承
继承就是在一个现有类型的基础上,通过增加新的方法或者重定义已有方法(重写)的方式,产生一个新的类型.继承是面向对 象的三个基本特征--封装.继承.多态的其中之一,我们在使用java时编写的每一个类都是 ...