界面布局简介
1.类别页面
2.功效页面
3.人群页面
4.营养页面
5.类别下食材页面
6.功效及人群下食材页面
7.营养下食材页面
8.食材详细介绍页面
9.搜索页面
功能实现
1.主页功能
主页主要有5个页面,分别为:类别,功效,人群,营养,更多。使用拖ib的方式,创建一个TabBarController,以及五个页面对应的ViewController,并都添加NavigationController。
在TabBarController上隐藏TabBar,并创建一个View和自定义的button来代替系统原来自带的TabBar,并给button添加方法就可以实现页面切换的功能。
2.按钮布局
类别,功效,人群,营养四个页面都是由2列n行的button来组成。用嵌套循环先进行布局,然后再循环内设置参数,可以修改参数来改变行数。因为按钮是需要先进行网络请求数据才能进行布局,所以要将布局写了一个方法。这个方法4个页面都可以共用,所以可以将这个方法进行封装。
-(void)CategoryLayout{
int row = 0;
int count;
if (dataSource.count%2==0) {
count = (int)dataSource.count/2;
}else{
count = (int)dataSource.count/2+1;
}
scrollView.contentSize = CGSizeMake(Screen_Width,(Screen_Width/2)*count);
for (int j = 0; j<count; j++){
for (int i = 0; i < 2; i++){
if (row == dataSource.count) {
break;
}
NSDictionary *dict = dataSource[row];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake((Screen_Width/2)*i, (Screen_Width/2)*j, Screen_Width/2, Screen_Width/2);
UIImageView * image = [[UIImageView alloc]initWithFrame:button.frame];
[image sd_setImageWithURL:dict[@"pic"] placeholderImage:[UIImage imageNamed:@"moon"]];
[button addTarget:self action:@selector(pushToCategoryTableView:) forControlEvents:UIControlEventTouchUpInside];
[scrollView addSubview:button];
[scrollView addSubview:image];
button.tag = [dict[@"id"] integerValue];
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake((Screen_Width/2)*i, 155+(Screen_Width/2)*j, Screen_Width/2, Screen_Width/2-155)];
label.text = dict[@"name"];
label.tag = 100+[dict[@"id"] integerValue];
label.textColor = [UIColor whiteColor];
label.backgroundColor = [UIColor colorWithRed: (0/255.0 ) green: (0/255.0) blue: (0/255.0) alpha:0.3];
[scrollView addSubview:label];
row++;
}
}
}
3.类别下食材页面
这个页面非常简单,直接创建Cell用ib来进行布局,在Cell的布局中需要对ib进行约束。然后根据网络请求的数据存到ViewController的dataSource里面进行布局即可。
每个页面我都设置了一个titleLabel来代替系统原来的title,并且将返回按钮自定义成自己想要得样式。titleLabel的text是根据上一个页面点击的按钮传值的参数来进行命名,之后每个页面的title都是这样设计。
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake( Screen_Width/2-50, 8, 100, 30)];
titleLabel.text = self.nameTitle;
[titleLabel setFont:[UIFont fontWithName:@"Helvetica-Bold" size:20]];
titleLabel.textAlignment = NSTextAlignmentCenter;
titleLabel.textColor = [UIColor whiteColor];
[self.navigationController.navigationBar addSubview:titleLabel];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:[UIImage imageNamed:@"back"] forState:0];
[button setFrame:CGRectMake(0, 0, 15,20)];
[button addTarget:self action:@selector(backAction:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *back = [[UIBarButtonItem alloc]initWithCustomView:button];
self.navigationItem.leftBarButtonItem = back;
4.功效及人群下食材页面
功效跟人群下得2个页面是相似的,所以可以共用。这个页面可以用2个方法来实现,第1个方法是使用tableViewController,改写Cell的布局方法可以实现。第2个方法是使用ScrollView进行布局。我自己使用的是第2种方法。
将文字介绍跟下面的button部分看做一个整体,为一个View。然后根据文字的高度还有button的数量来定义这个View的高度。看有多少个这样的View,用循环来布局,最后ScrollView的总高度为所有View的总高度。
同理营养下食材页面和食材详细介绍页面的布局也可以用到这个方法,只要理清楚每个部分的内容即可。最后食材详细介绍页面的内容比较多,所以要仔细的理清思路和数据。
for (int i = 0; i < itemsArray.count; k++) {
items = itemsArray[i];
memos = memosArray[i];
//根据文字多少来计算需要多少高度。
CGSize titleSize = [memos boundingRectWithSize:CGSizeMake(Screen_Width-55, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:17]} context:nil].size;
if (titleSize.height < 40) {
titleSize.height = 40;
}
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(0, needHeight, Screen_Width,titleSize.height+16)];
needHeight = needHeight+titleSize.height-10;
view.backgroundColor = [UIColor colorWithRed:250/255.0 green:230/255.0 blue:200/255.0 alpha:1.0];
[scrollView addSubview:view];
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(50,0,Screen_Width-55, titleSize.height+16)];
label.textAlignment = 0;
label.numberOfLines = 0;
label.text = memo;
[view addSubview:label];
UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(5, 15, 40, 30)];
imageView.image = [UIImage imageNamed:@"good1"];
[view addSubview:imageView];
CGFloat space = (Screen_Width-4*60)/5;
NSInteger count = item.count/4;
if (item.count%4 != 0) {
count++;
}
int how = 0;
for (int j = 0; j < count; j++) {
for (int i = 0; i < 4; i ++) {
if (how == item.count) {
break;
}
NSDictionary *dic = item[how];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(space+(space+60)*i, needHeight+35+70*j, 60, 60)];
[imageView sd_setImageWithURL:dic[@"pic"]];
[scrollView addSubview:imageView];
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
button.frame = CGRectMake(space+(space+60)*i,needHeight+35+70*j, 60, 60);
button.tag = [dic[@"id"] integerValue];
[button addTarget:self action:@selector(NextButton:) forControlEvents:UIControlEventTouchUpInside];
[scrollView addSubview:button];
how++;
}
}
needHeight = needHeight + 40 + 70*count;
scrollView.contentSize = CGSizeMake(0, needHeight);
5.搜索页面
搜索页面的3d球状效果,是从code4app上下载的demo,直接将方法添加进工程即可,然后修改里面需要的参数和给button添加方法。而上面的搜索栏是用TextField来实现。
(这里textF设置了全局变量)
textF = [[UITextField alloc] initWithFrame:CGRectMake(2, 2, 300, 26)];
textF.backgroundColor = [UIColor whiteColor];
textF.layer.masksToBounds = YES;
textF.layer.cornerRadius = 5.0;
textF.leftViewMode = UITextFieldViewModeAlways;
textF.leftView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Search1"]];
textF.placeholder = @"请输入搜索关键字";
textF.autocorrectionType = UITextAutocorrectionTypeNo;
textF.returnKeyType = UIReturnKeyDone;
//一键清除
textF.clearButtonMode = UITextFieldViewModeWhileEditing;
textF.leftView.frame = CGRectMake(5, 0, 20, 20);
[searchView addSubview:textF];
6.AFNetworking在项目中的应用
在项目中布局还有button的图片都需要网络请求,所以封装了一个类专门作为网络请求的类。然后建一个枚举类型,分别代表网络请求成功,失败和没网络的情况。当网络请求失败或没网络的情况,会显示,当网络请求成功,就会执行上面的布局代码,将请求到得json数据进行解析拿到需要的数据进行布局。
+(void)netWorkWithPath:(NSString *)path Params:(NSDictionary *)params CallBack:(CallBack)callback{
path = [DomainString stringByAppendingString:path];
//编码
path = [path stringByAddingPercentEscapesUsingEncoding:4];//4
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];//设置相应类型
//parameters不为空时是URL里有name = ???之类的串
[manager GET:path parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
callback(responseObject,SuccessType);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:error.debugDescription,@"info", nil];
callback(info,FailedType);
}];
}
7.SDWebImage在项目中的应用
项目中对于SDWebImage应用只有按钮图片的下载,在网络请求下来的json数据中,有对应按钮的图片网址,将网址解析到然后用方法。
[image sd_setImageWithURL:dict[@"pic"] placeholderImage:[UIImage imageNamed:@"moon"]];
项目自我总结
在项目中遇到的技术问题:1.json数据的处理 2.ScrollView页面的布局处理 3.重复代码很多,没有封装
解决方法:
1.json数据的处理后来使用了百度上在线解析工具,分清楚字典跟数数组的关系层次,逐层解析就能拿到自己需要的数据了。
2.因为ScrollView页面的布局很多,需要注意每个控件之间的关系。
3.将重复使用的代码用工具类封装起来,如:布局使用的方法,网络请求方法。
这次的项目主要运用的技术是tableview,tabBar,ScrollView等基本控件的应用。而且项目中很多的方法可以重复的运用,所以可以把这些方法进行封装,封装成工具类,这样可以大大的提高开发的速度。在项目中还运用到了多个第三方插件,SDWebImage,AFNetworking,shareSDK等。
而且项目中很多的细节需要注意,为了增强用户的体验感,需要对界面进行很多的细节处理。从这个项目中对自己的基础知识可以进行强化,并且可以开拓自己对项目完成的流程整理一个完整的思路。