UITableViewCell使用UIBezierPath时自动布局宽度不起作用

6
我在使用UIBezierPath时,遇到了UITableViewCell中自动布局约束的问题。我的单元格无法达到全屏宽度,您可以看到图像1和图像2之间的差异。在图像2中,我没有添加圆角。

图像1 With UIBezierPath

图像2 Without UIBezierPath

以前,在UIView中我也遇到了UIBezierPath同样的问题(您可以看到前两个带有“0”的UIView)。我使用的解决方法是像下面这样在viewDidLayoutSubviews中掩盖圆角:

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    [self.view layoutIfNeeded];

    UIView *container =  (UIView *)[self.view viewWithTag:100101];
    [container setBackgroundColor:[UIColor colorWithHexString:@"ffffff"]];
    [self setMaskTo:container byRoundingCorners:UIRectCornerAllCorners];
}

但是现在我被困在UITableViewCell中,因为我无法在viewDidLayoutSubviews中添加圆角。我的代码如下:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"myData";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    MyWClass *w = [_wData objectAtIndex:indexPath.row];

    UIView *container = (UIView *) [cell viewWithTag:200001];
    [container setBackgroundColor:[UIColor colorWithHexString:w.bgColor]];
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:container.layer.bounds
                                                   byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight
                                                         cornerRadii:CGSizeMake(10.0, 10.0)];
    CAShapeLayer *maskLayer = [CAShapeLayer layer];
    maskLayer.frame = container.bounds;
    maskLayer.path = maskPath.CGPath;
    container.layer.mask = maskLayer;

    [cell setBackgroundColor:[UIColor colorWithHexString:@"#efeff4"]];
    cell.layer.masksToBounds = NO;
    cell.layer.shadowOpacity = 1.0;
    cell.layer.shadowOffset = CGSizeMake(0, 2);
    cell.layer.shadowColor = [UIColor colorWithHexString:@"#e4e4e8"].CGColor;
    cell.layer.shadowRadius = 0;

    return cell;
}

我尝试添加 [cell.contentView layoutIfNeeded]; 但仍然没有变化。

任何帮助都将不胜感激。


@0yeoj 尝试了,仍然不起作用。 - skycrew
你最终解决了这个问题吗?我也遇到了同样的问题! - Erik
@Erik 是的。我重新调整了视图和约束,因为之前它们位于 UiView -> UiView 中。所以我删除了第二个 UiView,然后它就可以运行了。 - skycrew
@skycrew,我也遇到了这个问题,你能否详细解释一下解决方案? - Tulon
@skycrew,谢谢您的回复。在我的情况下,我必须将使用[UIBezierPath bezierPathWithRoundedRect创建的双侧圆角代码从- (void)awakeFromNib方法中移除到- (void)drawRect:(CGRect)rect方法中的customTableViewCell,现在已经可以正常工作了。 :) - Tulon
显示剩余6条评论
3个回答

0

兄弟,把你的贝塞尔路径初始化放在ViewDidLoad或ViewDidAppear里面,在cellForRowAtindexPath方法中进行属性设置。

像这样:

let maskLayer = CAShapeLayer.init()

override func viewDidLoad() {
        super.viewDidLoad()

        
        self.maskLayer.path = UIBezierPath(roundedRect: self.tableView.layer.bounds, byRoundingCorners: [UIRectCorner.topLeft, UIRectCorner.topRight], cornerRadii: CGSize.init(width: 26.0, height: 26.0)).cgPath

    }

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
      let cell = tableView .dequeueReusableCell(withIdentifier: "cellButtons",         for: indexPath)
            
            
       cell.layer.mask = self.maskLayer
       return cell
}

0
以下逻辑对我有效:
将您的UIView宽度设置为单元格宽度。
例如:container.frame.size.width = cell.frame.size.width

0
尝试在主线程中使用UIBezierPath(请参见以下的Swift 5解决方案)。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
             {
                let Cell: MyTableViewCell = tableView.dequeueReusableCell(withIdentifier: "MyTableViewCell") as! MyTableViewCell
                Cell.selectionStyle = .none
                DispatchQueue.main.async {
                    let maskPath = UIBezierPath(roundedRect: Cell.contentView.bounds,
                                                       byRoundingCorners: [.topLeft, .topRight],
                                                       cornerRadii: CGSize(width: 10, height: 10))
                    let shape = CAShapeLayer()
                    shape.path = maskPath.cgPath
                    Cell.contentView.layer.mask = shape
                           
                }
                return Cell
             }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接