iOS 将 UITableViewCell 标签与披露指示器居中

iOS Centring UITableViewCell label with disclosure indicator

我正在寻找一种在 table 单元格中输入标签的方法,该单元格也具有披露指示符。我现在遇到的问题是,在计算标签的位置时,披露指示符似乎被忽略了

这是一张照片:

正如您所见,标签位于单元格左侧和指示器左侧之间的区域中心,如果它位于单元格中心,它将位于导航栏标题下方。

感谢任何帮助谢谢

来自情节提要

好的,首先解释一下你的问题。它与 UITableViewCell 解剖学 有关。对于 anatomy,我的意思是 UITableViewCell 对你来说只是一个 container 对于另一个 container,也就是 contentView(你也可以在故事板中看到这个)。

当您在 Storyboards 中操作时,您只是在 contentView 上操作,而不是在实际的 UITableViewCell 上操作。因此,当您使用 AutoLayoutAutoLayout[=] 将 UILabel 设置为 以 X 轴为中心 43=] 将始终尝试将其置于 contentView 的中心,而不是在外部容器(即 UITableViewCell)中。然后,当您将 披露指示符 添加到 UITableViewCell 时,contentView 的宽度会自动缩小,因为单元格会为披露生成 space指标,并希望阻止您在为披露指标保留的正确区域添加 UI 元素。

现在,您有几个选择:

  1. 您可以直接编辑约束并向其添加常量(该常量必须与删除指示器时标签移动的值相同)

  1. 不要使用默认的披露指示符(即不要勾选 Storyboards 中的复选框),只需添加 UIImageView 和看起来相同的图像。

正如您已经注意到的,添加 'UITableViewCellAccessoryDisclosureIndicator' 会缩小分配给单元格的 contentView 的 space。另一种不需要自定义指示器或猜测偏移量的解决方案是以编程方式将 UILabel 添加到单元格的根视图,而不是 contentView。例如:

@property UILabel *label;

// ...

- (void)layoutSubviews
{
    [super layoutSubviews];

    [self.label removeFromSuperview];
    self.label = [[UILabel alloc] init];
    self.label.text = @"Motorsport";
    [self.label sizeToFit];
    label.center = CGPointMake(self.center.x, self.size.height/2);
    [self addSubview:self.label];
}

要不受任何常量的约束,您可以计算 framecontentView.frame 的宽度差异。所以首先像这样创建一个出口集合:

@property (strong, nonatomic) IBOutletCollection(NSLayoutConstraint) NSArray *centerConstraintsToOffset;

然后将要在单元格中水平居中的中心约束添加到该出口集合:

最后将此代码添加到您的单元格中:

override func layoutSubviews() {
    super.layoutSubviews()
    for constraint in centerConstraintsToOffset {
        constraint.constant = (frame.size.width - contentView.frame.size.width) / 2.0
    }
}

这也让您可以随时随地灵活地添加或移除电池配件,并且您的视图将始终完美居中对齐。即使您完全移除配件。

Pavel 的回答为我解决了这个问题。在按照他的回答演示创建 IBOutlet 集合后,这里是他为 Swift 3:

编辑的代码示例
override func layoutSubviews() {
    super.layoutSubviews()
    for constraint: NSLayoutConstraint in self.centerConstraintsToOffset {
        constraint.constant = (frame.size.width - contentView.frame.size.width) / 2.0
    }

}