Oc 新闻接口请求数据UI布局

添加PCH文件Starry.pch
在程序Build Settings 的Prefix Header 写上$(SRCROOT)/工程名称/Starry.pch

Starry.pch

#ifndef Starry_pch
#define Starry_pch

/*
    常用头文件的导入
*/
#import "BaseViewController.h"
#import "AppDelegate.h"
#import "MBProgressHUD.h"
#import "UIView+NewMethods.h"
#import "NSString+NewMethods.h"
#import "UserDataBase.h"
#import "NewsDataBase.h"
#import "UIImage+Tailor.h"
#import "QRCodeGenerator.h"
#import "URLService.h"
#define App_Delegate (AppDelegate *)[UIApplication sharedApplication].delegate

/*
   系统版本号
*/
#define VERSION_10_0   [UIDevice currentDevice].systemVersion.doubleValue >= 10.0
#define VERSION_9_0    [UIDevice currentDevice].systemVersion.doubleValue >= 9.0
/*
   用于适配的宏
*/
#define SCR_W [UIScreen mainScreen].bounds.size.width 
#define SCR_H [UIScreen mainScreen].bounds.size.height
//适配x轴的宏
#define FIT_X(w) (SCR_W / 375. *(w))
//适配Y轴的宏
#define FIT_Y(h) (SCR_H / 667. *(h))
/*
  当前app版本号的宏
*/
#define VERSION_CURRENT [[NSBundle mainBundle].infoDictionary objectForKey:@"CFBundleShortVersionString"]
//持久化当前版本号的key的宏
#define NOT_FIRST_LANUCH @"NotFirstLanuch"


/*
     Doucuments目录的宏
*/
#define DOCUMENT_PATH [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] 
/*
   注册通知
*/
//退出登录
#define LOGOUT_NOTIFICATION_NAME @"logoutNotification"
#endif /* Starry_pch */


BaseViewController.h

#import 
typedef enum{
    BaseViewControllerTag_Main = 444,//头条,天气,直播
    BaseViewControllerTag_Left//个人信息,我的收藏,关于我们
} BaseViewControllerTag;
@interface BaseViewController : UIViewController
//实例化对象并设置是那种类型(分为主模块和侧滑模块)
-(instancetype)initWithTag:(BaseViewControllerTag)tag;
#pragma mark -子类调用方法
//在导航条右侧添加一个分享按钮
- (void)addShareButtonToNavigationRightBarItem;
//隐藏弹出的分享视图
- (void)hidePopView;

//收藏按钮
@property (nonatomic,strong)UIButton *saveBtn;
//分享按钮保存数组
@property (nonatomic,strong)NSMutableArray *shareBtnArr;


@end

BaseViewController.m

#import "BaseViewController.h"
#import "UserDataBase.h"
@interface BaseViewController ()
{
    UIButton *headImgBtn;
    BaseViewControllerTag _ctlTag;//用于区分控制器的标签
    UIView *backView;//弹出分享窗口的背景图
}
@property (nonatomic,strong)UIWindow *shareView;
@end

@implementation BaseViewController
-(instancetype)initWithTag:(BaseViewControllerTag)tag
{
    self = [super init];
    if (self) {
        _ctlTag = tag;
    }
    return self;
}


- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor grayColor];
    /*
     导航条设置
    */
    //背景图
    [self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"navigationItem_background"] forBarMetrics:UIBarMetricsDefault];
    //设置导航条文字颜色和字体大小
    [self.navigationController.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor],NSFontAttributeName:[UIFont systemFontOfSize:18.0]}];
    /*
       返回按钮设置
    */
    if (self.navigationController.viewControllers.count == 1) {
        if (_ctlTag == BaseViewControllerTag_Main) {
            headImgBtn = [UIButton buttonWithType:UIButtonTypeCustom];
            headImgBtn.frame = CGRectMake(0, 0, 44, 44);
            headImgBtn.clipsToBounds = YES;
            headImgBtn.layer.cornerRadius = 44/2;
            
             headImgBtn.imageView.contentMode = UIViewContentModeScaleAspectFill;
            [headImgBtn addTarget:self action:@selector(headBtnHandle:) forControlEvents:UIControlEventTouchUpInside];
            
            UIView *view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 44, 44)];
            [view addSubview:headImgBtn];
            
            self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:view];
            
        }else{//还是导航的根(个人信息,我的收藏,关于我们)
            UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
            backBtn.frame = CGRectMake(0, 0, 20, 30);
            [backBtn setImage:[UIImage imageNamed:@"navigationItem_back"] forState:UIControlStateNormal];
            [backBtn addTarget:self action:@selector(backBtnHandle:) forControlEvents:UIControlEventTouchUpInside];
            self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:backBtn];
        }
        
        
    }
    //导航次级控制器
    else{
        self.navigationItem.hidesBackButton = YES;
        UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        backBtn.frame = CGRectMake(0, 0, 20, 30);
        [backBtn setImage:[UIImage imageNamed:@"navigationItem_back"] forState:UIControlStateNormal];
        [backBtn addTarget:self action:@selector(backBtnHandle:) forControlEvents:UIControlEventTouchUpInside];
        self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:backBtn];
    }
    
    //注册一个监听,监听退出登录
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(updateAllViewContents) name:LOGOUT_NOTIFICATION_NAME object:nil];
    
}
//头像按钮触发事件
- (void)headBtnHandle:(id)sender{
    AppDelegate *app = App_Delegate;
    [app.sideMenu presentLeftMenuViewController];
}
//返回方法
- (void)backBtnHandle:(id)sender{
    //点击了导航根视图控制器上的导航左侧按钮
    if (self.navigationController.viewControllers.count == 1) {
        [self.navigationController dismissViewControllerAnimated:YES completion:nil];
    }
    //点击了导航控制器中的次级视图控制器上的左侧按钮
    else{
      [self.navigationController popViewControllerAnimated:YES];
    }
    
}
#pragma mark -私有方法
//更新UI
-(void)updateAllViewContents{
    //判断导航栈中有几个控制器
    if (self.navigationController.viewControllers.count == 1) {
        //表示该视图是导航的根视图控制器
        self.tabBarController.tabBar.hidden = NO;
        
        //判断有无用户登录.来设置头像按钮的图片
        if(![[UserDataBase sharedDataBase]userHadLogin]){
            //如果没有登录用户,显示默认头像图片
            [headImgBtn setImage:[UIImage imageNamed:@"40"] forState:UIControlStateNormal];
        }else{
            //有持久化的登录人数据
            User *u= [[UserDataBase sharedDataBase]getCurrentLoginUser];
            //用户没有设置头像
            if(u.headImg == nil){
                //没有设置头像,显示默认图片头像
                [headImgBtn setImage:[UIImage imageNamed:@"40"] forState:UIControlStateNormal];
            }else{
                //设置头像,显示头像
                UIImage *img = [[UIImage alloc]initWithContentsOfFile:[DOCUMENT_PATH stringByAppendingPathComponent:u.headImg]];
                
                
                [headImgBtn setImage:img forState:UIControlStateNormal];
               
                
            }
        }
    }
    else{
        //表示该视图是导航的2级或3级视图控制器
        self.tabBarController.tabBar.hidden = YES;
    }
}
//在导航条右侧添加一个分享按钮
- (void)addShareButtonToNavigationRightBarItem{
    UIBarButtonItem *shareItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(popShareView)];
    self.navigationItem.rightBarButtonItem = shareItem;
    
    
}
//按钮触发弹出一个分享视图
- (void)popShareView{
    //如果view在屏幕的下面,就让他弹出
    if (self.shareView.frame.origin.y == SCR_H) {
        
        [UIView animateWithDuration:0.15 animations:^{
            self.shareView.frame = CGRectMake(0, SCR_H*3/5, SCR_W, SCR_H*2/5);
        }];
        
        
        backView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, SCR_W, SCR_H)];
        backView.backgroundColor = [UIColor lightGrayColor];
        backView.alpha = 0.2;
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(hidePopView)];
        [backView addGestureRecognizer:tap];
        [self.view addSubview:backView];
        
        
        [self.shareView makeKeyAndVisible];
    }else{//如果view在屏幕上显示,就让他消失
        [self hidePopView];
    }
}
//隐藏视图
- (void)hidePopView{
    
    [backView removeFromSuperview];
    backView = nil;
    [UIView animateWithDuration:0.15 animations:^{
        self.shareView.frame = CGRectMake(0, SCR_H, SCR_W, SCR_H*2/5);
    }];
    
    [self.shareView resignKeyWindow];
}
#pragma Mark- 导航右侧按钮
- (UIButton *)saveBtn{
    if (!_saveBtn) {
        self.saveBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        self.saveBtn.frame = CGRectMake(0, 0, FIT_X(60), FIT_Y(60));
        self.saveBtn.center = CGPointMake(SCR_W/2,FIT_X(30+40));
        [self.saveBtn setImage:[UIImage imageNamed:@"left_myorder"] forState:UIControlStateNormal];
       
    }
    return _saveBtn;
}
//分享视图
- (UIView *)shareView{
    if (!_shareView) {
        _shareView = [[UIWindow alloc]initWithFrame:CGRectMake(0, SCR_H, SCR_W, SCR_H*2/5)];
        _shareView.backgroundColor = [UIColor whiteColor];
        _shareView.windowLevel = UIWindowLevelAlert;
        
        //添加一个收藏按钮
        
        [_shareView addSubview:self.saveBtn];
        
        //添加分享按钮
        NSArray *shareImgNames = @[@"sns_icon_1",@"sns_icon_22",@"sns_icon_23",@"sns_icon_24"];
        CGFloat btnWidth = FIT_X(60);
        CGFloat btnDis = FIT_X(20);
        CGFloat startX = (SCR_W - shareImgNames.count*btnWidth - (shareImgNames.count - 1)*btnDis)/2;
        CGFloat btnY = self.saveBtn.frame.origin.y + self.saveBtn.frame.size.height + FIT_X(40);
        
        self.shareBtnArr = [[NSMutableArray alloc]init];
        
        for (int i = 0; i < shareImgNames.count; i++) {
            UIButton *shareBtn = [UIButton buttonWithType:UIButtonTypeCustom];
            shareBtn.frame = CGRectMake(startX + i * (btnDis + btnWidth), btnY, btnWidth, btnWidth);
            [shareBtn setImage:[UIImage imageNamed:shareImgNames[i]] forState:UIControlStateNormal];
            [_shareView addSubview:shareBtn];
            [self.shareBtnArr addObject:shareBtn];
        }
    }
    return _shareView;
}

#pragma mark - viewWillAppear
- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    [self updateAllViewContents];
    
}

- (void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    [self hidePopView];
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end

HttpRequest.h //封装网络请求

#import 
typedef void (^PassType)(id ,BOOL);

@interface HttpRequest : NSObject
///实例化对象,同时设置回传的代码块
- (instancetype)initWithRequestCompletion:(PassType)pass;

///NSURLSession的GET方式请求网络数据
- (void)requestBySessionGETWithURL:(NSString *)urlStr parames:(NSDictionary *)paramaDic;
///NSURLSession的POST方式请求网络数据
- (void)requestBySessionPOSTWithURL:(NSString *)urlStr parames:(NSDictionary *)paramaDic;
@end

HttpRequest.m

#import "HttpRequest.h"

@interface HttpRequest ()
@property (nonatomic,strong)PassType pass;
@end

@implementation HttpRequest

#pragma mark - 实例化对象,同时设置回传的代码块
- (instancetype)initWithRequestCompletion:(PassType)pass{
    self = [super init];
    if (self) {
        self.pass = pass;
    }
    return self;
}

#pragma mark - NSURLSession请求数据
///NSURLSession的GET方式请求网络数据
/*
 1)urlStr - 服务器的主地址
   http://api.jisuapi.com/news/get
 2)paramaDic - 参数字典 比如:
  @{@"channel":@"头条",@"start":@"0"}
 3)如果执行get请求,需要得到如下格式的网址字符串
 http://api.jisuapi.com/news/get?channel = 头条&start=0
*/
- (void)requestBySessionGETWithURL:(NSString *)urlStr parames:(NSDictionary *)paramaDic{
    
    //1)将网址字符串拼接好
    NSMutableString *urlString = [urlStr mutableCopy];
    if (paramaDic != nil && paramaDic.count != 0) {
        [urlString appendString:@"?"];
        for (NSString *key in paramaDic) {
            /*假设第一次执行时键值对为chanel和头条.得到以下字符串:
            http://api.jisuapi.com/news/get?channel=头条&
              假设第二次执行时键值对为start和0.得到以下字符串:
            http://api.jisuapi.com/news/get?channel=头条&start=0&
            */
            NSString *temp = [NSString stringWithFormat:@"%@=%@&",key,paramaDic[key]];
            [urlString appendString:temp];
        }
        //去除最后一个&字符
        [urlString deleteCharactersInRange:NSMakeRange(urlString.length-1, 1)];
        //2)如果带汉字,对汉字编码处理
        urlString = [[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]mutableCopy];
        //3)封装网址对象
        NSURL *url = [[NSURL URLWithString:urlString]copy];
        //4)实例化请求对象
        NSURLRequest *req = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:6.0];
        //5)做一个NSURLSession,请求网络数据
        NSURLSession *session = [NSURLSession sharedSession];
        //6)执行获取网络数据任务
        NSURLSessionDataTask *task = [session dataTaskWithRequest:req completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            NSLog(@"---------- 易晓腾,请求数据 ----------");
            //如果请求失败
            if (error) {
                self.pass(error, NO);
            }
            //请求成功
            else{
                if (data == nil) {
                    self.pass(nil, NO);
                }
                else{
                    NSError *myError;
                    //JSON解析
                    id object = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&myError];
                    
                    //解析失败
                    if (myError) {
                        self.pass(myError, NO);
                    }
                    else{
                        self.pass(object, YES);
                        
                    }
                    
                }
            }
        }];
        //7)任务开始执行
        [task resume];
        
    }
    
}
///NSURLSession的POST方式请求网络数据
- (void)requestBySessionPOSTWithURL:(NSString *)urlStr parames:(NSDictionary *)paramaDic{
    //1)将网址字符串封装为地址对象
    NSURL *url = [NSURL URLWithString:urlStr];
    //2)定义一个请求对象
    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:6.0];
    //设置请求方式为POST
    [req setHTTPMethod:@"POST"];
    //将请求的参数做成一个NSData数据
    NSMutableString *contentStr = [[NSMutableString alloc]init];
    for (NSString *key in paramaDic) {
        NSString *temp = [NSString stringWithFormat:@"%@=%@",key,paramaDic[key]];
        [contentStr appendString:temp];
    }
    [contentStr deleteCharactersInRange:NSMakeRange(contentStr.length-1, 1)];
    NSData *contentData = [contentStr dataUsingEncoding:NSUTF8StringEncoding];
    //设置请求的内容
    [req setHTTPBody:contentData];
    
    //3)使用NSURLSession执行任务
    [[[NSURLSession sharedSession]dataTaskWithRequest:req completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error) {
            self.pass(error, NO);
        }
        else{
            NSError *myError;
            id object = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&myError];
            if (myError) {
                self.pass(myError, NO);
            }
            else{
                self.pass(object, YES);
            }
        }
    }]resume];
    
    
}
@end

URLService.h

#import 
#import "News.h"
#import "Weather.h"
#import "BookIN.h"
#import "BookShow.h"
typedef  void(^PassDataBlock)(id,BOOL);
@interface URLService : NSObject

//用于回传数据的方法
- (instancetype)initWithCompletion:(PassDataBlock)pass;

///"新闻头条" - 获取新闻数据
- (void)getNewsByChannel:(NSString *)channel start:(int)start;
///"新闻头条" - 获取频道数据
- (void)getAllChannels;
///"新闻头条" - 搜索新闻
- (void)searchNewsBySerachContent:(NSString *)searchTxt;


@end

URLService.m

#import "URLService.h"
#import "HttpRequest.h"
#import "LiveShow.h"


//--"AppKey"
#define APP_KEY @"dbe4d556aed8a277"
//--"新闻模块"网址
//获取新闻数据
#define NEWS_URL @"http://api.jisuapi.com/news/get"
//获取频道数据
#define CHANNELS_URL @"http://api.jisuapi.com/news/channel"
//搜索新闻
#define NEWS_SEARCH_URL @"http://api.jisuapi.com/news/search"


@interface URLService()
@property (nonatomic,strong)PassDataBlock pass;
@end

@implementation URLService

//用于回传数据的方法
- (instancetype)initWithCompletion:(PassDataBlock)pass{
    self = [super init];
    if (self) {
        self.pass = pass;
    }
    return self;
    
}
#pragma mark - "新闻模块"接口
///"新闻头条" - 获取新闻数据
- (void)getNewsByChannel:(NSString *)channel start:(int)start{
    NSNumber *startNum = [NSNumber numberWithInt:start];
    //定义参数字典
    NSDictionary *paramDic = @{
                               @"appkey":APP_KEY,
                               @"channel":channel,
                               @"num":@15,
                               @"start":startNum
                              };
    //实例化自定义的request对象,并设置回调的代码块
    HttpRequest *req = [[HttpRequest alloc]initWithRequestCompletion:^(id passData, BOOL success) {
        NSLog(@"新闻数据:%@",passData);
        if (!success) {
            self.pass(passData, NO);
        }
        else{
            NSDictionary *dic = (NSDictionary *)passData;
            if (![dic[@"status"] isEqualToString:@"0"]) {
                self.pass(dic[@"msg"], NO);
            }
            else{
               NSArray *newsArr =  [NewsCreat createNewsArrayWithDictionary:dic];
               
                self.pass(newsArr, YES);
            }
        }
    }];
    //使用GET方式请求数据
    [req requestBySessionGETWithURL:NEWS_URL parames:paramDic];
}
///"新闻头条" - 获取频道数据
- (void)getAllChannels{
    
}
///"新闻头条" - 搜索新闻
- (void)searchNewsBySerachContent:(NSString *)searchTxt{
    
}


@end

News.h

#import 

@interface News : NSObject

@property (nonatomic,assign)int ID;//此ID用于收藏,表示收藏新闻的ID;如果从网络请求数据解析时,是没有此ID值得

@property (nonatomic,strong)NSString *title;//标题
@property (nonatomic,strong)NSString *time;//时间
@property (nonatomic,strong)NSString *src;//来源
@property (nonatomic,strong)NSString *category;//分类
@property (nonatomic,strong)NSString *pic;//图片
@property (nonatomic,strong)NSString *content;//内容
@property (nonatomic,strong)NSString *url;//原文手机网址
@property (nonatomic,strong)NSString *weburl;//原文pc网址
@end

@interface NewsCreat:NSObject
///解析返回的json数据,将其变为一个封装了多个News对象的数组
+ (NSArray *)createNewsArrayWithDictionary:(NSDictionary *)dict;

@end

News.m

#import "News.h"

@implementation News

@end


@implementation NewsCreat
+(NSArray *)createNewsArrayWithDictionary:(NSDictionary *)dict{
    
    NSDictionary *resaultDic = dict[@"result"];
    NSArray *listArr = resaultDic[@"list"];
    
    NSMutableArray *newsArr = [[NSMutableArray alloc]init];
    for (NSDictionary *newsDic in listArr) {
        News *oneNew = [[News alloc]init];
        [oneNew setValuesForKeysWithDictionary:newsDic];
        [newsArr addObject:oneNew];
    }
    //将数组返回
    return newsArr;
}
@end

NewsDataBase.h

#import 
#import "News.h"
@interface NewsDataBase : NSObject
//类方法,用于外部类获取该单例类对象
+(instancetype)sharedDataBase;

-(BOOL)addNews:(News *)oneNew;

- (NSMutableArray *)getUserSvedNews;

- (BOOL)deleteOneNewsByID:(int)delID;




@end

NewsDataBase.m

#import "NewsDataBase.h"
#import "FMDB.h"
//-------SQL语句
#define SQL_INIT_TABLE @"CREATE TABLE news (id INTEGER PRIMARY KEY AUTOINCREMENT,userid INTEGER,title TEXT,time TEXT,pic TEXT,content TEXT,url TEXT,weburl TEXT)"
#define SQL_INSERT @"INSERT INTO news VALUES (NULL,%d,%@,%@,%@,%@,%@,%@)"
#define SQL_SELECT @"SELECT *FROM news WHERE userid = %d"

#define SQL_DELETE @"DELETE FROM news WHERE id = %d"
@interface NewsDataBase()
@property (nonatomic,strong)FMDatabase *fmDB;
@end

static NewsDataBase *_defaultNewsDB = nil;

@implementation NewsDataBase
#pragma  mark -单例实现方法
//实例对外的类方法
+(instancetype)sharedDataBase{
    if (_defaultNewsDB == nil) {
        _defaultNewsDB = [[NewsDataBase alloc]init];
    }
    return _defaultNewsDB;
}
//重写allocWithZone方法.防止使用alloc生成新对象
+(instancetype)allocWithZone:(struct _NSZone *)zone{
    if (_defaultNewsDB == nil) {
        _defaultNewsDB = [super allocWithZone:zone];
    }
    return _defaultNewsDB;
}

- (id)copy{
    return self;
}

- (id)mutableCopy{
    return self;
}

#pragma mark - 数据库,初始化表
- (FMDatabase *)fmDB{
    if (!_fmDB) {
        //文件路径
        NSString *filePath = [DOCUMENT_PATH stringByAppendingPathComponent:@"starrysky.db"];
        NSLog(@"数据库路径%@",filePath);
        _fmDB = [FMDatabase databaseWithPath:filePath];
        
    }
    return _fmDB;
}

- (instancetype)init{
    self = [super init];
    if (self) {
        [self.fmDB open];
        [self.fmDB executeUpdate:SQL_INIT_TABLE];
        [self.fmDB close];
    }
    return self;
}
#pragma Mark- 增,删,查方法
-(BOOL)addNews:(News *)oneNew{
    //如果打开数据库失败,直接返回NO,表示添加失败
    if (![self.fmDB open]) {
        [self.fmDB close];
        return NO;
    }
    
    //获取当前登录用户的id
    int userid = [[UserDataBase sharedDataBase]getCurrentLoginUser].ID;
    //打开数据库成功,执行添加语句
    BOOL success = [self.fmDB executeUpdateWithFormat:SQL_INSERT,userid,oneNew.title,oneNew.time,oneNew.pic,oneNew.content,oneNew.url,oneNew.weburl];
    //假设不成功
    if (!success) {
        [self.fmDB close];
        return NO;
    }
    [self.fmDB close];
    return YES;
}

- (NSMutableArray *)getUserSvedNews{
    if (![self.fmDB open]) {
        [self.fmDB close];
        return nil;
    }
    FMResultSet *resSet = [self.fmDB executeQueryWithFormat:SQL_SELECT,[UserDataBase sharedDataBase].getCurrentLoginUser.ID];
    
    NSMutableArray *arr = [[NSMutableArray alloc]init];
    while ([resSet next]) {
        
        News *oneNew = [[News alloc]init];
        oneNew.ID = [resSet intForColumn:@"id"];
        oneNew.title = [resSet stringForColumn:@"title"];
        oneNew.time = [resSet stringForColumn:@"time"];
        oneNew.pic = [resSet stringForColumn:@"pic"];
        oneNew.content = [resSet stringForColumn:@"content"];
        oneNew.url = [resSet stringForColumn:@"url"];
        oneNew.weburl = [resSet stringForColumn:@"weburl"];
        
        [arr insertObject:oneNew atIndex:0];
    }
    //如果数组中没有数据,表示用户没有收藏过任何新闻,返回nil
    if (arr.count == 0) {
        [self.fmDB close];
        return nil;
    }
    
    //数组中有数据,将数组返回给controller
    [self.fmDB close];
    
    return arr;
}

- (BOOL)deleteOneNewsByID:(int)delID{
    if (![self.fmDB open]) {
        [self.fmDB close];
        return NO;
    }
    
    BOOL success = [self.fmDB executeUpdateWithFormat:SQL_DELETE,delID];
    if (!success) {
        [self.fmDB close]; 
        return NO;
    }
    [self.fmDB close];
    return YES;
    
    return NO;
}
@end

NewsViewController.h

#import 

@interface NewsViewController : BaseViewController

@end

NewsViewController.m

#import "NewsViewController.h"
#import "NewsDetailViewController.h"
#import "NewsCollectionViewCell.h"
#import "UIImageView+WebCache.h"

#define TITLE_HEIGHT 44 //标题视图的高度
#define TITLE_BTN_WIDTH (( SCR_W - 44)/6) // 每个标题按钮的宽度
#define COLLECTION_CELL_REUSE @"collectionCell"//网格单元格的复用标识
@interface NewsViewController ()
{
    NSMutableArray *_titleArr;//标题数组
    NSMutableArray *_contentArr;//新闻内容数组
    
    NSInteger _currentIndex;//当前选中的标题按钮的tag值
    
    int _newsStart; //获取新闻的起始位置
    
   
}
//标题滚动视图
@property (nonatomic,strong)UIScrollView *titleScrView;
//标题指示标签
@property (nonatomic,strong)UIView *titleDownLine;
//标题添加按钮
@property (nonatomic,strong)UIButton *titleAddBtn;
//新闻内容的网格视图
@property (nonatomic,strong)UICollectionView *newsCollectView;
//详情控制器
@property (nonatomic,strong)NewsDetailViewController *newsDetailVC;

@end

@implementation NewsViewController


#pragma mark ===== 改变按钮和指示线 ====
-(void)changeSelectButtonAndDownLineWithButtonTag:(NSInteger)tag{
    // 如果选中的其他按钮,先将所有的按钮置为normal状态
    for (UIView *sub in self.titleScrView.subviews) {
        if ([sub isKindOfClass:[UIButton class]]) {
            UIButton *btn = (UIButton *)sub;
            btn.selected = NO;
            if (btn.tag == tag) {
                btn.selected = YES;
                _currentIndex = btn.tag;
            }
        }
    }
    [UIView animateWithDuration:0.138 animations:^{
        // 移动指示条
        self.titleDownLine.frame = CGRectMake((tag - 200) * TITLE_BTN_WIDTH, TITLE_HEIGHT - 2, TITLE_BTN_WIDTH, 2);
    }];
    
}
#pragma mark - 触发事件
//标题按钮触发
- (void)titleButtonPress:(UIButton *)sender{
    // 如果选择了当前选中的按钮,不做任何处理,结束方法
    if (_currentIndex == sender.tag) {
        return;
    }
    
    //让网格视图跟着滚动
    //[self.newsCollectView scrollRectToVisible:CGRectMake(SCR_W*(sender.tag - 200), 0, SCR_W, SCR_H-TITLE_HEIGHT) animated:YES];
    
    [self .newsCollectView setContentOffset:CGPointMake(SCR_W*(sender.tag- 200), 0) animated:NO];
    
}
//标题添加按钮
- (void)titleAddButtonPress:(UIButton *)sender{
    
}
#pragma Mark-- 实例化重写
//标题滚动视图
- (UIScrollView *)titleScrView{
    if (!_titleScrView) {
        _titleScrView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0,SCR_W-TITLE_HEIGHT, TITLE_HEIGHT)];
        
        
        //设置内容视图大小
        _titleScrView.contentSize = CGSizeMake(TITLE_BTN_WIDTH * _titleArr.count, TITLE_HEIGHT);
        //隐藏自带的水平滚动指示条
        _titleScrView.showsHorizontalScrollIndicator = NO;
        //添加标题按钮子视图
        for (int i = 0; i<_titleArr.count; i++) {
            UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
            btn.frame = CGRectMake(i*TITLE_BTN_WIDTH, 0, TITLE_BTN_WIDTH, TITLE_HEIGHT - 1);
            [btn setTitle:_titleArr[i] forState:UIControlStateNormal];
            [btn setTitle:_titleArr[i] forState:UIControlStateSelected];
            [btn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
            [btn setTitleColor:[UIColor redColor] forState:UIControlStateSelected];
            btn.tag = i + 200;
           
            if (i == 0) {
                 btn.selected = YES;
                _currentIndex = 200;
            }
            
             [btn addTarget:self action:@selector(titleButtonPress:) forControlEvents:UIControlEventTouchUpInside];
            [_titleScrView addSubview:btn];
        }
        [_titleScrView addSubview:self.titleDownLine];
        
    }
    return _titleScrView;
}

//标题指示视图
- (UIView *)titleDownLine{
    if (!_titleDownLine) {
        _titleDownLine = [[UIView alloc]initWithFrame:CGRectMake(0, TITLE_HEIGHT - 2, TITLE_BTN_WIDTH, 2)];
        _titleDownLine.backgroundColor = [UIColor orangeColor];
    }
    return _titleDownLine;
}
//新闻内容的网格视图
- (UICollectionView *)newsCollectView{
    if (!_newsCollectView) {
        //实例化流式布局对象
        UICollectionViewFlowLayout *flow = [[UICollectionViewFlowLayout alloc]init];
        //设置单元格大小
        flow.itemSize = CGSizeMake(SCR_W, SCR_H-TITLE_HEIGHT);
        //设置滚动方向
        flow.scrollDirection = UICollectionViewScrollDirectionHorizontal;
        //设置间隔为0
        flow.minimumLineSpacing = 0.;
        
        _newsCollectView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, TITLE_HEIGHT, SCR_W, SCR_H-TITLE_HEIGHT) collectionViewLayout:flow];
        
        _newsCollectView.dataSource = self;
        _newsCollectView.delegate = self;
        //设置分页
        _newsCollectView.pagingEnabled = YES;
        
        _newsCollectView.backgroundColor = [UIColor whiteColor];
        _newsCollectView.bounces = NO;
        //tag值
        _newsCollectView.tag = 999;
        
        
        //注册网格单元格
        [_newsCollectView registerClass:[NewsCollectionViewCell class] forCellWithReuseIdentifier:COLLECTION_CELL_REUSE];
        
    }
    return _newsCollectView;
    
}
//标题添加按钮
- (UIButton *)titleAddBtn{
    if (!_titleAddBtn) {
        _titleAddBtn = [UIButton buttonWithType:UIButtonTypeContactAdd];
        _titleAddBtn.frame = CGRectMake(SCR_W - TITLE_HEIGHT, 0, TITLE_HEIGHT, TITLE_HEIGHT);
        [_titleAddBtn addTarget:self action:@selector(titleAddButtonPress:) forControlEvents:UIControlEventTouchUpInside];
    }
    return _titleAddBtn;
}
//详情控制器-新闻
- (NewsDetailViewController *)newsDetailVC{
    if (!_newsDetailVC) {
        _newsDetailVC = [[NewsDetailViewController alloc]init];
    }
    return _newsDetailVC;
}

#pragma mark----------UICollectionViewDelegate

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    //计算出当前x轴的偏移量
    CGFloat disX = scrollView.contentOffset.x;
    //计算出当前显示的标题的下标
    int index = disX / SCR_W;
    /*
     2  -- 让标题滚动视图上的按钮跟着变化
     */
    // 选中的按钮变化
    
    if (index > _currentIndex - 200) {
        [self.titleScrView scrollRectToVisible:CGRectMake(TITLE_BTN_WIDTH*(index+1), 0, TITLE_BTN_WIDTH, TITLE_HEIGHT) animated:YES];
    }else{
        [self.titleScrView scrollRectToVisible:CGRectMake(TITLE_BTN_WIDTH*(index-1), 0, TITLE_BTN_WIDTH, TITLE_HEIGHT) animated:YES];
    }
    /*
     3.数据变化
     */

    if (index != _currentIndex - 200) {
        _newsStart = 0;
        [self getURLDatasWithChannel:_titleArr[index] start:_newsStart];
    }
    
    [self changeSelectButtonAndDownLineWithButtonTag:index + 200];
    
    
    
    
    
}

#pragma mark----------UICollectionViewDataSource
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    return _titleArr.count;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    NewsCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:COLLECTION_CELL_REUSE forIndexPath:indexPath];
    if (cell == nil) {
        cell = [[NewsCollectionViewCell alloc]initWithFrame:CGRectMake(0, 0, SCR_W, SCR_H-TITLE_HEIGHT)];
    }
    //为cell中的表格视图设置代理
    cell.newsTable.dataSource = self;
    cell.newsTable.delegate = self;
    //为cell中的下拉刷新视图设置回调代码块
    cell.mjHeadView.beginRefreshingBlock = ^(MJRefreshBaseView *refreshView) {
        _newsStart = 0;
        [self getURLDatasWithChannel:_titleArr[_currentIndex-200] start:_newsStart];
    };
    //为cell中的上拉刷新视图设置回调代码块
    cell.mjFootView.beginRefreshingBlock = ^(MJRefreshBaseView *refreshView) {
        _newsStart += 15;
        [self getURLDatasWithChannel:_titleArr[_currentIndex-200] start:_newsStart];
    };
    
    return cell;
}
#pragma mark -UITableViewDelegate
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    //获取当前cell对应的新闻数据
    News *selectNews = _contentArr[indexPath.row];
    
    self.newsDetailVC.passNew = selectNews;
    [self.navigationController pushViewController:self.newsDetailVC animated:YES];
    
    
}
#pragma mark ----UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return _contentArr.count;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    static NSString *identifier = @"tableCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
        
    }
    
    News *oneNew = _contentArr[indexPath.row];
    cell.textLabel.text = oneNew.title;
    [cell.imageView sd_setImageWithURL:[NSURL URLWithString:oneNew.pic] placeholderImage:[UIImage imageNamed:@"40"] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
        
    }] ;
    
    
    return cell;
}

#pragma mark - 请求网络数据方法
- (void)getURLDatasWithChannel:(NSString *)channel start: (int)start{
    
    //显示等待指示器
    [self.newsCollectView showIdicatorMBProgressHUD];
    //显示状态栏指示器
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    URLService *urlSer = [[URLService alloc]initWithCompletion:^(id data, BOOL success) {
        //停止等待指示器
        dispatch_async(dispatch_get_main_queue(), ^{
            //停止MBProgressHUD刷新
            [self.newsCollectView hideIdicatorMBProgressHUD];
            //停止状态栏指示器
            [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
            //停止下拉刷新和上拉刷新
            for (NewsCollectionViewCell *cell in self.newsCollectView.visibleCells) {
                if (cell.mjHeadView.isRefreshing) {
                    [cell.mjHeadView endRefreshing];
                }
                if (cell.mjFootView.isRefreshing) {
                    [cell.mjFootView endRefreshing];
                }
            }
        });
        
        //根据返回的数据,做提示
        if (!success) {
            dispatch_async(dispatch_get_main_queue(), ^{
                [self.view showTextStyleMBProgressHUDWithTitle:@"网络请求失败"];
            });
        }else{
            if (start == 0) {
                //刚开始加载或下拉刷新,对表格数据重新赋值
                _contentArr = [data mutableCopy];
            }else{
                [_contentArr addObjectsFromArray:data];
            }
            
            dispatch_async(dispatch_get_main_queue(), ^{
                for (NewsCollectionViewCell *cell in self.newsCollectView.visibleCells) {
                    [cell.newsTable reloadData];
                }
            });
            
        }
        
        
    }];
    [urlSer getNewsByChannel:channel start:start];
}
#pragma mark - viewDidLoad
-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    
   
}
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    _titleArr = [@[
                   @"头条",
                   @"新闻",
                   @"财经",
                   @"体育",
                   @"娱乐",
                   @"军事",
                   @"教育",
                   @"科技",
                   @"NBA",
                   ]mutableCopy];
    
    self.view.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:self.titleScrView];
    [self.view addSubview:self.titleAddBtn];
    UIView *view = [[UIView alloc]init];
    [self.view addSubview:view];
    [self.view addSubview:self.newsCollectView];
    //获取网络数据
    _currentIndex = 200;
    _newsStart = 0;
    [self getURLDatasWithChannel:_titleArr[_currentIndex - 200] start:_newsStart];
    //让表格的下拉刷新视图开始刷新
    for (NewsCollectionViewCell *cell in self.newsCollectView.visibleCells) {
        [cell.mjHeadView beginRefreshing];
        
    }
    
}



- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end

NewsCollectionViewCell.h


#import 
#import "MJRefresh.h"
@interface NewsCollectionViewCell : UICollectionViewCell
@property (nonatomic,strong)UITableView *newsTable;
//刷新控件
//下拉刷新
@property (nonatomic,strong)MJRefreshHeaderView *mjHeadView;
//上拉刷新
@property (nonatomic,strong)MJRefreshFooterView *mjFootView;
@end

NewsCollectionViewCell.m

#import "NewsCollectionViewCell.h"

@implementation NewsCollectionViewCell

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.newsTable = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, SCR_W, SCR_H-44-108)style:UITableViewStylePlain];
        [self.contentView addSubview:self.newsTable];
        //给表格视图添加"下拉刷新"和"上拉刷新"视图
        self.mjHeadView = [[MJRefreshHeaderView alloc]initWithScrollView:self.newsTable];
        
        
        self.mjFootView = [[MJRefreshFooterView alloc]initWithScrollView:self.newsTable];
    }
    return self;
}
@end

NewsDetailViewController.h

#import 

@interface NewsDetailViewController : BaseViewController
@property (nonatomic,strong)News *passNew;
@end

NewsDetailViewController.m

#import "NewsDetailViewController.h"
#import "LoginViewController.h"
@interface NewsDetailViewController ()
@property (nonatomic,strong)UIWebView *webView;
@end

@implementation NewsDetailViewController

-(UIWebView *)webView{
    if (!_webView) {
        _webView = [[UIWebView alloc]initWithFrame:CGRectMake(0, 0, SCR_W, SCR_H)];
        _webView.delegate = self;
    }
    return _webView;
}
#pragma mark -UIWebViewDelegate

- (void)webViewDidStartLoad:(UIWebView *)webView{
    
}
- (void)webViewDidFinishLoad:(UIWebView *)webView{
    [self.view hideIdicatorMBProgressHUD];
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{
    [self.view hideIdicatorMBProgressHUD];
  
}
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor whiteColor];
   
    [self addShareButtonToNavigationRightBarItem];
    
    [self.saveBtn addTarget:self action:@selector(saveButtonPress:) forControlEvents:UIControlEventTouchUpInside];
    
    [self.view addSubview:self.webView];
    
}
#pragma mark - 触发方法
- (void)saveButtonPress:(id)sender{
    NSLog(@"*********执行收藏");
    //隐藏弹出的收藏视图
    [self hidePopView];
    //如果没有登录
    if (![[UserDataBase sharedDataBase]userHadLogin]) {
        
        LoginViewController *loginVC = [[LoginViewController alloc]init];
        [self presentViewController:loginVC animated:YES completion:nil];
    }
    //登录过
    else{
        //执行收藏
        BOOL success = [[NewsDataBase sharedDataBase]addNews:self.passNew];
        if (success) {
            [self.view showTextStyleMBProgressHUDWithTitle:@"收藏成功"];
        }
        else{
            [self.view showTextStyleMBProgressHUDWithTitle:@"收藏失败"];
        }
        
    }
}
- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    
    if (self.webView) {
        [self.webView removeFromSuperview];
        self.webView = nil;
    }

    [self.view addSubview:self.webView];
    NSString *urlStr = self.passNew.url;
    NSURL *url = [NSURL URLWithString:urlStr];
    NSURLRequest *req = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:6.0];
    
    [self.webView loadRequest:req];
    
    [self.view showIdicatorMBProgressHUD];
    
}
-(void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    [self.webView stopLoading];
    self.webView = nil;
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end

你可能感兴趣的:(Oc 新闻接口请求数据UI布局)