滚动关闭然后重新打开后,表视图单元格只能正确遮罩

Pet*_*vin 14 uitableview calayer ios

我正在调用一个表视图单元格tableView:cellForIndexPath,但是在单元格滚动然后重新打开之前,修改不会出现.我意识到我可以修改.xib文件或者可以分配/初始化一个单元而不是调用dequeue,但我想了解发生了什么.

这些变化涉及掩盖细胞以实现圆角底角.如果我设置角半径(即cell.layer.cornerRadius = ...),使所有角都圆,我没有看到问题.

更新:

我最初没有发布代码,因为它是专有的,涉及很多复杂性,我认为在没有任何细节的情况下问题是合理的.然而,根据响应,这里是一个显示问题的简化片段,唯一的变化是实际的小区标识符.我还更新了描述/问题以简化方案.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TheCorrectCellIdentifier" forIndexPath:indexPath];
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:cell.bounds byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight                                                         cornerRadii:CGSizeMake(4., 4.)];
    CAShapeLayer *maskLayer = [CAShapeLayer layer];
    maskLayer.frame = cell.bounds;
    maskLayer.path = maskPath.CGPath;
    cell.layer.masksToBounds = YES;
    cell.layer.mask = maskLayer;
    return cell;
}
Run Code Online (Sandbox Code Playgroud)

tec*_*erd 26

你的代码工作正常.但如果你仍然面临角半径问题,cellForRowAtIndexPath:那么试试吧willDisplayCell:.我尝试了两种方法并且工作正常.

willDisplayCell:

告诉委托表视图是否要为特定行绘制单元格.

表视图在使用单元格绘制行之前将此消息发送到其委托,从而允许委托在显示单元格对象之前对其进行自定义.此方法为委托提供了覆盖表视图前面设置的基于状态的属性的机会,例如选择和背景颜色.委托返回后,表视图仅设置alpha和frame属性,然后仅在向行或向外滑动时为行设置动画.这是我的代码.

据我所知,Apple提供了两套不同的方法(Protocol)来命名UITableViewDataSourceUITableViewDelegate管理UITableView.

UITableViewDataSource:数据源为单元格提供实际数据以填充详细信息.

UITableViewDelegate:在另一端,委托负责提供有关tableview的可视布局的信息并处理用户交互.

因此,结论是DataSource主要处理表的内容(Data)和Delegate处理tableview组件的表示和交互.

让我们来看看我们处理TableView.

我们都非常个人使用UITableViewDataSource方法tableView:cellForRowAtIndexPath:,这个方法负责创建或重用有效的UITableViewCell,并为每个索引路径提供适当的详细信息.我们倾向于在此方法中进行单元布局配置和UI修改.

tableView:cellForRowAtIndexPath:调用之后,系统执行布局配置,然后tableView:willDisplayCell:forRowAtIndexPath:在单元格在屏幕上显示之前调用方法.

所以我们可以使用这个方法来查看Tableview单元格的视图配置(可能是,Apple为我们提出了这个方法!!!).

因此,我逐渐倾向于使用tableView:cellForRowAtIndexPath:创建单元格和左单元UI配置任务的tableView:willDisplayCell:forRowAtIndexPath: 方法.

涂上面膜 willDisplayCell:

 -(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{

    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:cell.bounds byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight                                                         cornerRadii:CGSizeMake(10.0, 10.0)];
    CAShapeLayer *maskLayer = [CAShapeLayer layer];
    maskLayer.frame = cell.bounds;
    maskLayer.path = maskPath.CGPath;
    cell.layer.masksToBounds = YES;
    cell.layer.mask = maskLayer;
    }
Run Code Online (Sandbox Code Playgroud)

这是我的 cellForRowAtIndexPath:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

static NSString *identifier = @"cell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];

cell.textLabel.text = [NSString stringWithFormat:@"Row : %ld ", (long)indexPath.section];
return cell;
}
Run Code Online (Sandbox Code Playgroud)

输出:

在此输入图像描述

  • @OlDor:Peter Alvin明确表示“我想了解发生了什么事”。他没有要求解决方案,而是要求作出解释,到目前为止还没有放弃。 (2认同)

Meh*_*kar 6

重新加载tableView in viewDidAppearviewDidLayoutSubviews方法将使其工作.

-(void)viewDidAppear:(BOOL)animated
{
 [super viewDidAppear:animated];
 [self.tableView reloadData];
}
Run Code Online (Sandbox Code Playgroud)

原因为什么你的代码没有奏效:其实,按次生命周期,该方法被调用于以下方式,init,loadView,viewDidLoad,viewWillAppear,viewWillLayoutSubviews(被称为不止一次), viewDidLayoutSubviews(称为多时间),最后viewDidAppear.

现在,实际上tableview被加载到方法中viewDidLoad,而你应用的自动布局约束将在该方法之后应用.这就是为什么,它没有显示出预期的结果.在应用自动布局约束后再次重新加载使其工作.多数民众赞成以上代码肯定会奏效.

还有一点要注意:在故事板中,如果你使用iphone 5大小设计了你的viewController,然后如果你在iphone 5中运行代码,那么无需重新加载它,它必须工作,但是如果你在任何其他大小的viewController中运行它,然后它将无法正常工作.其背后的原因是,viewDidLoad方法被调用,然后任何视图都具有其故事板中的大小.

如果您有任何疑问,请告诉我


小智 5

Approach - 1 reload cell in viewWillAppear with delay mathod

func viewWillAppear(_ animated: Bool)
{ 
   super.viewWillAppear(animated) 
   DispatchQueue.main.asyncAfter(deadline: .now() + 0.10, execute: {
        self.tableView.reloadData() }) 
}

Approach - 2 Draw in GCD

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TheCorrectCellIdentifier" forIndexPath:indexPath];

dispatch_async(dispatch_get_main_queue(), ^{

    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:cell.bounds byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight                                                         cornerRadii:CGSizeMake(4., 4.)];
    CAShapeLayer *maskLayer = [CAShapeLayer layer];
    maskLayer.frame = cell.bounds;
    maskLayer.path = maskPath.CGPath;
    cell.layer.masksToBounds = YES;
    cell.layer.mask = maskLayer;

});
    return cell;
}
Run Code Online (Sandbox Code Playgroud)