IOS TableView实现简单豆瓣Demo

本文章只是在个人学习IOS开发中所写的Demo,仅供IOS开发新手入门参考。仅需实现一款豆瓣读书App的简单功能,包括搜索书籍,查看书籍列表以及书籍详情页。

1.开发环境:

mac OS 10.13.4、Xcode9.3.1、Objective-C

2.使用cocoapods管理第三方工具和类库

怎么安装就不说了,直接贴链接 http://www.code4app.com/article/cocoapods-install-usage

要使用到的第三方类库,AFNetworking和SDWebImage

在Podfile文件中编辑添加pod 'AFNetworking','~>3.1.0' pod 'SDWebImage','~>4.3.0'

# Uncomment the next line to define a global platform for your project

platform :ios, '9.0'


target 'DoubanDemo' do

  # Uncomment the next line if you're using Swift or would like to use dynamic frameworks

  # use_frameworks!

  pod'AFNetworking','~>3.1.0'

  pod'SDWebImage','~> 4.3.0'

  # Pods for DoubanDemo


  target 'DoubanDemoTests' do

    inherit! :search_paths

    pod 'Cedar', git: 'https://github.com/pivotal/cedar.git'

    # Pods for testing

  end


  target 'DoubanDemoUITests' do

    inherit! :search_paths

    # Pods for testing

  end


end


在xcode项目目录下运行命令pod install --no-repo-update自动下载依赖

3.代码思路:使用AFNetworking请求http://api.douban.com/v2/book/search接口,传入参数q和count表示关键字和结果条数,本地接收后拥NSMutableArray来存储书籍信息实体。再使用TableViewController渲染出列表,并为cell添加点击事件,跳转到书籍详情页,同时把书籍信息传递到页面。TableViewCell中需要网络异步加载图片,使用SDWebImage来实现这一部分。

4.在右边的Main.storyboard中拖入NavigationController,将NavigationController自带的Root View Controller删除,将自己的ViewController设置为Root View Controller,并将navigation controller设置为为入口,在ViewController中添加SearchBar,TableView等控件,设置书籍详情页面的布局。storyboard布局如下



书籍实体类,http请求返回的是json数据,再BookInfo中手动写了构造方法去解析json。BookInfo.m

//

//  BookInfo.m

//  DoubanDemo

//

//  Created by dave.luo on 2018/5/23.

//  Copyright © 2018年 dave.luo. All rights reserved.

//


#import <Foundation/Foundation.h>

#import "BookInfo.h"


@implementation BookInfo

@synthesize bid;

@synthesize subtitle;

@synthesize author;

@synthesize pubdate;

@synthesize image;

@synthesize translator;

@synthesize catalog;

@synthesize pages;

@synthesize publisher;

@synthesize title;

@synthesize url;

@synthesize author_intro;

@synthesize summary;

@synthesize price;

-(id)initWithJson:(id)data{

    bid=data[@"id"];

    subtitle=data[@"subtitle"];

    author=data[@"author"];

    pubdate=data[@"pubdate"];

    image=data[@"image"];

    translator=data[@"translator"];

    catalog=data[@"catalog"];

    pages=data[@"pages"];

    publisher=data[@"publisher"];

    title=data[@"title"];

    url=data[@"url"];

    author_intro=data[@"author_intro"];

    summary=data[@"summary"];

    price=data[@"price"];

    return self;

}

@end


Book的Service类,再这里的代码中每次请求都只返回10条记录,读者可以自己修改重构。BookService.m

//  BookService.m

//  DoubanDemo

//

//  Created by dave.luo on 2018/5/23.

//  Copyright © 2018年 dave.luo. All rights reserved.

//


#import <Foundation/Foundation.h>

#import <AFNetworking/AFNetworking.h>

#import "BookService.h"

#import "BookInfo.h"


@implementation BookService

@synthesize books;

@synthesize block;


//请求书籍搜索服务

-(void)getRequestWithURL:(NSString *)urlStr withKey:(NSString *)keyWord withTableView:(UITableView *)tableView withData:(NSMutableArray *)datas{

    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

    NSLog(@"%@",keyWord);

    [datas removeAllObjects];

    NSDictionary *dict=@{

                         @"q":keyWord,

                         @"count":@10

                         };

    manager.responseSerializer = [AFJSONResponseSerializer serializer];

    [manager GET:urlStr parameters:dict progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject){

        //NSMutableArray *books=[NSMutableArray new];

        NSArray *json= responseObject[@"books"];

        

        for(id book in json){

            BookInfo *b = [[BookInfo alloc]initWithJson:book];

            NSLog(@"%@",b.author[0]);

            [datas addObject:b];

        }

        [tableView reloadData];

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error){

        NSLog(@"返回失败");

        NSLog(@"%@",error);

    }];

}



@end


BookTableViewCell类继承了UITableViewCell类,在这里你可以调整cell的布局,通过layoutSubviews方法来固定cell中ImageView的图片大小,防止图片出现异常

//

//  BookTableViewCell.m

//  DoubanDemo

//

//  Created by dave.luo on 2018/5/24.

//  Copyright © 2018年 dave.luo. All rights reserved.

//


#import <UIKit/UIKit.h>

#import "BookTableViewCell.h"


@implementation BookTableViewCell

@synthesize lbPrice;

@synthesize bookTitle;

@synthesize subtitle;

@synthesize author;

-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{

    if (self=[super initWithStyle:style reuseIdentifier:reuseIdentifier])

    {

        CGFloat height = self.frame.size.height;

        CGFloat width = self.frame.size.width;

        lbPrice = [[UILabel alloc]initWithFrame:CGRectMake(width-20, height+70, 100,20)];

        bookTitle = [[UILabel alloc]initWithFrame:CGRectMake(170, 5, 200,50)];

        subtitle = [[UILabel alloc]initWithFrame:CGRectMake(170, 45, 200,50)];

        author = [[UILabel alloc]initWithFrame:CGRectMake(width-130, height+70, 100,20)];

        [lbPrice setTextColor:[UIColor redColor]];

        

        bookTitle.numberOfLines=0;

        bookTitle.font = [UIFont systemFontOfSize:19];

        subtitle.font = [UIFont systemFontOfSize:16];

        subtitle.numberOfLines=0;

        

        

        

        [self addSubview:bookTitle];

        [self addSubview:lbPrice];

        [self addSubview:subtitle];

        [self addSubview:author];

    }

    return self;

}


-(void)layoutSubviews{

    [super layoutSubviews];

    self.imageView.bounds =CGRectMake(5,5,44,44);

    self.imageView.frame =CGRectMake(15,10,115,155);

}

@end


ViewController里面绑定了storyboard中的TableView,实现UITableViewDatasource和UITableViewDelegate两个协议要实现的三个方法numberOfSectionsInTableView,numberOfRowsInSection,cellForRowAtIndexPath。再通过UISearchBarDelegate实现searchBar的搜索按钮点击事件,在点击事件当中,再调用一次请求方法即可。页面跳转的实现只需要实现didSelectRowAtIndexPath方法,通过获取storyboard中的目标Controller,这里我们要给storyboard中书籍详情页的Identifier确定一个id即可。

//

//  ViewController.m

//  DoubanDemo

//

//  Created by dave.luo on 2018/5/23.

//  Copyright © 2018年 dave.luo. All rights reserved.

//

#import <AFNetworking/AFNetworking.h>

#import <SDWebImage/UIImageView+WebCache.h>

#import "BookTableViewCell.h"

#import "BookService.h"

#import "BookDetailController.h"

#import "ViewController.h"

#import "BookInfo.h"



@interface ViewController ()<UITableViewDelegate,UITableViewDataSource,UISearchBarDelegate>


@end


@implementation ViewController

@synthesize books;

- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view, typically from a nib.

    _searchBook.barTintColor=[UIColor colorWithRed:67/255.0 green:189/255.0 blue:86/255.0 alpha:1];

    [self.navigationController setNavigationBarHidden:YES animated:YES];

    url = @"https://api.douban.com/v2/book/search";

    books = [[NSMutableArray alloc]init];

    _searchBook.delegate=self;

    _bookList.delegate=self;

    _bookList.dataSource=self;

    bookService = [[BookService alloc]init];

    [bookService getRequestWithURL:url withKey:@"python" withTableView:_bookList withData:books];

}


- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{

    NSString *key = searchBar.text;

    if(![key isEqualToString:@""])

        [bookService getRequestWithURL:url withKey:key withTableView:_bookList withData:books];

}


- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}



-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{

    return 1;

}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

    return [self.books count];

}


-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{

    return 160;

}


-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

    BookTableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:@"cellID"];

    if(cell==nil){

        cell = [[BookTableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cellID"];

    }

    

    BookInfo *book = [books objectAtIndex:indexPath.row];

    //cell.textLabel.text= book.title;

    cell.subtitle.text = book.summary;

    cell.lbPrice.text = book.price;

    cell.bookTitle.text=book.title;

    cell.author.text =book.author[0];

    NSString *imgUrl = book.image;

    

    [cell.imageView sd_setImageWithURL:[NSURL URLWithString:imgUrl] placeholderImage:[UIImage imageNamed:@"placeholder" ]];

    //[cell.imageView setFrame:CGRectMake(0, 0, 40, 100)];

//    [cell.imageView sd_setImageWithURL:[NSURL URLWithString:imgUrl] completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {

//

//    }];

    

    return cell;

}


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    BookDetailController *detail = [self.storyboard instantiateViewControllerWithIdentifier:@"detailView"];

    detail.book=[books objectAtIndex:indexPath.row];

    [self.navigationController pushViewController:detail animated:YES];

}


@end


BookDetailController里面则负责接受和显示详情页的代码,这里就不贴代码了

项目代码已发到github上,https://github.com/ljp88571133/DoubanDemo 欢迎下载

猜你喜欢

转载自blog.csdn.net/BonsoirDave/article/details/80494788