【问题标题】:Drawing dotted line between the cells of UICollectionView在 UICollectionView 的单元格之间绘制虚线
【发布时间】:2016-06-10 11:06:08
【问题描述】:

我必须实现这样的目标(请查看附加的屏幕截图)。我想到的最好的解决方案是UICollectionView。我沿着单元格创建了圆形边框并在单元格上放置了一个按钮。现在对于虚线直线,我使用了CAShapeLayerBezierPath,并将图层添加到我的collectionview background with background color set to clear color。问题来了,我没有看到任何虚线。这是我尝试过的。现在我有几个问题。回答时请把我当作初学者。

1) 为什么我的台词没有显示。
2) 如何计算两个单元格之间的宽度,我现在正在设置一个随机数。
3)有没有其他方法可以更有效地解决这个用例。

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
UIBezierPath *borderPath;
CGFloat borderWidth;

KKCollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"testCell" forIndexPath:indexPath];
borderPath = [UIBezierPath bezierPath];

[borderPath moveToPoint:CGPointMake(cell.frame.origin.x + cell.frame.size.width -1 , cell.frame.origin.y + 2)];
[borderPath addLineToPoint:CGPointMake(cell.frame.origin.x + cell.frame.size.width + 50,  cell.frame.origin.y +2)];
borderWidth = 1.0;
[self dottedLineWithPath:borderPath withborderWidth:borderWidth];
return cell; 
}

/** creating dotted line **/

- (void)dottedLineWithPath:(UIBezierPath *)path withborderWidth:(CGFloat)lineWidth
{
CAShapeLayer *shapelayer = [CAShapeLayer layer];
shapelayer.strokeStart = 0.0;
shapelayer.strokeColor = [UIColor blackColor].CGColor;
shapelayer.lineWidth = borderWidth;
shapelayer.lineJoin = kCALineJoinRound;
shapelayer.lineDashPattern = [NSArray arrayWithObjects:[NSNumber numberWithInt:1],[NSNumber numberWithInt:2 ], nil];
shapelayer.path = path.CGPath;

[self.milestoneCollection.backgroundView.layer addSublayer:shapelayer];
  }

这是我到目前为止所取得的成就.

【问题讨论】:

  • 集合视图为您提供什么好处?网格布局?
  • 是的,这就是我使用它的原因。原因可能是将来圈数可能会增加或减少。所以只是为了避免返工。无论如何你的建议是什么。我愿意接受任何其他可能性。
  • 按照复杂性和功能的顺序:首先,为所有图形使用图像并覆盖文本。然后使用布置在超级视图视图上的视图。然后是带有附件视图的集合视图。
  • 看起来有点乏味,不是什么简单的方法:)
  • 图像是一种简单的方法 - 编程并不容易,如果你只想简单地解决问题,那么你就做错了

标签: ios objective-c uicollectionview core-graphics


【解决方案1】:

您好,这是使用 UICollectionViewLayout 和绘图函数完成的。

在路径https://github.com/arunpkumar92/OrderStatusCollectionView上传的代码

- (void)reloadConnections{

    for (CAShapeLayer *shapelayer in self.connectionLines) {
        [shapelayer removeFromSuperlayer];
    }

    self.connectionLines = [NSMutableArray array];

    for (int i = 0; i <= (self.total-2); i++){
        NSArray *paths = [self pathForconnectionLineForIndexPath:i];
        for (UIBezierPath *path in paths) {
            UIColor *color = (self.currentLevel > i) ? [UIColor colorWithRed:0.078 green:0.557 blue:0.067 alpha:1.00] : [UIColor colorWithRed:0.957 green:0.659 blue:0.024 alpha:1.00];
            CAShapeLayer *shapelayer = [self drawdottedLineWithPath:path withborderWidth:1.0f withColor:color];
            [self.collectionView.layer addSublayer:shapelayer];
            [self.connectionLines addObject:shapelayer];
        }
    }

}

- (NSArray *)pathForconnectionLineForIndexPath:(int)index{
    NSMutableArray *paths = [NSMutableArray array];

    int row = index%self.noOfItems;
    int column = index/self.noOfItems;
    CGFloat cellWidth = self.view.frame.size.width/self.noOfItems;
    CGFloat cellHeight = self.view.frame.size.width/self.noOfItems;
    CGFloat connectionLength = cellHeight/2;

    CGFloat leftPadding;
    CGFloat topPadding;

    if (row != (self.noOfItems-1)) {
        leftPadding = cellWidth/4;
        topPadding = cellHeight/2;

        UIBezierPath *borderPath = [UIBezierPath bezierPath];
        CGFloat startX = (3*leftPadding)+(row*cellWidth);
        CGFloat startY = topPadding+(column*cellHeight);
        CGFloat endX = startX + connectionLength;
        CGFloat endY = startY;
        [borderPath moveToPoint:CGPointMake(startX , startY)];
        [borderPath addLineToPoint:CGPointMake(endX,  endY)];
        [self drawDirectionAt:CGPointMake((startX+(connectionLength/2)) , startY) isEnabled:(self.currentLevel > index) isRight:YES];
        [paths addObject:borderPath];

    }

    if ( (row == (self.noOfItems-1)) && (column%2 == 0) ) {
        leftPadding = cellWidth/2;
        topPadding = cellHeight/8;

        UIBezierPath *borderPath = [UIBezierPath bezierPath];
        CGFloat startX = leftPadding+(row*cellWidth);
        CGFloat startY = (7*topPadding)+(column*cellHeight);
        CGFloat endX = startX;
        CGFloat endY = startY + (2*topPadding);
        [borderPath moveToPoint:CGPointMake(startX , startY)];
        [borderPath addLineToPoint:CGPointMake(endX,  endY)];
        [self drawDirectionAt:CGPointMake(startX , (startY+topPadding)) isEnabled:(self.currentLevel > index) isRight:NO];
        [paths addObject:borderPath];

    }

    if ( (row == 0) && (column%2 != 0) ) {
        leftPadding = cellWidth/2;
        topPadding = cellHeight/8;

        UIBezierPath *borderPath = [UIBezierPath bezierPath];
        CGFloat startX = leftPadding+(row*cellWidth);
        CGFloat startY = (7*topPadding)+(column*cellHeight);
        CGFloat endX = startX;
        CGFloat endY = startY + (2*topPadding);
        [borderPath moveToPoint:CGPointMake(startX , startY)];
        [borderPath addLineToPoint:CGPointMake(endX,  endY)];
        [self drawDirectionAt:CGPointMake(startX , (startY+topPadding)) isEnabled:(self.currentLevel > index) isRight:NO];
        [paths addObject:borderPath];

    }

    return paths;
}

- (CAShapeLayer *)drawdottedLineWithPath:(UIBezierPath *)path withborderWidth:(CGFloat)lineWidth withColor: (UIColor *)color
{


    CAShapeLayer *shapelayer = [CAShapeLayer layer];
    shapelayer.strokeStart = 0.0;
    shapelayer.strokeColor = color.CGColor;
    shapelayer.lineWidth = lineWidth;
    shapelayer.lineJoin = kCALineJoinRound;
    shapelayer.lineDashPattern = [NSArray arrayWithObjects:[NSNumber numberWithInt:15],[NSNumber numberWithInt:10 ], nil];
    shapelayer.path = path.CGPath;

    return shapelayer;

}

- (void)drawDirectionAt:(CGPoint)point isEnabled:(BOOL)enabled isRight:(BOOL)isRight{
    NSString *imageName;
    imageName = isRight ? @"right-arrow" : @"down-arrow";
    imageName = [NSString stringWithFormat:@"%@-%@",imageName,(enabled ? @"enabled" : @"disabled")];

    CAShapeLayer* direction = [CAShapeLayer layer];
    direction.opacity = 1.0;
    direction.frame = CGRectMake(0, 0, 16, 16);
    direction.position = point;
    [direction setContents:(id)[[UIImage imageNamed: imageName] CGImage]];
    [self.connectionLines addObject:direction];
    [self.collectionView.layer addSublayer: direction];
}

【讨论】:

  • 为什么要投反对票???否决票的原因是什么。我无法在这里完整地解决代码。所以我添加了外部链接。
  • 为您的努力+1,我将在测试两个答案后添加赏金。现在,我正在移动,所以无法测试。
  • @KunalKumar 为什么你不接受答案,有什么问题吗?那么请添加评论
  • 无法在 iPhone 上运行,单元格正在折叠。使用单元格的大小和其他属性。
  • @KunalKumar :你应该管理。 :) 我刚刚为特定的解决方案做了一个示例 iPad 应用程序(非常粗糙)。点连接和流。
【解决方案2】:

为什么我的台词没有显示。

要让您的绘图可见,您必须将绘图代码直接添加到 UICollectionView 实例而不是它的 backgroundView 属性。

[self.milestoneCollection.layer addSublayer:shapelayer];

这 100% 有效。使用backgroundView 似乎是正确的做法,但他们可能会将其完全用于其他目的。我怀疑backgroundView 要么此时不可见(使用默认配置),要么完全忽略我们的更改请求。

如何计算两个单元格之间的宽度,我现在设置一个随机数。

-(void)getLineStartPoint:(CGPoint*)startPoint
             andEndPoint:(CGPoint*)endPoint
     fromCellAtIndexPath:(NSIndexPath*)fromIndexPath
       toCellAtIndexPath:(NSIndexPath*)toIndexPath
{
    UICollectionViewLayoutAttributes* fromAttributes =
    [self.milestoneCollection layoutAttributesForItemAtIndexPath:fromIndexPath];

    UICollectionViewLayoutAttributes* toAttributes =
    [self.milestoneCollection layoutAttributesForItemAtIndexPath:toIndexPath];

    *startPoint = fromAttributes.center;
    *endPoint = toAttributes.center;
}

UICollectionViewLayoutAttributes 是 100% 的特征,在特定的 indexPath 处包含有关 cells, headers, footers, decorationViews 的几何信息。为简单起见,我现在使用center。我相信您需要将您的逻辑与frame 属性一起使用。

有没有其他方法可以更有效地解决这个用例。

是的,总是有两种方法。

  • 完成它。
  • 完成正确

当然RIGHT会根据情况和可用时间而有所不同。

记住

  • 注意indexPath 的可用性,否则您很容易崩溃。这是一个最简单的守卫形式-

    NSInteger numberOfItems = [self collectionView:collectionView numberOfItemsInSection:indexPath.section];
    
    if(indexPath.item < numberOfItems-1)
    {
        CGPoint startPoint, endPoint;
        NSIndexPath* toIndexPath =
        [NSIndexPath indexPathForItem:indexPath.item+1 inSection:indexPath.section];
    
        [self getLineStartPoint:&startPoint
                    andEndPoint:&endPoint
            fromCellAtIndexPath:indexPath
              toCellAtIndexPath:toIndexPath];
    
        [borderPath moveToPoint:startPoint];
        [borderPath addLineToPoint:endPoint];
        borderWidth = 1.0;
        [self dottedLineWithPath:borderPath withborderWidth:borderWidth];
    }
    
  • 当您尝试滚动它时(如果需要),还会添加层/路径 每次创建单元格时(由于 多次添加层层次结构),你需要小心 这在重用细胞时。看看这个:-

这应该可以回答您的所有问题。祝你好运!

【讨论】:

  • 感谢您的回答,我会测试并更新您。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多