使用FDTemplateLayout框架打造个性App

效果展示

工程下载地址

这里写图片描述

·

这里写图片描述

进入构建结构

首先我们新建一个工程

这里写图片描述

接下来我们拖进来一个Table View Controller,将Storyboard Entry Point指向我们的Table View Controller。原来的ViewController就可以删除了。效果如图所示

这里写图片描述

这里写图片描述

选中Table View Controller,点击上面菜单栏中Editor->Embed in->Navigation Controller

这里写图片描述

这里写图片描述

基本的工作我们都做完了,可以讲工程中没用的东西都可以删除了,方便我们进行编写东西

这里写图片描述

主题(代码编写)

在这里我进行代码的编写,讲述主要部分,后面会把完整的项目给出

构建LDEntity用来初始化字典,进行Json数据的解析

LDEntity.h

#import <Foundation/Foundation.h>

@interface FDFeedEntity : NSObject

- (instancetype)initWithDictionary:(NSDictionary *)dictionary;

@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *content;
@property (nonatomic, copy) NSString *username;
@property (nonatomic, copy) NSString *time;
@property (nonatomic, copy) NSString *imageName;

@end

-(instancetype)initWithDictionary:(NSDictionary *)dictionary方法的具体实现,返回本身类型

LDEntity.m

#import "FDFeedEntity.h"

@implementation FDFeedEntity

- (instancetype)initWithDictionary:(NSDictionary *)dictionary
{
    self = super.init;
    if (self) {
        self.title = dictionary[@"title"];
        self.content = dictionary[@"content"];
        self.username = dictionary[@"username"];
        self.time = dictionary[@"time"];
        self.imageName = dictionary[@"imageName"];
    }
    return self;
}

@end

以上代码的功能主要是为了解析JSON数据

构建我们的Main.storyboard

选中Table View更改Style为Grouped

这里写图片描述

设计出以下样式,并且使用 auto layout进行约束

这里写图片描述

接下来编写cell

新建LDCell 继承 UITableViewCell

这里写图片描述

将Main.storyboard中TableView中的Cell的Identifier设置为LDCell,并且关联LDCell

这里写图片描述

LDCell.h

构建一个LDEntity对象解析数据

#import <UIKit/UIKit.h>
#import "LDEntity.h"

@interface LDCell : UITableViewCell

@property(nonatomic,strong)LDEntity *entity;

@end

将刚才的所有控件与LDCell.m关联

这里写图片描述

在LDCell.m中构建entity的set方法,还有需要注意的是如果你没有使用auto layout,你需要重写约束方法

LDCell.m

#import "LDCell.h"

@interface LDCell ()
@property (weak, nonatomic) IBOutlet UILabel *titleLabel;
@property (weak, nonatomic) IBOutlet UILabel *contentLabel;
@property (weak, nonatomic) IBOutlet UIImageView *contentImageView;
@property (weak, nonatomic) IBOutlet UILabel *usernameLabel;
@property (weak, nonatomic) IBOutlet UILabel *timeLabel;

@end

@implementation LDCell

- (void)awakeFromNib {
    // 修复IOS7中的BUG- 初始化 constraints warning

    self.contentView.bounds = [UIScreen mainScreen].bounds;
}

//关联控件进行数据显示
-(void)setEntity:(LDEntity *)entity{
    _entity = entity;

    self.titleLabel.text = entity.title;
    self.contentLabel.text = entity.content;
    self.contentImageView.image = entity.imageName.length > 0 ? [UIImage imageNamed:entity.imageName] : nil;
    self.usernameLabel.text = entity.username;
    self.timeLabel.text = entity.time;
}

#if 0

// 如果没有使用 auto layout, 请重写这个方法
- (CGSize)sizeThatFits:(CGSize)size
{
    CGFloat totalHeight = 0;
    totalHeight += [self.titleLabel sizeThatFits:size].height;
    totalHeight += [self.contentLabel sizeThatFits:size].height;
    totalHeight += [self.contentImageView sizeThatFits:size].height;
    totalHeight += [self.usernameLabel sizeThatFits:size].height;
    totalHeight += 40; // margins
    return CGSizeMake(size.width, totalHeight);
}

#endif

@end

开始编写我们最重要的类LDViewController.在编写这个类之前,我们需要使用FDTemplateLayout
,并且将TableViewController与LDViewController进行关联

LDViewController.h

#import <UIKit/UIKit.h>

@interface FDFeedViewController : UITableViewController

@end

TableView的使用有不明白的可以去学习下,这里不做解释了,注释中给出了重点的地方讲解,设置data source以及设置Delegate在程序中做出区分

LDViewController.m


#import "LDViewController.h"
#import "UITableView+FDTemplateLayoutCell.h"
#import "LDEntity.h"
#import "LDCell.h"

@interface LDViewController ()<UIActionSheetDelegate>

@property (nonatomic, copy) NSArray *prototypeEntitiesFromJSON;
@property (nonatomic, strong) NSMutableArray *feedEntitySections; // 2d array
@property (nonatomic, assign) BOOL cellHeightCacheEnabled;

@end

@implementation LDViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.tableView.estimatedRowHeight = 200;
    self.tableView.fd_debugLogEnabled = YES;

    self.cellHeightCacheEnabled = YES;

    [self buildTestDataThen:^{
        self.feedEntitySections = @[].mutableCopy;
        [self.feedEntitySections addObject:self.prototypeEntitiesFromJSON.mutableCopy];
        [self.tableView reloadData];
    }];
}

- (void)buildTestDataThen:(void (^)(void))then
{
    // 模拟一个异步请求
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        // 读取数据从 `data.json`
        NSString *dataFilePath = [[NSBundle mainBundle] pathForResource:@"data" ofType:@"json"];
        NSData *data = [NSData dataWithContentsOfFile:dataFilePath];
        NSDictionary *rootDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
        NSArray *feedDicts = rootDict[@"feed"];

        // 讲数据转化为 `LDEntity`
        NSMutableArray *entities = @[].mutableCopy;
        [feedDicts enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
            [entities addObject:[[LDEntity alloc] initWithDictionary:obj]];
        }];
        self.prototypeEntitiesFromJSON = entities;

        // 重返
        dispatch_async(dispatch_get_main_queue(), ^{
            !then ?: then();
        });
    });
}

//设置数据源
#pragma mark - Table view data source


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return self.feedEntitySections.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [self.feedEntitySections[section] count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //LDCell为Main.storyboard中的cell控件
    LDCell *cell = [tableView dequeueReusableCellWithIdentifier:@"LDCell" forIndexPath:indexPath];
    [self configureCell:cell atIndexPath:indexPath];
    return cell;
}

- (void)configureCell:(LDCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
    cell.fd_enforceFrameLayout = NO; // Enable to use "-sizeThatFits:"
    if (indexPath.row % 2 == 0) {
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    } else {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    }
    cell.entity = self.feedEntitySections[indexPath.section][indexPath.row];
}



//设置委托
#pragma mark - UITableViewDelegate

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (self.cellHeightCacheEnabled) {

        //LDCell为Main.storyboard中的cell控件

        return [tableView fd_heightForCellWithIdentifier:@"LDCell" cacheByIndexPath:indexPath configuration:^(LDCell *cell) {
            [self configureCell:cell atIndexPath:indexPath];
        }];
    } else {
        return [tableView fd_heightForCellWithIdentifier:@"LDCell" configuration:^(LDCell *cell) {
            [self configureCell:cell atIndexPath:indexPath];
        }];
    }
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        NSMutableArray *mutableEntities = self.feedEntitySections[indexPath.section];
        [mutableEntities removeObjectAtIndex:indexPath.row];
        [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
    }
}


@end

如果你想有自己的cell,你可以这么做:


#import "UITableView+FDTemplateLayoutCell.h"

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return [tableView fd_heightForCellWithIdentifier:@"reuse identifer" configuration:^(id cell) {
        // 配置此Cell(单元格)的数据, 同你在"-tableView:cellForRowAtIndexPath:"做了什么一样
        // 像这样:
        //    cell.entity = self.feedEntities[indexPath.row];
    }];
}

下面制作我们的最后一个功能就是下拉刷新操作

我们使用UITableViewController自带的UIRefreshControl

在LDViewController.m中添加此方法,并且与UIRefreshControl关联

//重新加载数据

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self.feedEntitySections removeAllObjects];
        [self.feedEntitySections addObject:self.prototypeEntitiesFromJSON.mutableCopy];
        [self.tableView reloadData];
        [sender endRefreshing];
    });

效果如下:

这里写图片描述

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用Vue搭建一个app框架的步骤: 1. 创建一个Vue项目 可以使用Vue官方提供的Vue CLI工具创建一个新的Vue项目,也可以手动创建一个Vue项目。 2. 安装相关依赖 在创建好的Vue项目中,需要安装一些相关的依赖库,例如vue-router、vuex、axios等。 可以使用npm命令安装这些依赖库: ``` npm install vue-router vuex axios --save ``` 3. 配置路由和状态管理 在src目录下创建一个router.js文件,用于配置路由规则。在src目录下创建一个store.js文件,用于配置状态管理。 4. 创建视图组件 在src目录下创建一个views目录,用于存放各个视图组件。可以根据实际需要创建不同的视图组件。 5. 创建公共组件 在src目录下创建一个components目录,用于存放公共组件。例如Header、Footer等组件可以放在这里。 6. 创建App.vue组件 在src目录下创建一个App.vue组件,用于定义整个app的布局和结构。 7. 在main.js中引入依赖库和组件 在main.js文件中,引入相关依赖库和组件,并实例化Vue对象。 8. 在App.vue中配置路由和状态管理 在App.vue中引入router和store对象,并在template使用router-view和vuex的mapState、mapActions等指令。 9. 运行Vue项目 在命令行中运行npm run serve命令,启动Vue项目。可以在浏览器中访问http://localhost:8080查看效果。 以上就是使用Vue搭建一个app框架的步骤。需要根据实际需求进行调整和修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值