UI星辰:疯狂食材总结

来源:互联网 发布:日本电影推荐知乎 编辑:程序博客网 时间:2024/04/30 15:39

很多新手在学习ios到最后都会拿一些小项目练一练手,在这里我也为大家介绍一下疯狂食材吧!虽然它不是我的第一个项目,也不是第一个上架的项目,但是对于一个新手来说还是有着一定的意义。

疯狂食材也是我的一个练手项目。疯狂食材是一个小项目,主要是数据的请求,界面的排版,数据的处理。

在 iOS开发的过程中,界面的美观也是很重要的,就工具类的项目而言,界面的美观很大程度上会影响着这个程序的推广。一个工具类的小项目而言,app store上的软件已经已经几乎应有尽有了,在功能无法体现的出差距的情况下,界面的美观也就很重要了。当然,对于任何一个苹果手机的app而言,iOS开发人员对于界面的美观要求就好像苹果公司对于苹果手机的极致追求一样,有人曾对我说,一个app功能可以不怎么样,但是界面却不能落后。但是界面排版本不是很困难,在此就扦插到下面。

我们可以查考app store上已有的疯狂食材app,在此,我们要有一个清楚的认识,所有的网络请求都必须使用多线程,必须是异步请求数据的过程。在此我使用[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {}];方法请求数据,无论数据多小,因为我们无法保证网络是正常的,如果同步请求数据一旦网络不正常,就会卡机,这是十分令人恶劣的。在网络请求之前,我们先检查网络的状态。可以使用第三方类库AFNetWorking。但是第三方类库AFNetWorking和后面分享到微信使用的微信api的发生命名冲突,查看网上一些资料,可以帮我们解决这个问题,我没有使用此第三方,因此就不多说了。

对于请求回来的数据,我们可以建立一个model来存放。当然你也可以不存放到model中而直接食用,不过相比之下,建立一个model对于后期数据的处理起来更加的方便,如果个人的话可以不建model,但是团队开发缺很有必要行。因此建议无论什么情况下尽量使用model。

查考app store上已有的疯狂食材app,我们知道有一个UITabBarController,此tabBar是自定义的。控制着五个UINavigationBarController。其中有四个UINavigationBarController中的UIViewController的界面是一样的。在此,我们可以考虑使用UIScrollerView或UITableView构建界面。在构建界面时,使用约束是较好的,但是考虑到约束过较为麻烦,使用frame也可以,但是一定要使用比例值,而不能使用固定值,否则适配会出现问题。在此我使用UITableView,在UITableView的cell中顺序添加三层View; UIButton 第一层,用于显示图片,UILabel 第二层,用于显示阴影,透明度0.5。UILabel最上层,用于显示名称。为了方便数据的处理,我们可以将button.titleLabel.text设置为食材类别的id,同时清空颜色。这样button.titleLabel.text是存在的但是却是不显示的。

在疯狂食材中,图片的处理也是有所要求,对于图片我们可以下载第三方类库SDWebImage,在此,我也没有使用此第三方,而是通过自己写的一个方法,若文件存在,先在文件中读取图片,否则将请求回来的图片数据写入到一个文件中,再读取出来。在没有读出数据之前,先让button显示一张固定的图片。同时考虑到第一次进入app之后再次进入app就不再需要等待数据请求,第一次请求数据之后把数据写入本地文件,每次进去app先从本地文件读取数据,之后网络请求跟新本地数据。由于几乎所有的界面都需要加载图片,我就为UIViewController添加一个类目,如下方法:

//检查文件是否存在

    if (![[NSFileManager defaultManager] fileExistsAtPath:stringPath]) {

//如果文件不存在就创建一个新的文件

       [[NSFileManager defaultManager] createDirectoryAtPath:stringPath withIntermediateDirectories:YES attributes:nil error:nil];
    }

//如果文件不存在就加载图片。

    if (![[NSFileManager defaultManager] fileExistsAtPath:stringPath]) {

//加载之前先显示一张图片

         [button setBackgroundImage:[UIImage imageNamed:@"AppIcon57x57@2x"] forState:0];
      
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
            
            if (connectionError == nil) {
               //加载完成之后,改变图片
                [data writeToFile:stringPath options:NSAtomicWrite error:nil];
                [button setBackgroundImage:[UIImage imageWithContentsOfFile:stringPath] forState:0];
           
            }
        }];
    }else {

//如果文件存在,直接设置图片

        [button setBackgroundImage:[UIImage imageWithContentsOfFile:stringPath] forState:0];
    }
}


在设置cell的过程中,我们使用自定义的cell,根据需要在-(id) initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier;方法中定义自己的cell。我们也可以直接在- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath中为cell添加view,但是由于cell是重用的,每一执行此方法的时候都要移除cell原有的子类,同时要设置mytableView.separatorStyle = UITableViewCellSeparatorStyleNone; 如果不加词句,当第一次为cell添加view,separatorStyle 是一条线,重用之后,separatorStyle的view就被移除,使得界面不美观。同时通过- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;方法可以设置tableView的header。

对于标签控制器中的四个导航控制器中的视图控制器,还是较为容易的,之后的几个界面较为困难一些,而是展示但一种石材显示信息的界面是较为困难的。我们需要使用boundingRectWithSize:方法求出string文本的宽和高。对数据的考虑情况也比较多。值得注意的是网络请求回来的数据,取出来之后,有可能是空值,例如在取出有利搭配的数组时,要判断 (NSNull *)arrayGood != [NSNull null];

在整个项目的过程中,倒也没什么大问题,在项目的开发过程中细心是很重要的,一个小小的不经意间的差错,往往使得我们浪费不少时间。为了提高代码的质量,需要将代码进行封装,每一个方法的代码行数不宜过多,不要将所有的代码都写在同一个或几个方法之中,一个完整的处理过程可以单一写成一个方法,这样便于阅读和检查错误。












0 0
原创粉丝点击