UICollectView自定义Layout布局

关于UICollectView自定义Layout布局,首先需要定义类继承UICollectionViewFlowLayout,需要重写的方法:

//collectview第一次布局的时候调用
//collectView刷新(reload)的时候会再次调用
//子类必须要调用[super prepareLayout]
 - (void)prepareLayout;

 //根据指定rect,返回该rect区域内cell的相关信息,UICollectionViewLayoutAttributes -> cell的相关信息(frame、center、size、transform3D、bounds、transform等相关信息)
 - (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect;

//在滚动的时候是否允许刷新布局,默认为No
 - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds;
 //当手指抬起的时候调用,确定最终偏移量
 - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity;
 //子类必须要重写此方法,计算内容范围,返回collectView的内容区域
 - (CGSize)collectionViewContentSize;

实现如下图的一个自定义layout布局:
这里写图片描述

自定义Layout:

//不需要处理
 - (void)prepareLayout
{
    [super prepareLayout];
}
//不需要处理,直接调用super返回内容范围
- (CGSize)collectionViewContentSize
{
    return [super collectionViewContentSize];
}
- (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{
    //获取当前显示区域self.collectionView.bounds内的cell的布局
    NSArray *attrs = [super layoutAttributesForElementsInRect:self.collectionView.bounds];
    for (UICollectionViewLayoutAttributes *attr in attrs) {
        //对应其他特效可在此处处理
        CGFloat space = fabs((attr.center.x - self.collectionView.contentOffset.x) - self.collectionView.bounds.size.width / 2);
        //计算缩放比例
        CGFloat scale = 1 - space / (self.collectionView.bounds.size.width * 0.5) * 0.3;
        attr.transform = CGAffineTransformMakeScale(scale, scale);
    }
    return attrs;
}

//在滚动的时候允许刷新布局
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
    return YES;
}
//确定最终偏移量,定位cell显示居中
 - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
    //1. 获取UICollectionView停止滚动时的可视范围
    CGRect contentFrame;
    contentFrame.size = self.collectionView.frame.size;
    contentFrame.origin = proposedContentOffset;
    //获取可视范围内的cell
    NSArray *array = [super layoutAttributesForElementsInRect:contentFrame];

    //2. 计算在可视范围的距离中心线最近的Item
    CGFloat minCenterX = MAXFLOAT;
    //中心线
    CGFloat collectionViewCenterX = proposedContentOffset.x + self.collectionView.frame.size.width * 0.5;
    for (UICollectionViewLayoutAttributes *attrs in array) {
        CGFloat space = attrs.center.x - collectionViewCenterX;
        if(fabs(space) < fabs(minCenterX)){
            minCenterX = attrs.center.x - collectionViewCenterX;
        }
    }
    //3. 更新ContentOffset,则正好将Item居中显示
    return CGPointMake(proposedContentOffset.x + minCenterX, proposedContentOffset.y);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Log4j2是一个灵活的日志框架,允许用户自定义日志输出格式(layout)。以下是自定义Log4j2 layout的步骤: 1. 创建自定义layout类,该类应继承AbstractStringLayout,并实现toSerializable方法。该方法接受一个LogEvent对象,将其转换为字符串格式并返回。 示例代码如下: ```java @Plugin(name = "CustomLayout", category = Node.CATEGORY, elementType = Layout.ELEMENT_TYPE, printObject = true) public class CustomLayout extends AbstractStringLayout { protected CustomLayout() { super(StandardCharsets.UTF_8); } public String toSerializable(LogEvent event) { // 自定义日志输出格式的实现代码 return null; } @PluginFactory public static CustomLayout createLayout(@PluginAttribute(value = "pattern") String pattern) { return new CustomLayout(); } } ``` 2. 在log4j2.xml文件中添加自定义layout的配置,例如: ```xml <Configuration status="INFO"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <CustomLayout/> </Console> </Appenders> <Loggers> <Root level="debug"> <AppenderRef ref="Console"/> </Root> </Loggers> </Configuration> ``` 在以上配置中,我们将自定义layout作为Console appender的子元素,并命名为CustomLayout。 3. 在代码中使用自定义layout,例如: ```java private static final Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME); public static void main(String[] args) { logger.info("Hello, world!"); } ``` 以上是自定义Log4j2 layout的简单步骤,您可以根据实际需求自定义不同的layout,输出不同的日志格式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值