在前面2篇关于Table View的介绍中,我们使用的Style都是Plain,没有分组,没有index,这次学习的Table View和iphone中的通讯录很像,有一个个以字符为分割的组,最右边有一列小字符作为index,最顶端有一个搜索栏可以进行搜索,好了,下面开始这次的学习。

1)创建一个新的项目,template选择Single View Application,命名为Sections

2)添加Table View,连接delegate和data source到File's Owner
选中BIDViewController.xib文件,从Object Library中拖一个Table View到view上,然后选中view中的table view,打开Connections Inspector,拖动dataSource和delegate右边的小圆圈到File's Owner上

3)改变Table View style
还是选中view中的table view,然后选择Attributes inspector,将Style改成“Grouped”

可以看到,table view的样子发生了改变,展现的形式和iphone中的Setting有点类似,一块一块的,这样的table view我们可以叫它Grouped table(之前2篇中所呈现的table view的样式我们称之为Plained table,如果在Plained table的右边加一列索引,我们就称之为Indexed table,indexed table是我们这张重点要学习的)

3)导入数据
我们这篇所要学习的是数据的分组和索引的内容,因此我们需要大量的数据来做实验,下载下面的文件,然后拖入到项目中,放置在Sections文件夹下
sortednames.plist.zip
选中sortednames.plist,在右边可以看到文件的内容,文件的格式应该很熟悉了,我们已经多次使用过,sortednames.plist以26个英文字母为key进行分组,各组中的单词都是以该组的key开头的。

4)写代码
打开BIDViewController.h,添加如下代码

#import <UIKit/UIKit.h>

@interface BIDViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>

@property (strong, nonatomic) NSDictionary *names;
@property (strong, nonatomic) NSArray *keys;
@end

NSDictionary用于存放sortednames.plist中的数据,用key来对应,NSArray用来存放key

打开BIDViewController.m,添加如下代码

#import "BIDViewController.h"

@implementation BIDViewController
@synthesize names;
@synthesize
keys; ...... #pragma mark - View lifecycle - (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSString *path = [[NSBundle mainBundle] pathForResource:@"sortednames" ofType:@"plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
self.names = dict; NSArray *array = [[names allKeys] sortedArrayUsingSelector:@selector(compare:)];
self.keys =
array;
} - (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
self.names = nil;
self.keys =
nil;
}

上面的code现在读起来应该很容易了,唯一可以稍微解释一下的就是在viewDidLoad中,使用NSBundle来找到sortednames.plist文件,NSDictionary使用initWithContentsOfFile的方法来读取数据。其他的应该不用解释了。下面继续在BIDViewController.m中添加代码

#pragma mark -
#pragma mark Table View Data Source Methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [self.keys count];
} - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSString *key = [keys objectAtIndex:section];
NSArray *nameSection = [names objectForKey:key];
return [nameSection count];
} - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row]; NSString *key = [keys objectAtIndex:section];
NSArray *nameSection = [names objectForKey:key]; static NSString *SectionsTableIdentifier = @"SectionsTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SectionsTableIdentifier];
if(cell == nil) {
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:SectionsTableIdentifier];
} cell.textLabel.text = [nameSection objectAtIndex:row];
return cell;
} - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSString *key = [keys objectAtIndex:section];
return key;
}

这里多了2个新的方法,解释如下:
numberOfSectionsInTableView:tableView,这个方法是返回table view中有多少个section(group)的,因为之前的2篇中section只有一个,因此也就无需这个方法来返回section的数量了
tableView:titleForHeaderInSection,这个方法用来设置每个section的title的文字
其他的2个方法都很熟悉,一个用来返回每个section中row的数量,另一个用来创建UITableViewCell。
一般来说,table view都是分section的,很少有单一的section的情况,所以在这里每次都要先确定在那个section中,然后在进行针对cell的操作,上面的code还是很直观的,应该很容易理解。

5)编译运行
编译运行程序,效果如下

每个section一个group,每个section上都有自己的title。如果你将刚才我们设置的table view的style改成Plain,在此运行,效果会变成一下的样子


这个就是Plain和Grouped的区别

6)添加Index
上面虽然已经实现的table view,但是用起来还是非常的不方便,例如我们想寻找Z开头的名字,我们需要花半天时间,从A一直滑动到Z,这样子手是会抽筋的,因此,我们需要一个index,能够帮我们进行快速定位(根据key值进行索引),在BIDViewController.m中,添加如下代码

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return keys;
}

sectionIndexTitlesForTableView用于设置index,它返回index的集合,在这个例子中,我们的keys是26个英文字母,我们把这个作为index,在index中,每一个字母和一个section对应,第1个字母对应第一个section,第2个字母对应第二个section,以此类推。是不是比想象的要简单的多?编译运行程序,table view的右边出现一列index,选中index中的“Z”,我们可以快速定位到Z对应的section

现在我们可以很方便的定位到需要的section,然后在该section下寻找相关的name,但是还不是最最方便,很多情况下,我们需要一个搜索功能,搜索那些包含特定字母的name,这个可以更快的寻找到我们需要的name,下面我们就为实现table view的搜素功能。

7)实现搜索栏(Search Bar)
我们先添加一些文件和代码,为等会添加search bar做一些准备,选中Project navigator中的Sections文件,然后command+N,添加一个新的文件。在弹出的对话框中,左边选择Cocoa Touch,右边选择Objective-C category,然后点击Next

在下一个界面中设置Category和Category on如下,单击Next

点击Create,完成文件创建

如果你学过Objective-C,那么你一定知道什么是Category,如果你对Objective-C不熟悉,那你肯定会有疑问,为什么文件名有些诡异(文件名的中间有个加号),这个是Objective-C中独有的一种特性、语法现象叫做“Category”,就是为一个已有的类添加一个方法而不需要生成其子类,简单的理解就是在特定的情况下,单独为已存在的类添加一个方法,从上面的名叫命名可以看出NSDictionary+MutableDeepCopy,NSDictionary是已有的类,MutableDeepCopy是为已有的类添加方法,好吧,基本原理就是这些,如果还是有疑惑,那就google、百度一下吧,很快就会找到答案的。

打开NSDictionary+MutableDeepCopy.h,添加如下代码

#import <Foundation/Foundation.h>

@interface NSDictionary (MutableDeepCopy)
- (NSMutableDictionary *)mutableDeepCopy;
@end

这里为NSDictionary添加了一个mutableDeepCopy的方法,再打开NSDictionary+MutableDeepCopy.m,添加如下代码

@implementation NSDictionary (MutableDeepCopy)

- (NSMutableDictionary *)mutableDeepCopy {
NSMutableDictionary *returnDict = [[NSMutableDictionary alloc] initWithCapacity:[self count]];
NSArray *keys = [self allKeys];
for(id key in keys) {
id oneValue = [self valueForKey:key];
id oneCopy = nil; if([oneValue respondsToSelector:@selector(mutableDeepCopy)])
oneCopy = [oneValue mutableDeepCopy];
else if([oneValue respondsToSelector:@selector(mutableCopy)])
oneCopy = [oneValue mutableCopy];
if (oneCopy == nil)
oneCopy = [oneValue copy];
[returnDict setValue:oneCopy forKey:key]; }
return returnDict;
}
@end

这里是对mutableDeepCopy方法进行实现,从字面意思就可以清楚的知道是对一个NSDictionary对象进行深拷贝(这个概念在C#中也有,是类似的东西),实现深拷贝的原因再后面会说到。

打开BIDViewController.h,添加如下代码

#import <UIKit/UIKit.h>

@interface BIDViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate>

@property (strong, nonatomic) NSDictionary *names;
@property (strong, nonatomic) NSArray *keys;
@property (strong, nonatomic) NSMutableDictionary *names;
@property (strong, nonatomic) NSMutableArray *keys;
@property (strong, nonatomic) IBOutlet UITableView *table;
@property (strong, nonatomic) IBOutlet UISearchBar *search;
@property (strong, nonatomic) NSDictionary *allNames; - (void)resetSearch;
- (void)handleSearchForTeam:(NSString *)searchTerm;
@end

引入UISearchBarDelegate,之后的searchbar需要这个协议来实现方法
删除之前声明的names和keys,替换成mutable(可修改的)的Dictionary和Array,因为之后有对names和keys的删除操作,NSDictionary和NSArray都是immutable(不可修改的),我们的搜索结果是比较所有的names,把不符合的names从dictionary中删除,把不符合的key从array中删除,所以dictionary和array必须是可修改的,因此我们声明NSMutableDictionary和NSMutableArray
声明2个outlet分别控制table view和searchbar
声明一个NSDictionary,用于存放完整的names

8)添加Search Bar
选中BIDViewController.xib,在Object library中找到Search Bar,把Search Bar放在view的最顶端,searchbar会自动拉伸以适应屏幕的宽度,table view会自动空出顶部searchbar的位置

选中searchbar,打开attributes inspector,找到Options下的“Shows Cancel Button”,这样一个Cancel按钮会出现在search栏的右边

ok,此时我们先build一下我们的project,当然会有很多警告出现,我们暂时无视,然后运行程序,一个bug出现了

最右边的index和searchbar上的Cancel按钮重叠了,好吧,我们必须解决这个问题,解决的方法可以说比较笨拙但也可以认为比较巧妙,大致的方法是在searchbar下面放一个垫背的View控件,然后这个垫背的View控件上放2个其他的控件,一个是searchbar,另一个是navigation bar。View控件的作用有2个,一是占据table view上的空间,当往table view上拖一个View控件时,table view会自动让出顶部的hearder section;View控件的第二个作用是它可以容纳其他的控件,可以在它上面放置searchbar和navigation bar(为什么要使用navigation bar,这个后面会解释)。

好了,下面我们进行具体的操作,先将searchbar从table view上面删除,然后在Object library中找到View控件

将View控件拖到table view的顶部,table view上会有一个蓝色的小框框出现(table view的hearder section),将View放置在其中

再从Object library中拖一个Search Bar到View上,调整Search Bar的宽度到295(选中searchbar的情况下,打开size inspector,设置Width=295)

最后一步是拖一个navigation bar,在Object library中找到Navigation Bar

默认的Navigation Bar会充满整个View控件

先双击navigation bar上的Title,然后将Title删除,我们这里不需要使用到文字内容,然后调整navigation bar的宽度,在dock中选中“Navigation Bar”

拖动左边的点,使其的宽度缩小为25px,这样navigation bar的宽度正好填充了刚才search bar空出的宽度,而且search bar从见天日了。

选中searchbar,打开attributes inspector,在Options下的选中“Shows Cancel Button”,在Placeholder中填入“Search”,再编译运行一次,最终的效果如下

怎么样,很完美吧,完全看不出来是2个控件,这里可以解释一下选择Navigation Bar的原因了,因为Navigation Bar删除title后,其背景颜色和Search Bar是一样的,这样我们就可以使2个控件看上去“合二为一”,最终达到我们需要的效果。但是为什么不直接拖一个Navigation Bar呢?因为Navigation Bar无法让table view为其留出顶部的header section,所有需要View控件来代劳。

9)连接
选中File's Owner,control-drag到table view,在弹出的框中选择“table”

同样的方法,control-drag到search bar,选择“search”

这样就将刚才在BIDViewController.h中定义的2个outlet分类连接到了它们负责的对象上面。

选中search bar,打开connections inspector,将delegate拖动到File's Owner上,我们在BIDViewController.h中引入了UISearchBarDelegate,因此就让这个search bar到BIDViewController中去寻找方法。

10)写代码
打开BIDViewController.m,添加如下代码

#import "BIDViewController.h"
#import "NSDictionary+MutableDeepCopy.h" @implementation BIDViewController
@synthesize names;
@synthesize keys;
@synthesize table;
@synthesize search;
@synthesize allNames; #pragma mark -
#pragma mark Custom Methods
- (void)resetSearch {
self.names = [self.allNames mutableDeepCopy];
NSMutableArray *keyArray = [[NSMutableArray alloc] init];
[keyArray addObjectsFromArray:[[self.allNames allKeys] sortedArrayUsingSelector:@selector(compare:)]];
self.keys = keyArray;
} - (void)handleSearchForTeam:(NSString *)searchTerm { NSMutableArray *sectionsToRemove = [[NSMutableArray alloc] init];
[self resetSearch]; for (NSString *key in self.keys) {
NSMutableArray *array = [names valueForKey:key];
NSMutableArray *toRemove = [[NSMutableArray alloc] init];
for (NSString *name in array) {
if ([name rangeOfString:searchTerm options:NSCaseInsensitiveSearch].location == NSNotFound) {
[toRemove addObject:name];
}
}
if ([array count] == [toRemove count]) {
[sectionsToRemove addObject:key];
} [array removeObjectsInArray:toRemove];
}
[self.keys removeObjectsInArray:sectionsToRemove];
[table reloadData];
}

引入NSDictionary+MutableDeepCopy.h,就可以调用我们定义的mutableDeepCopy方法了

resetSearch:是一个SearchBar的delegate,用于初始化搜索内容,将完整的names和keys复制到NSMutableDictionary和NSMutableArray中,之后的搜索就搜索这2个对象中的内容,可以对他们进行删除操作。这个方法会在点击searchbar上的Cancel按钮和当搜索的关键词发生改变时进行调用。

handleSearchForTeam:searchTerm:SearchBar的另一个delegate,根据搜索词searchTerm来进行搜索

NSMutableArray *sectionsToRemove = [[NSMutableArray alloc] init]; //声明一个NSMutableArray,用于记录哪些section可以整个的被删除,即某个index item下的所有name都不符合搜索的要求,这个index item就可以被删除了
[self resetSearch]; //初始化搜索对象,一个是NSMutableDictionary,另一个是NSMutableArray
for (NSString *key in self.keys) { //循环遍历所有的key
    NSMutableArray *array = [names valueForKey:key]; //根据key取得对应的name
    NSMutableArray *toRemove = [[NSMutableArray alloc] init]; //初始化一个NSMutableArray,用于记录可删除的name
    for (NSString *name in array) { //循环遍历当前key下的name
        if ([name rangeOfString:searchTerm options:NSCaseInsensitiveSearch].location == NSNotFound) { //如果当前的name中不包含搜索词searchTerm,那这个name是可以被删除的
            [toRemove addObject:name]; //将name添加到toRemove array中
        }
    }
    if ([array count] == [toRemove count]) { //判断是不是可以删除的name个数和当前section(index item)下的name个数一样,一样的话,真个的section就可以被删除了
        [sectionsToRemove addObject:key]; //将可以删除的section添加到array中
    }
    [array removeObjectsInArray:toRemove]; //删除name
}
[self.keys removeObjectsInArray:sectionsToRemove]; //删除section
[table reloadData]; //重新载入数据

下面继续添加code

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSString *path = [[NSBundle mainBundle] pathForResource:@"sortednames" ofType:@"plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
self.names = dict;
self.allNames = dict; NSArray *array = [[names allKeys] sortedArrayUsingSelector:@selector(compare:)];
self.keys = array; [self resetSearch];
[table reloadData];
[table setContentOffset:CGPointMake(
0.0, 44.0) animated:NO];
} - (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
self.names = nil;
self.keys = nil;
self.table = nil;
self.search = nil;
self.allNames =
nil;
}

这里需要解释的就是[table setContentOffset:CGPointMake(0.0, 44.0) animated:NO];,将table view上移动44px,这样当初次载入程序的时候,搜索栏不会显示,只用向下拖动table view,searchbar才会出现。

继续添加code

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [self.keys count];
return ([keys count] > 0) ? [keys count] : 1;
} - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if([keys count] == 0)
return 0
; NSString *key = [keys objectAtIndex:section];
NSArray *nameSection = [names objectForKey:key];
return [nameSection count];
} ...... - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if([keys count] == 0)
return
nil; NSString *key = [keys objectAtIndex:section];
return key;
}

增加的几个if语句都是用于判断search结果的,调用完handleSearchForTeam:searchTerm后,看还有多少个key和name

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[search resignFirstResponder];
return indexPath;
}

table view的delegate方法,当点击table view上的一行是,将弹出的键盘隐藏

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
NSString *searchTeam = [searchBar text];
[self handleSearchForTeam:searchTeam];
} - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchTerm {
if ([searchTerm length] == 0) {
[self resetSearch];
[table reloadData];
return;
}
[self handleSearchForTeam:searchTerm];
} - (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
search.text = @"";
[self resetSearch];
[table reloadData];
[searchBar resignFirstResponder];
}

三个Search Bar的delegate方法
searchBarSearchButtonClicked:searchBar当点击虚拟键盘上的search按钮时,调用该方法
searchBar:textDidChange:当searchBar上的输入发生改变时,调用该方法
searchBarCancelButtonClicked:searchBar当点击searchbar上的Cancel按钮时,调用该方法

好了,所有的code添加完毕,编译运行,效果如下

当程序启动后,searchbar是看不见的,因为我们将table view上移了44px,将table view向下拖动后,searchbar出现了

点击search bar的输入栏,调出键盘,然后我们输入“ab”,table view总的内容会随之改变,只显示含有关键词“ab”的name,index也会改变

点击table view中的一行,键盘会隐藏

11)隐藏index
如果我们希望在搜索的时候隐藏index,添加下面的code

在BIDViewController.h中添加一个property

@interface BIDViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate>

@property (strong, nonatomic) NSMutableDictionary *names;
@property (strong, nonatomic) NSMutableArray *keys;
@property (strong, nonatomic) IBOutlet UITableView *table;
@property (strong, nonatomic) IBOutlet UISearchBar *search;
@property (strong, nonatomic) NSDictionary *allNames;
@property (assign, nonatomic) BOOL isSearching;

注意,这里用的是assign(不好意思,我还没有弄清楚为什么要用assign,因此无法解释,了解的同学们帮忙指导一下,谢谢)

在BIDViewController.m中添加code

#import "BIDViewController.h"
#import "NSDictionary+MutableDeepCopy.h" @implementation BIDViewController
@synthesize names;
@synthesize keys;
@synthesize table;
@synthesize search;
@synthesize allNames;
@synthesize isSearching; ...... - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
if(isSearching)
return nil;
return keys;
} - (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[search resignFirstResponder];
isSearching = NO;
search.text = @"";
[table reloadData];
return indexPath;
} ...... - (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
isSearching = NO;
search.text = @"";
[self resetSearch];
[table reloadData];
[searchBar resignFirstResponder];
} - (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
isSearching = YES;
[table reloadData];
}

添加了一个新的Search Bar的delegate:searchBarTextDidBeginEditing,当开始键入搜索词的时候,设置标识符isSearching为YES,然后重新载入table,当重新载入table的时候,就会判断isSearching是否为YES,如果是,就不显示index。其他的代码修改应该都可以看懂吧,就不解释了,编译运行程序,点击搜索栏,index消失了,效果如下

当结束搜索(点击search bar的Cancel按钮或者选中table view中的一行),index就会显示出来

12)添加index中的放大镜
现在的index定位,只能定位到某个section,如果想直接定位到search bar还是不行的,我们需要添加额外的代码,使其可以定位到search bar,基本思路如下:
添加一个特殊的值到keys中,然后点击这个特别的key,就可以定位到search bar
阻止iOS为这个特殊的key生成一个section hearder,其他的keys(A、B、C.....Z)每个都一个section header
当这个特殊的key被选中时,定位到search bar

- (void)resetSearch {
self.names = [self.allNames mutableDeepCopy];
NSMutableArray *keyArray = [[NSMutableArray alloc] init];
[keyArray addObject:UITableViewIndexSearch];
[keyArray addObjectsFromArray:[[self.allNames allKeys] sortedArrayUsingSelector:@selector(compare:)]];
self.keys = keyArray;
} ...... - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if([keys count] == 0)
return nil; NSString *key = [keys objectAtIndex:section];
if (key == UITableViewIndexSearch) {
return nil;
}
return key;
} ...... - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
NSString *key = [keys objectAtIndex:index];
if(key == UITableViewIndexSearch) {
[tableView setContentOffset:CGPointZero animated:NO];
return NSNotFound;
}
else
return index;
}

resetSearch方法中为key添加了一个iOS自带的对象[keyArray addObject:UITableViewIndexSearch],这个就是放大镜。
titleForHeaderInSection中,判断key是不是UITableViewIndexSearch,如果是,就返回nil,不显示section header
最后添加了一个新的delegate,用于定位到search bar

编译运行,放大镜出现了
点击放大镜,就可以定位到search bar了

13)总结
终于要完结这篇了,花了好长时间,内容比较多,比较复杂,不过很实用,很多app程序都用到这些基础的东西,其实也不难,很多方法都是iOS自带的,我们只需要自己调用一下即可,总的来说,收获还是很大的,加油吧!

Sections

从零开始学ios开发(十三):Table Views(下)Grouped and Indexed Sections的更多相关文章

  1. 从零开始学 iOS 开发的15条建议

    事情困难是事实,再困难的事还是要每天努力去做是更大的事实. 因为我是一路自学过来的,并且公认没什么天赋的前提下,进步得不算太慢,所以有很多打算从零开始的朋友会问我,该怎么学iOS开发.跟粉丝群的朋友交 ...

  2. 从零开始学ios开发(十六):Navigation Controllers and Table Views(下)

    终于进行到下了,这是关于Navigation Controllers和Table Views的最后一个例子,稍微复杂了一点,但也仅仅是复杂而已,难度不大,我们开始吧. 如果没有上一篇的代码,可以从这里 ...

  3. 从零开始学ios开发(十二):Table Views(上)

    这次学习的控件非常重要且非常强大,是ios应用中使用率非常高的一个控件,可以说几乎每个app都会使用到它,它就是功能异常强大的Table Views.可以打开你的iphone中的phone.Messa ...

  4. 从零开始学IOS开发

    从今天开始开一个坑,由于业务变动,要开始学习IOS开发进行IOS app开发,其实鄙人本身就是一只菜鸟加大学狗,有过两年的C#,ASP.NET MVC,微信公众平台开发经验,一只在继续努力着,从大三下 ...

  5. 从零开始学ios开发(三):第一个有交互的app

    感谢大家的关注,也给我一份动力,让我继续前进.有了自己的家庭有了孩子,过着上有老下有小的生活,能够挤出点时间学习真的很难,每天弄好孩子睡觉已经是晚上10点左右了,然后再弄自己的事情,一转眼很快就到12 ...

  6. 从零开始学ios开发(一):准备起航

    首先介绍一下自己的背景,本人09年研究生毕业,大学就不介绍了,反正是上海的一所211大学,学的是计算机科学与技术专业,学生时代,从事过ACM,没有什么太大的成就,中国的牛人是在太多,我的水平,估计连高 ...

  7. 从零开始学ios开发(十五):Navigation Controllers and Table Views(中)

    这篇内容我们继续上一篇的例子接着做下去,为其再添加3个table view的例子,有了之前的基础,学习下面的例子会变得很简单,很多东西都是举一反三,稍稍有些不同的内容,好了,闲话少说,开始这次的学习. ...

  8. 从零开始学ios开发(十四):Navigation Controllers and Table Views(上)

    这一篇我们将学习一个新的控件Navigation Controller,很多时候Navigation Controller是和Table View紧密结合在一起的,因此在学习Navigation Co ...

  9. 从零开始学ios开发(十二):Table Views(中)UITableViewCell定制

    我们继续学习Table View的内容,这次主要是针对UITableViewCell,在前一篇的例子中我们已经使用过UITableViewCell,一个默认的UITableViewCell包含imag ...

随机推荐

  1. oracle PL/SQL(procedure language/SQL)程序设计之游标cursors

    游标 Cursors--Conception 每一条被Oracle服务器执行的SQL语句都有一个独立的游标与之相关联:隐式游标 Implicit cursors: 用于所有的DML和PL/SQL的SE ...

  2. hdu 3909 数独扩展

    思路:做法与9*9的一样.只不过是变量. #include<set> #include<map> #include<cmath> #include<queue ...

  3. 2014年互联网IT待遇【转载】

    2014年互联网IT待遇[转载] 一.民企 1.百度 13k*14.6,special 14~17k*14.6 开发类 13K*14.6    (2014) 测试类.前端类 12K*14.6    ( ...

  4. popToViewController的用法(跳转到你想跳转到的那个控制器)

    [self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIn ...

  5. Linux 进程管理子系统

    一.进程管理子系统 1.进程要素 (1). 程序与进程 程序:存放在磁盘上的一系列代码和数据的可执行映像,是一个静止的实体 进程:是一个执行中的程序,他是一个动态的实体. (2). 进程4要素 1.有 ...

  6. 实现类似微信的延迟加载的Fragment——LazyFragment

    参考微信,使用ViewPager来显示不同的tab,每个tab是一个Fragment, 假设有3个tab,对应的fragment是FragmentA.FragmentB.FragmentC 需要实现的 ...

  7. Part 82 to 85 Talking about Generic queue, stack collection class

    Part 82   Generic queue collection class Part 83   Generic stack collection class Part 84   Real tim ...

  8. MVC基础知识-持续更新....

    1.如何在自动生成的视图中显示需要的字段名称: 在相应的定义字段中添加Display,例如: [Display(Name = "用户名:")] public string User ...

  9. 在sql设计中没法修改表结构

    在做练习的时候经常表没设计好,后来有要去数据库修改表结构但是没词用界面修改的时候都会提示要保存 转自http://www.57xue.com/ItemView/Sql/2016061600160.ht ...

  10. JavaScript之canvas

    num.push(x,y); 动画草图(举个栗子,我们把数字“2”给画出来): <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transit ...