[How to] 使用Xib来创建view

时间:2022-09-15 14:30:37

1.简介

代码库

正如之前博客介绍的,xib可定义页面的某个部分,特别当此部分区域的view集中并且还有一些相互关联性(如隐藏等)是i特别适合使用xib来进行封装。

本文为[How to]使用自定义cell进行tableview的创建,适用于cell样式不发生变化的情况的后续。在本文中需要在tableview的footview中增加一个加载

按钮用于模拟加载更多数据的场景。如下图:

[How to] 使用Xib来创建view

2.实现

1.创建xib文件

[How to] 使用Xib来创建view

在xib中load more ing view为隐藏状态,对于进度圈也有特殊如下设置:

[How to] 使用Xib来创建view

这是为了让进度圈在显式的时候旋转效果,在隐藏的时候停止旋转效果,以减少性能的损耗。

2.创建对应的view子类XFLoadMoreView

XFLoadMoreView.h

#import <UIKit/UIKit.h>

// 创建按钮点击的处理协议
@class XFLoadMoreView;
@protocol XFLoadMoreViewDelegate <NSObject>

/**
 *  当按钮点击后通知代理实现对象
 *
 *  @param loadMoreView 触发者本身
 */
@optional
-(void) loadMoreViewDidClickedToLoadBtn:(XFLoadMoreView *) loadMoreView;

@end

@interface XFLoadMoreView : UIView

// 代理属性,指向显示了此代理的对象,防止循环引用需要使用weak属性参数
@property (nonatomic,weak) id<XFLoadMoreViewDelegate> delegate;

/**
 *  类初始化方法
 *
 *  @return 对象
 */
+(instancetype) loadMoreView;

@end

XFLoadMoreView.m

#import "XFLoadMoreView.h"

@interface XFLoadMoreView()
@property (weak, nonatomic) IBOutlet UIButton *loadMoreBtnView;

@property (weak, nonatomic) IBOutlet UIView *loadMoreIngView;

- (IBAction)loadMoreClick;
@end

@implementation XFLoadMoreView

/**
 *  初始化方法
 *
 *  @return load view
 */
+(instancetype) loadMoreView
{
    // 直接从xib中加载view
    XFLoadMoreView *loadView  = [[[NSBundle mainBundle] loadNibNamed:@"XFLoadButton" owner:nil options:nil] lastObject];

    // 美化按钮,将按钮的四个角圆润化
    loadView.loadMoreBtnView.layer.cornerRadius = ;
    loadView.loadMoreBtnView.layer.masksToBounds = YES;

    return loadView;
}

/**
 *  点击加载更多按钮后触发
 */
- (IBAction)loadMoreClick {
    // 将botton隐藏让后将加载样式呈现
    self.loadMoreBtnView.hidden = YES;
    self.loadMoreIngView.hidden = NO;

    // 使用此方法能够达到延迟执行效果
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2.0 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        self.loadMoreBtnView.hidden = NO;
        self.loadMoreIngView.hidden = YES;

        // 向代理发送信息,由于是代理定义中设置的是可选方法,所以发送信息之前需要检查是否实现了此方法
        if ([self.delegate respondsToSelector:@selector(loadMoreViewDidClickedToLoadBtn:)])
        {
            [self.delegate loadMoreViewDidClickedToLoadBtn:self];
        }
    });

}
@end

3.设置当前xib中view对应的类

[How to] 使用Xib来创建view

并将按钮和加载view做代码连结处理。

4.Controller测的处理-实现代理

XFLoadMoreView类中定义了代理XFLoadMoreViewDelegate,在Controller测去实现此代理方法,藉此后续在xib中触发的点击事件后能够通知到Controller去处理。

@interface XFGoodsShowsViewController () <UITableViewDataSource, XFLoadMoreViewDelegate>
#pragma 重写foot view的代理方法

// 加载按钮按下后通知到此对象调用此方法
-(void) loadMoreViewDidClickedToLoadBtn:(XFLoadMoreView *) loadMoreView
{
    // 这里我们模拟增加一个团购的信息,插入到列表的最好一行
    XFGoodModel *model = [[XFGoodModel alloc] init];
    model.image = @"image.jpg";
    model.name = @"new food";
    model.price = ;
    model.soldNum = ;

    // 将次信息插入到表数据源中
    [self.goodsList addObject:model];

    // 需要将此数据塞入table的最后一行
    NSIndexPath *indexPath = [NSIndexPath indexPathForItem:self.goodsList.count -  inSection:];\
    [self.goodsTableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];

    // 加载完毕后将table滚到新加入的行那里,也就是最后一条
    [self.goodsTableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}

5.Controller测的处理-初始化加载view并设定其代理对象

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    // 指定tableview的数据代理
    self.goodsTableView.dataSource = self;

    // 加载tableView的footview
    XFLoadMoreView *loadMoreView = [XFLoadMoreView loadMoreView];

    // 设定view的代理为当前对象,时间发生后将通知当前对象
    loadMoreView.delegate = self;

    // 设定tableview的foot view属性
    self.goodsTableView.tableFooterView = loadMoreView;
}

3.总结

本文最重要的是阐述当自定义view中发生事件后如何通过代理去通知Controller,这样做的目的就是自定义view与外部解耦,这样自定义view才具有通用性。