iOS 8 UITableViewセパレータインセット0が機能しない


662

UITableViewセパレーターインセットがカスタム値(右0、左)に設定されているアプリがあります0。これはで完璧に動作iOS 7.xしかし中に、iOS 8.0私は、セパレータのインセットがデフォルトに設定されていることがわかり15、右側に。xibファイルではに設定され0ていますが、それでも正しく表示されません。

UITableViewCellセパレータのマージンを削除するにはどうすればよいですか?


インセットを0ではなく0.001に設定してみましたか?エッジインセットが0に反応せず、0.001(または同様の小さなもの)には反応するという同様の問題を覚えています。
2014

私はそれをしようと、それはどちらか..動作しませんでした
user3570727

4
次に、セパレータの色を設定し[UIColor clearColor]て独自のセパレータを描画することをお勧めします。そうすれば、はるかに柔軟になります。
2014

1
これがまだUITableViewCellSeparatorStyleデフォルトの1つではないことはまだ信じられません。受け入れられた答えでさえ、私の意見では本当に汚いハックです。
Enrico Susatyo 2014

回答:


1071

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

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

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

(ObjectiveC)

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

(swift 4.2):

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

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


加えてlayoutMarginsプロパティ、Appleが追加したプロパティを、あなたのテーブル表示の余白設定を継承することを防止することをあなたの携帯に。このプロパティが設定されている場合、セルはテーブルビューとは関係なく独自のマージンを構成できます。オーバーライドと考えてください。

このプロパティはと呼ばれpreservesSuperviewLayoutMargins、これをに設定するNOと、セルのlayoutMargin設定がlayoutMarginTableViewで設定されているものをオーバーライドできるようになります。時間の節約(テーブルビューの設定を変更する必要がない)と、より簡潔です。詳細な説明については、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];
    }
}

スウィフト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];
    }
} 

スウィフト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: モハメド・サレーは私の注意にiOSの9の可能な変化をもたらしたあなたはテーブル表示の設定する必要があるかもしれませんcellLayoutMarginsFollowReadableWidthにしNOますが、インセットや余白をカスタマイズしたい場合。あなたの走行距離は変わるかもしれません、これはあまりよく文書化されていません。

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

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

スウィフト4:

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

iOS 8 UITableViewセパレーターインセット0の上記のコードは機能しません

編集:これは純粋なインターフェイスビルダーアプローチです:

TableViewAttributesInspector TableViewCellSizeInspector

注:iOS 11はこの動作の多くを変更および簡素化します。近日中にアップデートが提供されます...


2
UIPopoverController内のテーブルビューの場合、willDisplayCellだけでなく、上記のように両方を実行する必要がありました。
Zhang

44
上記のすべてのコードにも関わらず、cell.preservesSuperviewLayoutMargins = NO@ bffmikeの提案に従って、またはスクロールした後にインセットが表示される方法を追加する必要があることもわかりました。(wtf ??)
inorganik

グループ化されたtableViewの1種類のセルに対してのみマージンを設定したい場合はどうなりますか?
SAHM、2014年

willDisplayCellで設定して、実際に機能するかどうかを確認してみてください(セルにハンドルがあるので、簡単なはずです)。そうでない場合は、バグを報告する必要があります。セル固有のレイアウトマージンが可能なはずです(IMO)。
cdstamper 2014年

2
これはcell.preservesSuperviewLayoutMargins私のデータソースメソッドに追加して私にとってうまく- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
いきました

257

引数!!! Cellサブクラスでこれをやって遊んだ後:

- (UIEdgeInsets)layoutMargins
{
    return UIEdgeInsetsZero;
}

またはcell.layoutMargins = UIEdgeInsetsZero;私のためにそれを修正して設定します。


13
この回答の最初の解決策は私にとってはうまくいきましたが、2番目の解決策はうまくいきませんでした。
スパイバート、2014

5
cell.layoutMargins = UIEdgeInsetsZeroだけを使用しないでください。iOS 7.xでクラッシュするため。セレクタを使用する前に、セレクタが最初に存在するかどうかを確認することをお勧めします。以下の私の解決策を参照してください。
リッキー

3
彼はcell.layoutMarginsを設定していません...このソリューションは、カスタムセルがすでにある場合に適切に機能します。
Sjoerd Perfors 2014

11
これは、メソッドが呼び出されないため、iOS 7では正常に機能します。ただし、テーブルビューのlayoutMarginsも設定する必要があります。そうしないと機能しません。
cdstamper 2014

2
アクセサーのオーバーライドは私のために働いた。しかし、他のすべてのソリューションはしませんでした。separatorInsetIB での構成さえも機能しませんでした。テーブルビューの背景色にも問題があります。これは本当に病気のものです。
glasz 2014

178

問題を修正するためにやみくもに充電する前に、少し時間をとって問題を理解しましょう。

デバッガーをざっと見てみると、区切り線がのサブビューであることがわかりUITableViewCellます。セル自体がこれらの線のレイアウトにかなりの責任を負っているようです。

iOS 8では、レイアウトマージンの概念が導入されています。デフォルトでは、ビューのレイアウトマージンは8ptすべての側にあり、祖先ビューから継承されます。

よくわかるように、セパレーターラインをUITableViewCellレイアウトするときは、左側のインセットを制約するために使用して、左側のレイアウトマージンを尊重します。

これらすべてを組み合わせて、真にゼロの望ましいインセットを実現するには、以下を行う必要があります。

  • 左のレイアウトマージンを 0
  • それを上書きする継承されたマージンを停止します

そのように置くと、達成するのはかなり簡単なタスクです:

cell.layoutMargins = UIEdgeInsetsZero;
cell.preservesSuperviewLayoutMargins = NO;

注意事項:

  • このコードはセルごとに1回だけ実行する必要があり(結局のところ、セルのプロパティを構成するだけです)、実行することを選択するタイミングについて特別なことは何もありません。あなたにとって最もきれいに見えることをしてください。
  • 残念ながら、どちらのプロパティもInterface Builderで設定できませんがpreservesSuperviewLayoutMargins、必要に応じてユーザー定義のランタイム属性を指定できます。
  • 明らかに、アプリが以前のOSリリースもターゲットにしている場合は、iOS 8以降で実行するまで上記のコードを実行しないようにする必要があります。
  • を設定するのpreservesSuperviewLayoutMarginsではなく、祖先ビュー(テーブルなど)を左余白を持つように構成することもできます0が、階層全体を制御しないため、これは本質的にエラーが発生しやすくなります。
  • 左マージンのみを設定し0、他のマージンはそのままにしておくと、多少クリーンになります。
  • UITableViewプレーンスタイルのテーブルの下部に描画される「余分な」セパレーターに0インセットを設定したい場合は、テーブルレベルでも同じ設定を指定する必要があると思います(これは試していません)。

3
ありがとうございました!これは本当により簡潔な答えです。2つのメソッドをオーバーライドしてブルートフォースを強制するよりもはるかに優れています。
LunaCodeGirl 2014年

16
私にとってiOS 8では、これなしでは機能しません[self.tableView setSeparatorInset:UIEdgeInsetsMake(0, 0, 0, 0)];
davetw12

1
明確な説明をありがとうございます。TableView自体にもlayoutMarginsがあり、separatorInsetに加えて設定する必要がある場合があることを述べておきます。
cdstamper 2014

@ davetw12および@cdstamperこれの証拠を提供できますか?これまでの私のすべての調査では、両方layoutMarginspreservesSuperviewLayoutMarginsセルの設定が必要なすべてであると述べています。他のものはブードゥー教を信頼するような気がします。
Mike Abdullah

3
いいえ、それはブードゥー教の@MikeAbdullahの形式ではありません。iOS 8のデフォルトseparatorInsetのa を回避するには、との両方でUITableViewCellset UIEdgeInsetsをゼロに設定する必要があります。両方を行わない場合でも、左のはめ込みはゼロより大きくなります。これを何度も確認しました。UITableViewUITableViewCell
davetw12 14

58

これは私がここで尋ねたのと同じ質問だと思います:iOS 8 UITableViewのSeparatorInsetをXCode 6 iPhoneシミュレーターから削除します

ではiOSの8、継承するすべてのオブジェクトに対して1つの新しいプロパティがありますUIView。したがって、SeparatorInsetiOS 7.xでを設定するソリューションでは、iOS 8のUITableViewに表示される空白を削除できません。

新しいプロパティは「layoutMargins」と呼ばれます。

@property(nonatomic) UIEdgeInsets layoutMargins
Description   The default spacing to use when laying out content in the view.
Availability  iOS (8.0 and later)
Declared In   UIView.h
Reference UIView Class Reference

iOS 8 UITableView setSeparatorInset:UIEdgeInsetsZero setLayoutMargins:UIEdgeInsetsZero

ソリューション:-

-(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 ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
        [cell setLayoutMargins:UIEdgeInsetsZero];
   }
}

が存在cell.layoutMargins = UIEdgeInsetsZero;するかどうかを確認せずに設定layoutMarginsすると、iOS 7.xでアプリがクラッシュします。したがって、最善の方法は、layoutMarginsが最初に存在するかどうかを確認することですsetLayoutMargins:UIEdgeInsetsZero


展開ターゲットがiOS 7に設定されている場合、このアプローチはどのように使用できますか?
Petar

tableViewのコードをviewDidLoadに入れて、正常に動作しています。willDisplayCell()で毎回呼び出す必要はないと思います。
Abdullah Umer、2015年

46

アプリケーションの起動時に(UIが読み込まれる前に)UIAppearanceを1回使用して、デフォルトのグローバル設定として設定できます。

// iOS 7:
[[UITableView appearance] setSeparatorStyle:UITableViewCellSeparatorStyleSingleLine];
[[UITableView appearance] setSeparatorInset:UIEdgeInsetsZero];

[[UITableViewCell appearance] setSeparatorInset:UIEdgeInsetsZero];

// iOS 8:
if ([UITableView instancesRespondToSelector:@selector(setLayoutMargins:)]) {

    [[UITableView appearance] setLayoutMargins:UIEdgeInsetsZero];
    [[UITableViewCell appearance] setLayoutMargins:UIEdgeInsetsZero];
    [[UITableViewCell appearance] setPreservesSuperviewLayoutMargins:NO];

}

このようにして、UIViewControllerのコードをクリーンに保ち、必要に応じていつでもそれをオーバーライドできます。


41

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

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

しかし、Appleが追加したプロパティと呼ばpreservesSuperviewLayoutMarginsあなたのテーブルビューの余白設定を継承することを防止しますあなたのセルにします。このように、セルはテーブルビューとは関係なく独自のマージンを構成できます。オーバーライドと考えてください。

このプロパティは、preservesSuperviewLayoutMarginsと呼ば、NOに設定すると、テーブルビューのlayoutMargin設定を独自のセルのlayoutMargin設定でオーバーライドできます。時間の節約(テーブルビューの設定を変更する必要がない)と、より簡潔です。詳細な説明については、Mike Abdullahの回答を参照してください。

注:これは、Mike Abdullahの回答で述べられているように、適切で面倒な実装ではありません。セルのpreservesSuperviewLayoutMargins = NOを設定すると、テーブルビューがセル設定を上書きしないようになります。

最初のステップ-セルのマージンを設定します。

/*
    Tells the delegate that the table view is about to draw a cell for a particular row.
*/
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell,
    forRowAtIndexPath indexPath: NSIndexPath)
{
    // Remove separator inset
    if cell.respondsToSelector("setSeparatorInset:") {
        cell.separatorInset = UIEdgeInsetsZero
    }

    // Prevent the cell from inheriting the Table View's margin settings
    if cell.respondsToSelector("setPreservesSuperviewLayoutMargins:") {
        cell.preservesSuperviewLayoutMargins = false
    }

    // Explictly set your cell's layout margins
    if cell.respondsToSelector("setLayoutMargins:") {
        cell.layoutMargins = UIEdgeInsetsZero
    }
}

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

2番目のステップ-すべてが失敗した場合にのみ、テーブルビューのマージンを総当たりにすることができます。

/*
    Called to notify the view controller that its view has just laid out its subviews.
*/
override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    // Force your tableview margins (this may be a bad idea)
    if self.tableView.respondsToSelector("setSeparatorInset:") {
        self.tableView.separatorInset = UIEdgeInsetsZero
    }

    if self.tableView.respondsToSelector("setLayoutMargins:") {
        self.tableView.layoutMargins = UIEdgeInsetsZero
    }
}

...そして、そこに行きます!これはiOS 7だけでなくiOS 8でも機能するはずです。

注:iOS 8.1および7.1を使用してテストしました。私の場合、この説明の最初のステップのみを使用する必要がありました。

2番目のステップは、レンダリングされたセルの下に未入力のセルがある場合にのみ必要です。テーブルがテーブルモデルの行数より大きい場合。2番目のステップを実行しないと、セパレーターのオフセットが異なります。


1
willDisplayCellメソッド自体はすでにiOS 8以降であり、古いバージョンから呼び出されることはないため、メソッドでセレクターを確認する必要はありません。
Rivera

38

SwiftではlayoutMarginsはプロパティであるため、少し面倒です。そのため、ゲッターセッターをオーバーライドする必要があります。

override var layoutMargins: UIEdgeInsets {
  get { return UIEdgeInsetsZero }
  set(newVal) {}
}

これにより実質的にlayoutMargins読み取り専用になりますが、私の場合は問題ありません。


このソリューションだけが私にとってうまくいきました。メソッドに行のコードを追加する必要はありませんでした。カスタムセルを使用しました。
Ramis

2
静的セルの場合、layoutMarginsのオーバーライドを除いて、セルのセパレータースタイルを「カスタムインセット」に変更し、ストーリーボードで左の値を「0」に設定する必要があります。
hufeng03 2014年

22

iOS 9の場合、以下を追加する必要があります。

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

詳細については質問を参照してください。


12
それは...そう、最初の外観ステー同じことをバージョンごとにいくつかのコードを追加して面白いです
キリスト教の

20

Swift 2.0拡張

テーブルビューのセルセパレーターからマージンを削除するために作成した拡張機能を共有したかっただけです。

extension UITableViewCell {
    func removeMargins() {

        if self.respondsToSelector("setSeparatorInset:") {
            self.separatorInset = UIEdgeInsetsZero
        }

        if self.respondsToSelector("setPreservesSuperviewLayoutMargins:") {
            self.preservesSuperviewLayoutMargins = false
        }

        if self.respondsToSelector("setLayoutMargins:") {
            self.layoutMargins = UIEdgeInsetsZero
        }
    }
}

コンテキストで使用:

    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! CustomCell

    cell.removeMargins()
    return cell

15

迅速:

override func viewDidLoad() {
    super.viewDidLoad()

    if self.tableView.respondsToSelector("setSeparatorInset:") {
        self.tableView.separatorInset = UIEdgeInsetsZero
    }
    if self.tableView.respondsToSelector("setLayoutMargins:") {
        self.tableView.layoutMargins = UIEdgeInsetsZero
    }

    self.tableView.layoutIfNeeded()            // <--- this do the magic
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
     ...

    if cell.respondsToSelector("setSeparatorInset:") {
        cell.separatorInset = UIEdgeInsetsZero
    }
    if cell.respondsToSelector("setLayoutMargins:") {
        cell.layoutMargins = UIEdgeInsetsZero
    }

    return cell
}

11

私はこれを行うことによってそれを機能させました:

tableView.separatorInset = UIEdgeInsetsZero;
tableView.layoutMargins = UIEdgeInsetsZero;
cell.layoutMargins = UIEdgeInsetsZero;

9

テーブルビューの代わりにcdstamperが提案したことについては、セルのlayoutSubviewメソッドに以下の行を追加するとうまくいきます。

- (void)layoutSubviews 
{
    [super layoutSubviews];

    if ([self respondsToSelector:@selector(setSeparatorInset:)])
                [self setSeparatorInset:UIEdgeInsetsZero];

        if ([self respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)])
        {
            [self setPreservesSuperviewLayoutMargins:NO];;
        }

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

9

Swift 3.0の例:

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    // removing seperator inset
    if cell.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
        cell.separatorInset = .zero
    }
    // prevent the cell from inheriting the tableView's margin settings
    if cell.responds(to: #selector(setter: UIView.preservesSuperviewLayoutMargins)) {
        cell.preservesSuperviewLayoutMargins = false
    }
    // explicitly setting cell's layout margins
    if cell.responds(to: #selector(setter: UITableViewCell.layoutMargins)) {
        cell.layoutMargins = .zero
    }
}

9

多くの調査の後...

これを完全に制御する唯一の方法はここにあります(私が見つけることができました)

各セルのセパレータインセットとレイアウトマージンの両方を完全に制御します。これをのwillDisplayCellメソッドで行いますUITableviewDelegate

func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    cell.layoutMargins = UIEdgeInsetsZero
    cell.contentView.layoutMargins = UIEdgeInsetsMake(0, 10, 0, 10)
    cell.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0)
}

セルオブジェクトはセパレータを制御し、contentViewその他すべてを制御します。セパレータインセットスペースが予期しない色で表示されている場合、これで解決できます。

cell.backgroundColor = cell.contentView.backgroundColor

8

カスタムのSwift for iOS 8のシンプルなソリューションUITableViewCell

override func awakeFromNib() {
    super.awakeFromNib()

    self.layoutMargins = UIEdgeInsetsZero
    self.separatorInset = UIEdgeInsetsZero
}

このように設定するlayoutMarginと、上記の回答のほとんどが示唆するように、separatorInsetそれぞれに対して設定するのではなく、一度だけ設定willDisplayCellします。

カスタムを使用している場合UITableViewCellは、これを行うのが適切な場所です。それ以外の場合は、で行う必要がありますtableView:cellForRowAtIndexPath

もう1つのヒント:preservesSuperviewLayoutMargins = falseデフォルト値はすでにNO!なので、設定する必要はありません。


8

私にとっては、シンプルなラインが仕事をしました

cell.layoutMargins = UIEdgeInsetsZero

これをcellForRowAtIndexPathデリゲートメソッドで呼び出しました。良い答え:)
セントジャブ2016年

7

以下のコードを追加するだけでこのプログラムを解決できます。

頑張って!

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

       if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
           [cell setSeparatorInset:UIEdgeInsetsZero];
       }

       if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
           [cell setLayoutMargins:UIEdgeInsetsZero];
       }

}

5

SwiftでのLukaszの回答:

    // iOS 7:
    UITableView.appearance().separatorStyle = .SingleLine
    UITableView.appearance().separatorInset = UIEdgeInsetsZero
    UITableViewCell.appearance().separatorInset = UIEdgeInsetsZero

    // iOS 8:
    if UITableView.instancesRespondToSelector("setLayoutMargins:") {
        UITableView.appearance().layoutMargins = UIEdgeInsetsZero
        UITableViewCell.appearance().layoutMargins = UIEdgeInsetsZero
        UITableViewCell.appearance().preservesSuperviewLayoutMargins = false
    }

5

これは、Swiftで機能するコードです。

override func viewDidLoad() 
{
    super.viewDidLoad()
    ...
    if tableView.respondsToSelector("setSeparatorInset:") {
        tableView.separatorInset = UIEdgeInsetsZero
    }
}

func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell,forRowAtIndexPath indexPath: NSIndexPath)
{
    if cell.respondsToSelector("setSeparatorInset:") {
        cell.separatorInset.left = CGFloat(0.0)
    }
    if tableView.respondsToSelector("setLayoutMargins:") {
        tableView.layoutMargins = UIEdgeInsetsZero
    }
    if cell.respondsToSelector("setLayoutMargins:") {
        cell.layoutMargins.left = CGFloat(0.0)
    }
}

これは私にとって(今のところ)最もクリーンなようです。すべてのcell / tableViewエッジ/マージン調整はtableView:willDisplayCell:forRowAtIndexPath:、不要なコードをに詰め込むことなくメソッドで行われるためtableView:cellForRowAtIndexPath:です。

ところで、セルの左側のseparatorInset / layoutMarginsを設定しているだけです。この場合は、セルに設定した制約を台無しにしたくないからです。

Swift 2.2に更新されたコード:

 override func viewDidLoad() {
   super.viewDidLoad()       

    if tableView.respondsToSelector(Selector("setSeparatorInset:")) {
      tableView.separatorInset = UIEdgeInsetsZero
        }
    }

 override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell,forRowAtIndexPath indexPath: NSIndexPath) {
        if cell.respondsToSelector(Selector("setSeparatorInset:")) {
            cell.separatorInset.left = CGFloat(0.0)
        }
        if tableView.respondsToSelector(Selector("setLayoutMargins:")) {
            tableView.layoutMargins = UIEdgeInsetsZero
        }
        if cell.respondsToSelector(Selector("setLayoutMargins:")) {
            cell.layoutMargins.left = CGFloat(0.0)
        }
    }

何がうまくいっていないのですか?iOS 8.1 SDKがインストールされたiPhone 5シミュレーターでこのコードをテストしたところ、すべて私が最初にこの回答を投稿したときと同じです。コードはコンパイルされ、Xcode 6.1.1で実行されました。
Ivan

4

ほとんどの答えは、セパレータのインセットを示しているとレイアウトマージンは方法(すなわち、さまざまな上に設定されviewDidLayoutSubviewswillDisplayCell細胞およびtableviewsのため、など)が、私はちょうどでこれらを入れていることを発見したcellForRowAtIndexPath素晴らしい作品。最もきれいな方法のようです。

// kill insets for iOS 8
if ([[UIDevice currentDevice].systemVersion floatValue] >= 8) {
    cell.preservesSuperviewLayoutMargins = NO;
    [cell setLayoutMargins:UIEdgeInsetsZero];
}
// iOS 7 and later
if ([cell respondsToSelector:@selector(setSeparatorInset:)])
    [cell setSeparatorInset:UIEdgeInsetsZero];

4

以下のコードスニペットを使用して、IOS 8および7のUITableViewの不要なパディング問題を回避します。

-(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 ([cell respondsToSelector:@selector(setLayoutMargins:)])
    {
        [cell setLayoutMargins:UIEdgeInsetsZero];
    }
}

4

代わりに更新するpreservesSuperviewLayoutMarginslayoutMargins(使用中のセルのスクロールをするたびにwillDisplayCell)、私は一度でそれを行うことをお勧めしたいですcellForRowAtIndexPath:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = super.tableView(tableView, cellForRowAtIndexPath: indexPath)

    cell.preservesSuperviewLayoutMargins = false
    cell.layoutMargins = UIEdgeInsetsZero

    return cell

}

4

インセットをグローバルに削除する簡単な方法を次に示します。

UITableViewCell+Extensions.swift

import UIKit

extension UITableViewCell {

  override public var layoutMargins: UIEdgeInsets {
    get { return UIEdgeInsetsZero }
    set { }
  }

}

AppDelegate application:didFinishLaunchingWithOptions:

  UITableViewCell.appearance().separatorInset = UIEdgeInsetsZero

代わりseparatorInsetlayoutMargins、a)拡張機能をオーバーライドするか、b)の外観プロキシを設定することもできます。どちらも機能しません。separatorInsetプロパティとして示されている場合でも、プロパティ(またはメソッド)としてオーバーライドしようとすると、コンパイラエラーが発生します。そして、外観のプロキシ設定UITableViewCelllayoutMargins(そのことについては、またの外観プロキシ設定や、UITableViewのをlayoutMarginsしてseparatorInsetも効果はありません)を。


3

iOS8の場合:

これを私のUITableViewCellサブクラスに追加します。

- (UIEdgeInsets)layoutMargins {
    return UIEdgeInsetsZero;
}

これを「tableView:cellForRowAtIndexPath」または「tableView:willDisplayCell」に変更します。

[editCell setSeparatorInset:UIEdgeInsetsZero];

私のために働いた。


2
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        // ... Get the cell
        cell.separatorInset = UIEdgeInsetsMake(0.f, 20.f, 0.f, [UIScreen mainScreen].bounds.size.width - 20);
        // others
        return cell;
}

セパレータを非表示にする特定のセル。


2

3階で答えを見た後、TableViewとTableViewCellの間にセパレーターを設定することの関係を理解し​​ようとし、いくつかのテストを行いました。これが私の結論です:

  1. セルのセパレーターをゼロに設定するには、2つのステップでセパレーターを移動する必要があると考えることができます。最初のステップは、セルのセパレーターをゼロに設定することです。2番目のステップは、セルのmarginlayoutをゼロに設定することです。

  2. TableViewのseparatorinsetおよびmarginlayoutを設定すると、Cellのseparatorinsetに影響を与える可能性があります。ただし、テストから、TableViewのseparatorinsetは役に立たないように見えることがわかりました。TableViewのmarginlayoutは、実際にはセルのmarginlayoutに影響を与える可能性があります。

  3. CellのPreservesSuperviewLayoutMargins = falseを設定すると、TableViewのmarginlayout効果をセルにカットできます。

  4. ソリューションの1つ:

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        var cell = UITableViewCell()
    
        cell.preservesSuperviewLayoutMargins = false
        cell.separatorInset = UIEdgeInsetsZero
        cell.layoutMargins = UIEdgeInsetsZero
    
        return cell
    }

2

これが私の解決策です。これはカスタムセルサブクラスに適用されます。両方をサブクラスに追加するだけです。

  1. - (UIEdgeInsets)layoutMargins {    
        return UIEdgeInsetsMake(0, 10, 0, 10);
    }

2。

self.separatorInset = UIEdgeInsetsMake(0, 10, 0, 10);

そして、あなたにデザイナーにそれを描くように頼むことなくセパレーターの位置をカスタマイズできるのは便利です..........


1

最も投票された回答よりもコンパクトな方法で...

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

    if ([cell respondsToSelector:@selector(setSeparatorInset:)] && [cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)] && [cell respondsToSelector:@selector(setLayoutMargins:)]) {
         [cell setSeparatorInset:UIEdgeInsetsZero];
         [cell setPreservesSuperviewLayoutMargins:NO];
         [cell setLayoutMargins:UIEdgeInsetsZero];
    }

}


1

このスニペットを追加すると、SwiftのシンプルでエレガントなものがiOS8で機能します。

    // tableview single line
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    cell.preservesSuperviewLayoutMargins = false
    cell.layoutMargins = UIEdgeInsetsZero
}

1

これは、iOS 8とiOS 9では完全に機能しました。

OBJ-C

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath  { 
        if ([tableView respondsToSelector:@selector(setSeparatorInset:)])
        {
            [tableView setSeparatorInset:UIEdgeInsetsZero];
        }

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

        if ([cell respondsToSelector:@selector(setLayoutMargins:)])
        {
            [cell setLayoutMargins:UIEdgeInsetsZero];
        }
         return cell;
    }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.