微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

iOS UICollectionViewCell 可调整大小的虚线边框 代码问题

如何解决iOS UICollectionViewCell 可调整大小的虚线边框 代码问题

我有一个 UICollectionView,其中一些单元格应该有一个虚线边框,其中一些应该有一个实心边框。此外,根据数据模型中存在的内容,单元格的大小可能会有所不同。

我遇到的问题是我无法使虚线边框与集合视图单元格的大小相同,而且单元格大小可以根据内容更改。但基本上,单元格应该有虚线边框或实心边框。实心边框很容易调整到正确的大小。

这是它现在的样子的图片。虚线边框涂成绿色只是为了更容易看到。

rendered view

这是视图层次结构调试视图。这里有两个虚线边框,因为我一直在试验。绿色边框是 UICollectionViewCell 根层上的一个子层。灰色边框是单独视图的子层,该视图是集合视图单元格的 contentView 属性的子视图。

view debugger

代码

方法 1 - 添加带有子层的专用视图

这里我想添加一个带有虚线边框的 UIView 子类。然后,当我需要显示虚线边框或隐藏虚线边框时,我只需相应地设置视图的 hidden 属性。这工作正常,除了我无法调整虚线边框子层的大小。

视图正在根据 AutoLayout 约束调整为正确的宽度和高度,如上面的视图层次结构调试器屏幕截图所示。但是子图层仍然是原始大小(大约 50px x 50px,我猜它来自 UICollectionView,因为我没有在任何地方指定该大小)。

对于这个实现,我有一个名为 MyResizableSublayerView自定义 UIView 子类。它覆盖 layoutSublayersOfLayer 来处理子层的大小调整,或者至少这是应该发生的事情,但显然它不起作用。

但随后在集合视图单元格中使用 MyResizableSublayerView 类将虚线边框添加到视图层次结构中。

MyResizableSublayerView
@interface MyResizableSublayerView : UIView

@property (strong,nonatomic) CAShapeLayer *borderLayer;

+ (instancetype)viewWithBorderSublayer:(CAShapeLayer *)shapeLayer;

@end




@implementation MyResizableSublayerView

+ (instancetype)viewWithBorderSublayer:(CAShapeLayer *)shapeLayer {
    CIResizableSublayerView *view = [[MyResizableSublayerView alloc] init];
    view.borderLayer = shapeLayer;
    return view;
}

- (void)setBorderLayer:(CAShapeLayer *)borderLayer {
    if (self->_borderLayer) {
        [self->_borderLayer removeFromSuperlayer];
    }
    
    self->_borderLayer = borderLayer;
    [self.layer addSublayer:self->_borderLayer];
}

- (void)layoutSublayersOfLayer:(CALayer *)layer {
    [super layoutSublayersOfLayer:layer];
    self.borderLayer.frame = layer.bounds;
}


@end
MyCollectionViewCell
@interface MyCollectionViewCell ()

@property (strong,nonatomic) MyResizableSublayerView *unavailableBorderView;

@end



@implementation MyCollectionViewCell

- (instancetype)init {
    return [self initWithFrame:CGRectZero];
}

- (instancetype)initWithCoder:(NSCoder *)coder {
    if (self = [super initWithCoder:coder]) {
        [self initialize];
    }
    return self;
}

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        [self initialize];
    }
    return self;
}

- (void)initialize {
    self.contentView.layer.cornerRadius = 4.0f;
    self.contentView.layer.borderWidth = 1.0f;

    //... add other subviews
    [self.contentView addSubview:self.unavailableBorderView];
    
    [NSLayoutConstraint activateConstraints:@[
        [self.contentView.widthAnchor constraintLessthanorEqualToConstant:250.0],[self.contentView.widthAnchor constraintGreaterThanorEqualToConstant:100.0],[self.unavailableBorderView.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor],[self.unavailableBorderView.topAnchor constraintEqualToAnchor:self.contentView.topAnchor],[self.unavailableBorderView.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor],[self.unavailableBorderView.bottomAnchor constraintEqualToAnchor:self.contentView.bottomAnchor],//... constraints for other views
    ]];
}

- (MyResizableSublayerView *)unavailableBorderView {
    if (!self->_unavailableBorderView) {
        CAShapeLayer *layer = [CAShapeLayer layer];
        layer.strokeColor = [UIColor colorWithRed:0xE0/255.0 green:0xE0/255.0 blue:0xE0/255.0 alpha:1.0].CGColor;
        layer.linewidth = 4.0;
        layer.lineJoin = kCALineJoinRound;
        layer.fillColor = [UIColor clearColor].CGColor;
        layer.lineDashPattern = @[@4,@4];
        layer.frame = self.contentView.bounds;
        layer.path = [UIBezierPath bezierPathWithRoundedRect:self.contentView.bounds cornerRadius:self.contentView.layer.cornerRadius].CGPath;

        self->_unavailableBorderView = [MyResizableSublayerView viewWithBorderSublayer:layer];
        self->_unavailableBorderView.translatesAutoresizingMaskIntoConstraints = NO;
        self->_unavailableBorderView.layer.cornerRadius = self.contentView.layer.cornerRadius;
        self->_unavailableBorderView.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.0];
    }
    return self->_unavailableBorderView;
}

//... more logic

@end

方法 2 - 直接添加到 UICollectionViewCell

对于这种方法,我将 CAShapeLayer 直接添加到 UICollectionViewCell,然后覆盖 layoutSublayersOfLayer 以尝试调整虚线边框子层的大小,但这也不起作用。

@interface MyCollectionViewCell ()

@property (strong,nonatomic) CAShapeLayer *unavailableBorderLayer;

@end



@implementation MyCollectionViewCell

- (instancetype)init {
    return [self initWithFrame:CGRectZero];
}

- (instancetype)initWithCoder:(NSCoder *)coder {
    if (self = [super initWithCoder:coder]) {
        [self initialize];
    }
    return self;
}

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        [self initialize];
    }
    return self;
}

- (void)initialize {
    self.contentView.layer.cornerRadius = 4.0f;
    self.contentView.layer.borderWidth = 1.0f;

    //... add other subviews
    
    [NSLayoutConstraint activateConstraints:@[
        [self.contentView.widthAnchor constraintLessthanorEqualToConstant:250.0],//... constraints for other views
    ]];
    
    
    CAShapeLayer *layer = [CAShapeLayer layer];
    layer.strokeColor = [UIColor greenColor].CGColor;
    layer.linewidth = 2.0;
    layer.lineJoin = kCALineJoinRound;
    layer.fillColor = [UIColor clearColor].CGColor;
    layer.lineDashPattern = @[@4,@4];
    layer.frame = self.contentView.bounds;
    layer.path = [UIBezierPath bezierPathWithRoundedRect:self.contentView.bounds cornerRadius:self.contentView.layer.cornerRadius].CGPath;
    self->_unavailableBorderLayer = layer;
    [self.layer addSublayer:self->_unavailableBorderLayer];
}

- (void)layoutSublayersOfLayer:(CALayer *)layer {
    [super layoutSublayersOfLayer:layer];
    self.unavailableBorderLayer.frame = self.bounds;
}

//... more logic

@end

问题

我对此有几个问题。

  1. 我的代码不允许将虚线边框调整为与集合视图单元格大小相同的代码有什么问题?
  2. 哪种方法是向集合视图单元格添加虚线边框的最佳方法。或者有没有比我在这里列出的方法更好的方法?同样,我的目标是能够显示或隐藏虚线边框,并使其与动态调整大小的集合视图单元格大小相同。

解决方法

不太清楚您对内容视图的约束做了什么……但是,如果您获得了所需的布局,除了虚线边框,请尝试一下。

首先,不要使用 layoutSublayersOfLayer,使用:

- (void)layoutSubviews {
    [super layoutSubviews];
    _unavailableBorderLayer.frame = self.bounds;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。