Commit 3836454d cgx

完成睡眠文章页面

1 个父辈 705b37d1
//
// ArticleCell.h
// DreamSleep
//
// Created by peter on 2022/10/19.
//
#import "BaseTableViewCell.h"
#import "ArticleModel.h"
NS_ASSUME_NONNULL_BEGIN
/// 文章cell
@interface ArticleCell : BaseTableViewCell
@property (nonatomic, strong) ArticleModel *model;
@end
NS_ASSUME_NONNULL_END
//
// ArticleCell.m
// DreamSleep
//
// Created by peter on 2022/10/19.
//
#import "ArticleCell.h"
@interface ArticleCell ()
@property (nonatomic, strong) UILabel *titleLab;
@property (nonatomic, strong) UILabel *contentLab;
@property (nonatomic, strong) UIImageView *coverIV;
@property (nonatomic, strong) UIView *tagsView;
@end
@implementation ArticleCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
[self cornerRadius:12];
self.dk_backgroundColorPicker = DKColorPickerWithKey(CornerViewBG);
[self.contentView addSubview:self.titleLab];
[self.contentView addSubview:self.contentLab];
[self.contentView addSubview:self.coverIV];
[self.contentView addSubview:self.tagsView];
[self.coverIV mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.contentView).offset(-8);
make.centerY.equalTo(self.contentView);
make.size.mas_equalTo(CGSizeMake(86, 86));
}];
[self.titleLab mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.contentView).offset(8);
make.top.equalTo(self.contentView).offset(12);
make.right.equalTo(self.coverIV.mas_left).offset(-12);
}];
[self.contentLab mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(self.titleLab);
make.top.equalTo(self.contentView).offset(43);
}];
[self.tagsView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(self.titleLab);
make.height.equalTo(@21);
make.bottom.equalTo(self.contentView).offset(-12);
}];
}
return self;
}
- (void)setModel:(ArticleModel *)model {
_model = model;
self.titleLab.text = model.title;
self.contentLab.text = model.content;
[self.coverIV yy_setImageWithURL:[NSURL URLWithString:model.cover] placeholder:[UIImage defaultPlaceholderWithSize:CGSizeMake(86, 86)]];
NSArray *tagsTitleArr = model.tags ? [model.tags componentsSeparatedByString:@"|"] : @[];
[self.tagsView.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
[obj removeFromSuperview];
}];
for (int idx = 0; idx < tagsTitleArr.count; idx++) {
NSString *tagTitle = [NSString stringWithFormat:@"#%@", tagsTitleArr[idx]];
CGFloat tagTitleW = [UILabel getWidthWithText:tagTitle font:SysFont(12)] + 16;
UILabel *tagLab = [UILabel labWithTextColor:BrandColor font:SysFont(12)];
tagLab.text = tagTitle;
tagLab.textAlignment = NSTextAlignmentCenter;
tagLab.backgroundColor = ColorFromHexA(0x62C3D5, .2);
[tagLab cornerRadius:10.5];
tagLab.frame = CGRectMake(idx * (tagTitleW + 8), 0, tagTitleW, 21);
[self.tagsView addSubview:tagLab];
}
}
#pragma mark - lazy
- (UILabel *)titleLab {
if (!_titleLab) {
_titleLab = [UILabel labWithFont:BoldFont(15)];
_titleLab.dk_textColorPicker = DKColorPickerWithKey(Dk_TITLE);
}
return _titleLab;
}
- (UILabel *)contentLab {
if (!_contentLab) {
_contentLab = [UILabel labWithFont:SysFont(14)];
_contentLab.dk_textColorPicker = DKColorPickerWithColors(SubTitleColor, ColorFromHexA(0xFFFFFF, .5), DSWhite);
}
return _contentLab;
}
- (UIImageView *)coverIV {
if (!_coverIV) {
_coverIV = [UIImageView new];
[_coverIV cornerRadius:12];
_coverIV.dk_alphaPicker = DKAlphaPickerWithAlphas(1.f, 0.5f, 0.1f);
}
return _coverIV;
}
- (UIView *)tagsView {
if (!_tagsView) {
_tagsView = [UIView new];
}
return _tagsView;
}
@end
...@@ -6,12 +6,12 @@ ...@@ -6,12 +6,12 @@
// //
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#import "BaseViewController.h"
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
/// 社区睡眠文章控制器 /// 社区睡眠文章控制器
@interface ArticleController : UIViewController @interface ArticleController : BaseViewController
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END
...@@ -7,9 +7,12 @@ ...@@ -7,9 +7,12 @@
#import "ArticleController.h" #import "ArticleController.h"
#import "ArticleRequestModel.h" #import "ArticleRequestModel.h"
#import "ArticleCell.h"
@interface ArticleController () @interface ArticleController () <UITableViewDelegate>
@property (nonatomic, strong) ArticleRequestModel *articleVM;
@property (nonatomic, strong) UITableView *articleView;
@property (nonatomic, strong) DSDataSource *dataSource;
@end @end
@implementation ArticleController @implementation ArticleController
...@@ -19,15 +22,111 @@ ...@@ -19,15 +22,111 @@
self.navigationItem.title = @"睡眠文章"; self.navigationItem.title = @"睡眠文章";
self.view.dk_backgroundColorPicker = DKColorPickerWithKey(VCViewBG); self.view.dk_backgroundColorPicker = DKColorPickerWithKey(VCViewBG);
self.articleVM = [[ArticleRequestModel alloc] init];
[ArticleRequestModel querySsmianKnowledgeListWithCompletion:^(ArticleRequestModel * _Nonnull requestModel) { [self.dataSource addDataArray:self.articleVM.articleArr];
}
- (void)getArticleListRequest:(BOOL)loadMore {
[self.articleVM querySsmianKnowledgeListWithLoadMore:loadMore completion:^(ArticleRequestModel * _Nonnull requestModel) {
[self endRefreshing:loadMore];
if (requestModel.resCode == DSResCodeSuccess) {
if (requestModel.articleArr.count == 0) {
[self dealErrorWithType:ExceptionTypeNoData errInfo:@""];
return;
}
if (requestModel.latestDataList.count == 0) {
if (loadMore) {
[self.articleView.mj_footer endRefreshingWithNoMoreData];
}
} else {
[self.articleVM updateOffset];
[self.dataSource addDataArray:self.articleVM.articleArr];
[self.articleView reloadData];
}
} else {
if (requestModel.articleArr.count) {
[DSProgressHUD showToast:requestModel.errMessage];
} else {
[self dealErrorWithType:ExceptionTypeNet errInfo:requestModel.errMessage];
}
}
}]; }];
} }
#pragma mark - 品牌模式 - (void)endRefreshing:(BOOL)loadMore {
- (NaviStyle)navigationBarStyle { if (loadMore) {
return NaviStyleDefault; [self.articleView.mj_footer endRefreshing];
} else {
[self.articleView.mj_header endRefreshing];
[self.articleView.mj_footer resetNoMoreData];
}
}
- (void)refreshHandle {
[super refreshHandle];
[self.articleView.mj_header beginRefreshing];
}
#pragma mark - UITableViewDelegate
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 110;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return section == 0 ? 15 : CGFLOAT_MIN;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
return [UIView new];
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return section == self.dataSource.dataArray.count - 1 ? 15 : 12;;
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
return [UIView new];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
ArticleModel *model = self.dataSource.dataArray[indexPath.section];
[self.navigationController pushViewController:[[DsWebController alloc] initWithTitle:model.title link:model.url] animated:YES];
}
#pragma mark - lazy
- (DSDataSource *)dataSource {
if (!_dataSource) {
CellConfigureBlock cellBlock = ^(ArticleCell * cell, ArticleModel * model, NSIndexPath * indexPath) {
cell.model = model;
};
_dataSource = [[DSDataSource alloc] initWithIdentifier:NSStringFromClass([ArticleCell class]) datas:@[] isSection:YES configureBlock:cellBlock];
UITableView *articleTV = [[UITableView alloc] initWithFrame:CGRectMake(15, 0, kScreenWidth - 30, kScreenHeight - kTopHeight(0)) style:UITableViewStyleGrouped];
articleTV.separatorStyle = UITableViewCellSeparatorStyleNone;
articleTV.delegate = self;
articleTV.dataSource = _dataSource;
articleTV.showsVerticalScrollIndicator = NO;
articleTV.backgroundColor = DSClearColor;
articleTV.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
[articleTV registerClass:[ArticleCell class] forCellReuseIdentifier:NSStringFromClass([ArticleCell class])];
UIView *footView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, CGFLOAT_MIN)];
articleTV.tableFooterView = footView;
[self.view addSubview:articleTV];
self.articleView = articleTV;
WS(weakSelf);
articleTV.mj_header = [DSGifHeader headerWithRefreshingBlock:^{
[weakSelf getArticleListRequest:NO];
}];
[articleTV.mj_header beginRefreshing];
articleTV.mj_footer = [MJRefreshBackNormalFooter footerWithRefreshingBlock:^{
[weakSelf getArticleListRequest:YES];
}];
}
return _dataSource;
} }
@end @end
//
// ArticleModel.h
// DreamSleep
//
// Created by peter on 2022/10/19.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface ArticleModel : NSObject
@property (nonatomic, assign) NSInteger articleID;
@property (nonatomic, copy) NSString *tags;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *content;
@property (nonatomic, copy) NSString *url;
@property (nonatomic, copy) NSString *cover;
@end
NS_ASSUME_NONNULL_END
//
// ArticleModel.m
// DreamSleep
//
// Created by peter on 2022/10/19.
//
#import "ArticleModel.h"
@implementation ArticleModel
+ (nullable NSDictionary<NSString *, id> *)modelCustomPropertyMapper {
return @{@"articleID" : @"article_id",
@"tags" : @"article_tags",
@"title" : @"article_title",
@"content" : @"article_content",
@"url" : @"article_url",
@"cover" : @"cover_img"
};
}
@end
...@@ -12,10 +12,17 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -12,10 +12,17 @@ NS_ASSUME_NONNULL_BEGIN
/// 文章咨询数据请求model /// 文章咨询数据请求model
@interface ArticleRequestModel : DSNetworkTool @interface ArticleRequestModel : DSNetworkTool
/// 服务器返回最新某一页的列表数据
@property (nonatomic, strong) NSArray *latestDataList;
/// 最终列表数据
@property (nonatomic, strong) NSArray *articleArr;
/// 获取文章咨询列表接口 /// 获取文章咨询列表接口
/// @param completion completion /// @param loadMore loadMore
+ (NSURLSessionDataTask *)querySsmianKnowledgeListWithCompletion:(void (^)(ArticleRequestModel *requestModel))completion; /// @param completion offset
- (NSURLSessionDataTask *)querySsmianKnowledgeListWithLoadMore:(BOOL)loadMore completion:(void (^)(ArticleRequestModel *requestModel))completion;
- (void)updateOffset;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END
...@@ -6,24 +6,53 @@ ...@@ -6,24 +6,53 @@
// //
#import "ArticleRequestModel.h" #import "ArticleRequestModel.h"
#import "ArticleModel.h"
@interface ArticleRequestModel ()
@property (nonatomic, assign) int offset;
@end
@implementation ArticleRequestModel @implementation ArticleRequestModel
+ (NSURLSessionDataTask *)querySsmianKnowledgeListWithCompletion:(void (^)(ArticleRequestModel *requestModel))completion { - (instancetype)init {
ArticleRequestModel * requestModel = [[ArticleRequestModel alloc] init]; if (self = [super init]) {
self.offset = 1;
self.articleArr = [NSArray array];
}
return self;
}
- (NSURLSessionDataTask *)querySsmianKnowledgeListWithLoadMore:(BOOL)loadMore completion:(void (^)(ArticleRequestModel *requestModel))completion {
if (loadMore == NO) { self.offset = 1; }
NSString *api = @"query_ssmian_knowledge_list"; NSString *api = @"query_ssmian_knowledge_list";
NSString *argStr = [NSString stringWithFormat:@"query{%@}", api]; NSString *argStr = [NSString stringWithFormat:@"query{%@(offset:%d)}", api, self.offset];
return [self httpPostBodyRequestWithAPI:api params:@{@"query" : argStr} view:nil hasNetActivity:YES loadingInfo:nil hasFailInfo:NO success:^(NSDictionary * _Nonnull apiDic) { return [ArticleRequestModel httpPostBodyRequestWithAPI:api params:@{@"query" : argStr} view:nil hasNetActivity:YES loadingInfo:nil hasFailInfo:NO success:^(NSDictionary * _Nonnull apiDic) {
DSLog(@"文章咨询数据接口apiDic:%@", apiDic); DSLog(@"文章咨询数据接口apiDic:%@", apiDic);
requestModel.resCode = DSResCodeSuccess; self.resCode = DSResCodeSuccess;
NSDictionary *resultDic = apiDic[@"result"]; NSArray *resultArr = apiDic[@"result"];
NSMutableArray *tmpArr = [NSMutableArray array];
completion(requestModel); for (int i = 0; i < resultArr.count; i++) {
ArticleModel *model = [ArticleModel yy_modelWithDictionary:resultArr[i]];
[tmpArr addObject:model];
}
self.latestDataList = tmpArr.copy;
if (loadMore) {
NSMutableArray *tmp_list_arr = [NSMutableArray arrayWithArray:self.articleArr];
[tmp_list_arr addObjectsFromArray:self.latestDataList.copy];
self.articleArr = tmp_list_arr.copy;
} else {
self.articleArr = self.latestDataList.copy;
}
completion(self);
} failure:^(id _Nonnull failureInfo) { } failure:^(id _Nonnull failureInfo) {
requestModel.resCode = [failureInfo[@"errorCode"] integerValue]; self.resCode = [failureInfo[@"errorCode"] integerValue];
requestModel.errMessage = failureInfo[@"errMessage"]; self.errMessage = failureInfo[@"errMessage"];
completion(requestModel); completion(self);
}]; }];
} }
- (void)updateOffset {
self.offset++;
}
@end @end
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!