1. ホーム
  2. ios

[解決済み] iOS 8 UITableViewのセパレータインセット0が機能しない件

2022-03-15 06:58:08

質問

あるアプリで UITableView のセパレータインセットはカスタム値に設定されています - Right 00 . これは iOS 7.x しかし iOS 8.0 セパレーターインセットがデフォルトの 15 を右側に表示します。xibファイルでは、右側が 0 が、まだ正しく表示されません。

を削除するにはどうすればよいですか? UITableViewCell セパレータの余白について教えてください。

解決方法は?

iOS 8.0では、セルとテーブルビューにlayoutMarginsプロパティが導入されました。

このプロパティはiOS 7.0では利用できないので、割り当てる前に確認する必要があります!

簡単な方法は、@user3570727 が提案するように、セルをサブクラス化し、レイアウトのマージン プロパティをオーバーライドすることです。しかし、セーフエリアからマージンを継承するようなシステム動作は失われるので、以下の解決策はお勧めしません。

(ObjectiveC)

-(UIEdgeInsets)layoutMargins { 
     return UIEdgeInsetsZero // override any margins inc. safe area
}

(スイフト4.2)です。

override var layoutMargins: UIEdgeInsets { get { return .zero } set { } }

プロパティをオーバーライドしたくない場合、または条件付きで設定する必要がある場合は、このまま読み進めてください。


に加えて layoutMargins プロパティに加え、Appleは プロパティ を指定すると、テーブルビューのマージン設定がセルに継承されなくなります。このプロパティを設定すると、セルはテーブル・ビューとは独立して独自のマージンを設定できるようになります。これはオーバーライドと考えることができます。

このプロパティは preservesSuperviewLayoutMargins に設定し、それを NO を指定すると、そのセルの layoutMargin の設定を上書きすることができます。 layoutMargin は、TableViewに設定されています。これは時間の節約にもなりますし ( テーブルビューの設定を変更する必要がありません。 というように、より簡潔です。詳しい説明は、Mike Abdullahの回答を参照してください。

注:以下のものは セルレベルのマージン設定 Mike Abdullahの回答で表現されている通りです。セルに preservesSuperviewLayoutMargins=NO は、テーブルビューがセルの設定を上書きしないようにします。もし、テーブルビュー全体のマージンを一定にしたいのであれば、それに応じてコードを調整してください。

セルの余白を設定します。

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Remove seperator inset
    if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
           [cell setSeparatorInset:UIEdgeInsetsZero];
    }

    // Prevent the cell from inheriting the Table View's margin settings
    if ([cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)]) {
        [cell setPreservesSuperviewLayoutMargins:NO];
    }

    // Explictly set your cell's layout margins
    if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
        [cell setLayoutMargins:UIEdgeInsetsZero];
    }
}

Swift 4:

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    // Remove seperator inset
    if cell.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
        cell.separatorInset = .zero
    }
    // Prevent the cell from inheriting the Table View's margin settings
    if cell.responds(to: #selector(setter: UITableViewCell.preservesSuperviewLayoutMargins)) {
        cell.preservesSuperviewLayoutMargins = false
    }
    // Explictly set your cell's layout margins
    if cell.responds(to: #selector(setter: UITableViewCell.layoutMargins)) {
        cell.layoutMargins = .zero
    }
}

を設定します。 preservesSuperviewLayoutMargins プロパティをNOに設定します。 べきである テーブルビューがセルの余白を上書きするのを防ぐことができます。場合によっては、正しく機能しないこともあるようです。

すべて失敗した場合、テーブルビューのマージンをブルートフォースで変更することができます。

-(void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];

    // Force your tableview margins (this may be a bad idea)
    if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {
        [self.tableView setSeparatorInset:UIEdgeInsetsZero];
    }

    if ([self.tableView respondsToSelector:@selector(setLayoutMargins:)]) {
        [self.tableView setLayoutMargins:UIEdgeInsetsZero];
    }
} 

Swift 4:

func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    // Force your tableview margins (this may be a bad idea)
    if tableView.responds(to: #selector(setter: UITableView.separatorInset)) {
        tableView.separatorInset = .zero
    }
    if tableView.responds(to: #selector(setter: UITableView.layoutMargins)) {
        tableView.layoutMargins = .zero
    }
}

...で、完成です。これはiOS 7と8で動作するはずです。


EDITです。 Mohamed Salehから、iOS 9で起こりうる変更について注意を促されました。 テーブルビューの cellLayoutMarginsFollowReadableWidth から NO は、インセットやマージンをカスタマイズしたい場合に使用します。これはあまりよく知られていません。

このプロパティはiOS 9にしか存在しないので、設定する前に必ず確認してください。

if([myTableView respondsToSelector:@selector(setCellLayoutMarginsFollowReadableWidth:)])
{
    myTableView.cellLayoutMarginsFollowReadableWidth = NO;
} 

Swift 4:

if myTableView.responds(to: #selector(setter: self.cellLayoutMarginsFollowReadableWidth)) {
    myTableView.cellLayoutMarginsFollowReadableWidth = false
}

(上記のコードは iOS 8 UITableViewのセパレータインセット0が機能しない )

EDIT: ここでは、純粋なInterface Builderのアプローチを紹介します。

注:iOS 11はこの動作の多くを変更し、簡素化しましたので、近日中にアップデートを行います。