简体   繁体   English

如何消除 UITableView 左侧的边距,而不会在右侧产生间隙?

[英]How do I eliminate the margin on the left side of a UITableView, without creating a gap on the right?

I am targeting iOS 7 and 8, and I want to eliminate the margin appearing on the left side of the images in this UITableView below.我的目标是 iOS 7 和 8,我想消除下面这个 UITableView 中图像左侧出现的边距。 I would even be willing to accept a solution that only works on iOS 8 if the solution is simple/elegant.如果解决方案简单/优雅,我什至愿意接受仅适用于 iOS 8 的解决方案。 (I would just live with the margin on iOS 7 as it dies out). (我只会忍受 iOS 7 的余量,因为它已经消失了)。

This is what I would like it to look like:这就是我希望它的样子:

I have read through many similar questions on Stack Overflow ( such as this one ), or ones specific to grouped UITableViews ( here and here ), but cannot seem to get any to work quite right.我已经阅读了许多关于 Stack Overflow 的类似问题( 例如这个),或者特定于分组 UITableViews 的问题( 这里这里),但似乎无法让任何问题正常工作。

For example, if I try to solve the problem using contentInset (a common answer on SO):例如,如果我尝试使用 contentInset(SO 上的常见答案)解决问题:

- (void) viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    self.tableView.contentInset = UIEdgeInsetsMake(self.tableView.contentInset.top, -16, self.tableView.contentInset.bottom, self.tableView.contentInset.right);
    self.tableView.separatorInset = UIEdgeInsetsMake(0, 33, 0, 0);
}

Then I end up with the gap on the right side of the tableview:然后我最终得到了 tableview 右侧的间隙:

I get why it's happening, the entire tableview is just shifted over, as seen in the Debug View Hierarchy screen:我明白为什么会发生这种情况,整个 tableview 只是移动了,如 Debug View Hierarchy 屏幕中所示:

However, I've tried adjusting the tableView frame size to compensate, but it never seems to work correctly.但是,我尝试调整 tableView 框架大小以进行补偿,但它似乎永远无法正常工作。 Plus this seems hacky;另外,这看起来很笨拙; there must be a better way.一定会有更好的办法。

For the record, here's my cellForRowAtIndexPath:作为记录,这是我的 cellForRowAtIndexPath:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // get a cell that we can use]
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"VideoCell" forIndexPath:indexPath];

    cell.textLabel.numberOfLines = 0;

    cell.selectedBackgroundView = selectionColor;

    cell.accessoryView = [[UIImageView alloc] initWithImage:[PTStyleKit imageOfArrow]];

    // Create the attributed string (text + attributes)
    NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithString:[videos objectAtIndex:indexPath.row] attributes:attributes];

    // Set it in our UILabel and we are done!
    [cell.textLabel setAttributedText:attributedText];

    NSString* filename = [filenames objectAtIndex:indexPath.row];
    if (filename == nil)
    {
        filename = cell.textLabel.text;
    }

    UIImage *imageOne = [UIImage imageNamed:[NSString stringWithFormat:@"medium-%@", filename]];
    cell.imageView.image = [UIImage imageWithCGImage:imageOne.CGImage scale:imageOne.size.height/44 orientation:imageOne.imageOrientation];

    return cell;
}

It appears the only solution I can find is to subclass UITableViewCell, and then override the layout of the imageView and textLabel.看来我能找到的唯一解决方案是继承 UITableViewCell,然后覆盖 imageView 和 textLabel 的布局。 While researching this approach I found this related answer .在研究这种方法时,我发现了这个相关的答案 (I guess I didn't realize this whole time I was searching for tableview behavior that was originally in iOS 6.) (我想我一直没有意识到我一直在寻找最初在 iOS 6 中的 tableview 行为。)

My subclass has this one and only overridden method:我的子类有这个唯一的重写方法:

- (void)layoutSubviews
{
    [super layoutSubviews];

    // Slide image to the left, eliminating gutter
    self.imageView.frame = CGRectMake(0, 0, self.imageView.frame.size.width, self.imageView.frame.size.height);

    // Slide text label to the left, and extend width by additional
    // space gained by eliminating the left-most gutter
    self.textLabel.frame = CGRectMake((self.imageView.frame.origin.x + self.imageView.frame.size.width + 15), 0, self.textLabel.frame.size.width + 15, self.textLabel.frame.size.height);
}

My resulting tableview now looks exactly the way I want:我生成的 tableview 现在看起来完全符合我的要求:

enter image description here

Set a clear background to your table view and set the contentInset property.为您的表格视图设置清晰的背景并设置contentInset属性。

Code:代码:

tableView.contentInset = UIEdgeInsetsMake(0, -15, 0, 0);
tableView.backgroundColor = [UIColor clearColor];

but increase the width of the table view by 15 pixels by setting the frame.但是通过设置框架将表格视图的宽度增加 15 个像素。

1. On iOS 13 1. 在 iOS 13 上

The key is, together with other things, to set cell.contentView.layoutMargins to .zero :关键是,连同其他事情,将cell.contentView.layoutMargins设置为.zero

/// view controller
...
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "identifier")
tableView.separatorInset = .zero
tableView.directionalLayoutMargins = .zero
tableView.layoutMargins = .zero
...

/// data source
...
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "identifier")!
    cell.textLabel?.text = "Text"
    cell.directionalLayoutMargins = .zero
    cell.layoutMargins = .zero
    cell.contentView.directionalLayoutMargins = .zero
    cell.contentView.layoutMargins = .zero
    return cell
}

If you are utilizing UITableViewController, in addition to all the above you also need to apply this:如果您正在使用 UITableViewController,除了上述所有内容外,您还需要应用以下内容:

tableViewController.viewRespectsSystemMinimumLayoutMargins = false

2. On iOS 12 and lower 2. 在 iOS 12 及更低版本上

It seems that there is no way to use layoutMargins etc. to place the standard UITableViewCell.textLabel to zero offset in relation to the table.似乎没有办法使用 layoutMargins 等将标准 UITableViewCell.textLabel 放置到与表格相关的零偏移量。 The easiest and the only way I found is to subclass the cell and override layoutSubviews like this:我发现的最简单也是唯一的方法是子类化单元格并像这样覆盖layoutSubviews

class MyCell: UITableViewCell {
    ...
    override func layoutSubviews() {
        super.layoutSubviews()
        let leading = contentView.directionalLayoutMargins.leading
        textLabel?.frame.origin.x = leading
    }
    ...
}

And of course you need the layout margins to be properly set for that to work当然,您需要正确设置布局边距才能使其工作

I think I just came up with an easy solution, which I found over stackoverflow, one way to adjust cell margins, add this method in you code我想我只是想出了一个简单的解决方案,我在 stackoverflow 上找到了它,一种调整单元格边距的方法,在你的代码中添加这个方法

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
    if ([tableView respondsToSelector:@selector(setSeparatorInset:)]) {
        [tableView setSeparatorInset:UIEdgeInsetsZero];
    }
    if ([tableView respondsToSelector:@selector(setLayoutMargins:)]) {
    [tableView setLayoutMargins:UIEdgeInsetsZero];
    }
    if ([tableView respondsToSelector:@selector(setLayoutMargins:)]) {
    cell.preservesSuperviewLayoutMargins = NO;
    [cell setLayoutMargins:UIEdgeInsetsZero];
    }
    if ([cell respondsToSelector:@selector(setSeparatorInset:)]){
    [cell setSeparatorInset:UIEdgeInsetsZero];
    }
}

This solves my problem.这解决了我的问题。

Swift 3 and 4斯威夫特 3 和 4

public func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    if cell.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
        cell.separatorInset = .zero
    }
    if (cell.responds(to: #selector(setter: UIView.preservesSuperviewLayoutMargins))) {
        cell.preservesSuperviewLayoutMargins = false
    }

    if (cell.responds(to: #selector(setter: UIView.layoutMargins))) {
        cell.layoutMargins = UIEdgeInsets.zero
    }
    if tableView.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
        tableView.separatorInset = .zero
    }

}

iOS 8+ iOS 8+

In your table view:在您的表格视图中:

table.separatorInset = UIEdgeInsets.zero     // or UIEdgeInsetsZero

You may also need:您可能还需要:

table.layoutMargins = UIEdgeInsets.zero

Credit to https://stackoverflow.com/a/30640595/385273 .归功于https://stackoverflow.com/a/30640595/385273

You can try;你可以试试;

[cell.textLabel setTranslatesAutoresizingMaskIntoConstraints:false];
[cell.textLabel.centerYAnchor constraintEqualToAnchor:cell.contentView.centerYAnchor].active = YES;
[cell.textLabel.leadingAnchor constraintEqualToAnchor:cell.contentView.leadingAnchor constant:22].active = YES; 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM