web-dev-qa-db-ja.com

グループ化されたUITableviewは、外側の区切り線を削除します

プログラムで作成されたグループ化されたUITableviewがあります。また、プログラムでtableviewに入力されたxibファイルのセルもあります。ここまでは順調ですね。しかし、外側の区切り線のみを削除したいです。以下のコードを使用しましたが、今回はすべての区切り線を削除しました。

self.tableView.separatorColor = [UIColor clearColor];

これは私の状況には適していません。これが私がやりたいことのスクリーンショットです。

enter image description here

61
serhat sezer

セルにはcontentViewであるUIViewがあるので、解決策を考え出したので、contentViewのボトムラインに集中できると思います。

ここに私のコードがあります:

最初に、セパレータをクリアする必要があります

tableView.separatorColor = UIColor.clear

第二に、cellForRowAt関数で:

let bottomBorder = CALayer()

bottomBorder.frame = CGRect(x: 0.0, y: 43.0, width: cell.contentView.frame.size.width, height: 1.0)
bottomBorder.backgroundColor = UIColor(white: 0.8, alpha: 1.0).cgColor
cell.contentView.layer.addSublayer(bottomBorder)

ここでは、次のようなUIが表示されます。

enter image description here

6
Qi Lee

私のソリューションは次のとおりです。

self.tableView.separatorColor = self.tableView.backgroundColor

@xxtesaxx, you should have a real test

17
Brook

Static Cellのグループ化されたUITableViewでもセパレーターを削除できます。

class Cell: UITableViewCell {

override func layoutSubviews() {
    super.layoutSubviews()
    for view in subviews where view != contentView {
        view.removeFromSuperview()
    }
}
10
morizotter

ビュー階層を調べた後、各UITableViewCellには、コンテンツビュー(UITableViewCellContentView)と2つのセパレータビュー(__UITableViewCellSeparatorView_)の3つのサブビューしかないようです。私はNSStringsからの動的クラスのインスタンス化のファンではありません(また、Apple ????)でもありません。)。ただし、contentViewUITableViewCellはプライベートAPIを使用せずにアクセスできる場合、ソリューションは非常に簡単であることがわかります。

アイデアは、単にUITableViewCellのサブビューを反復処理し、contentView以外のビューを削除することです。

_func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    let subviews = cell.subviews
    if subviews.count >= 3 {
        for subview in subviews {
            if subview != cell.contentView {
                subview.removeFromSuperview()
                break
            }
        }
    }
}
_

tableView(:willDisplayCell:forRowAtIndexPath:)は、テーブルビューのレンダリング中に複数回呼び出されるため、上記はセルに含まれるサブビューの数をチェックすることで状態を追跡します。サブビューが3つある場合、両方のセパレーターはそのままです。また、セパレータの1つのみを削除しますが、breakを削除することで両方を削除できます。また、サブビューのフレームをチェックすることにより、上部セパレーターまたは下部セパレーターを削除するかどうかを指定できます。フレームのy軸の原点が_0_である場合、それが上部のセパレータです。 _0_でない場合は、一番下です。

お役に立てれば!

Swift 4 Swift 4.2アップデート:

_func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    let subviews = cell.subviews
    guard subviews.count >= 3 else {
        return
    }

    for subview in subviews where NSStringFromClass(subview.classForCoder) == "_UITableViewCellSeparatorView" {
        subview.removeFromSuperview()
    }
}
_
9
Dan Loewenherz

Googleは、2018年であっても、この質問に対する最高の結果としてこのページを提供しています。 iOS 11では、提供された回答のいずれにも運がなかったので、ここに私が思いついたものがあります。

extension UITableViewCell {
    func removeSectionSeparators() {
        for subview in subviews {
            if subview != contentView && subview.frame.width == frame.width {
                subview.removeFromSuperview()
            }
        }
    }
}

任意のUITableViewCellインスタンスで.removeSectionSeparators()を呼び出すと、問題が解決されます。少なくとも私の場合は、セル自体と同じ幅のセクションセパレータのみがあります(他のセパレータはすべてインデントされているため)。

残された唯一の質問は、それをどこから呼ぶべきかということです。 willDisplayCellが最良の選択だと思いますが、セパレータービュー自体が生成される前に最初の呼び出しが発生するため、サイコロはありません。

最終的に、リロードされたセルを返す直前に、これをcellForRowAtIndexPathメソッドに入れました。

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "MyReusableIdentifier", for: indexPath)

    Timer.scheduledTimer(withTimeInterval: 0.15, repeats: false) { (timer) in
        cell.removeSectionSeparators()
    }

    return cell
}

エレガントではありませんが、まだ問題に遭遇していません。

EDIT:これも必要なようです(再利用されたセルの場合):

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    cell.removeSectionSeparators()
}

このコードのスクリーンショットの前/後を次に示します。

BeforeBefore Separator Removal

AfterAfter Separator Removal

8
cook

それは本当に古い質問ですが、それでも各セクションの上部と下部の区切り文字を削除する方法を検索するときのグーグルの最初のエントリの1つです。

いくつかの調査の後、私はAppleからこれをどうにかしてビュー階層のばかげた複雑なハックなしで実現する方法はなく、意図もありません。

幸いなことに、このような外観を実現する絶対に簡単で簡単な方法があります。

enter image description here

シンプルですが、初心者にとっては、UITableViewの仕組みと独自のセルの実装方法を理解していないため、これは難しいかもしれません。説明しよう。

  1. UITableViewCellサブクラスを作成します
  2. セルで、@IBOutlet weak var separatorView: UIView!プロパティを作成します
  3. ストーリーボードで、tableviewセルを選択し、セルをバックアップするクラスとして独自のセルを選択します。 :あなたはしないカスタムスタイルを使用する必要があります。基本、字幕などを引き続き使用できます。
  4. UITableViews Separator StyleNoneに設定して、デフォルトのセパレータを非表示にします
  5. UIViewをセルにドラッグし、セルの下部(または上部)に収まるようにサイズを変更します。 Size Inspectors Autoresizingを使用して、開始/終了/下部に固定し、フレックスの幅を与えます(または、この場合はAutolayoutですが、それはちょうど上です)
  6. ビューをセルクラスのアウトレットに接続します
  7. UITableViewDataSources cellForRowAtIndexPath:で、indexPath.rowが最後の行であるかどうかに基づいて、カスタムセパレーターのisHiddenプロパティを設定します(ビューが上)セクション

コードの例をいくつか示します。

class MyCell: UITableViewCell {
    @IBOutlet weak var separatorView: UIView!
}

class ViewController: UITableViewController {


    override func numberOfSections(in tableView: UITableView) -> Int {
        return 3
    }
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 3
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! MyCell
        cell.separatorView.isHidden = indexPath.row == 2
        return cell
    }

}

そして、ここにいくつかのスクリーンショット:

enter image description here

enter image description here

enter image description here

enter image description here

はい、それはいくつかの作業ですが、コーディングするときに何かを無料で行う方法はありません。最終的に、私たちはプログラマーであり、コーディングを行うのは私たち次第です。 Appleがビュー階層を変更することを決定したときに、今後動作しなくなる可能性のあるハッキングコードを単にコピーして貼り付けるよりも、この設定に5-10分を費やす方が常に良いです。

実際には、セパレーターを実装するよりも、この答えを書くのは多くの作業でした。私も同様に簡単で迅速な解決策を探していましたが、結局のところ、使用する価値があると思うほど十分なものではありませんでした。

実行中にビュー階層からビューを非表示にしたり、削除したりするためにセルのサブビューを反復するforループを見るときに懐疑的になることを願っていますAppleは、安定した将来に向けたソリューションがすぐ近くにあります。7つの小さなステップが本当に必要なすべてであり、簡単に理解できます。

4
xxtesaxx

これは私がついに思いついたものです:

enter image description here

これよりも良い方法を見つけることができませんでした。しかし、それは私にとって大いに役立っています。 Xcodeバージョン7.3.1(7D1014)で最後に試しました。この手順は、ストーリーボードを通じて行われました。

基本的に、UITableViewCellに0.5 pt HeightのUIViewを追加し、そのUIViewの背景色を設定します。親UITableViewのSeparatorをNoneに設定します。

詳細は次のとおりです。

UITableViewCell、カスタムまたはデフォルトをすでに設定していることを考慮してください。最初の段階で、UITableViewのセパレーターをNoneに設定します。

enter image description here

次に、1ポイントの高さのUIViewを追加し、必要に応じて背景を設定します。私の場合は赤です。

enter image description here

enter image description here

制約の設定を開始します。問題は、UIViewの高さを0.5 ptに設定することです。これは、このワークフローの唯一の問題です。

0.5 ptの高さのUIView:

UIViewの高さ0.5 ptを設定する方法を共有します。

最初に(1)ビューを固定し、次に(2)高さを0.5に設定します。 Enterキーを押します。

enter image description here

最後に、UIViewは次のようになります。

enter image description here

この方法以外では、高さを0.5に設定できませんでした。

3
Shad

ここで解決策。これは静的セル用です。動的にしたい場合は、「count」を書き換えます。それが役に立てば幸い。

extension NSObject {
   var theClassName: String {
       return    NSStringFromClass(self.dynamicType).componentsSeparatedByString(".").last!
   }
}

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.separatorStyle = .None
}
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    let count = tableView.numberOfRowsInSection(indexPath.section)
    if ( indexPath.row != count - 1 ) {
        for view in cell.subviews {
            if view.theClassName == "_UITableViewCellSeparatorView" {
                view.backgroundColor = UIColors.redColor()
            }
        }
    }
}
2
onemanstartup

各セクションの区切り線の上部と下部を削除します。これを静的セルに追加します。

override func layoutSubviews() {
    super.layoutSubviews()

    //Get the width of tableview
    let width = subviews[0].frame.width

    for view in subviews where view != contentView {
        //for top and bottom separator will be same width with the tableview width
        //so we check at here and remove accordingly
        if view.frame.width == width {
            view.removeFromSuperview()
        }
    }
}

下の画像のような結果

enter image description here

2
titan

cell.separatorInset = UIEdgeInsetsMake()回避策に基づいてさまざまなソリューションを試しましたが、どれも適切に動作しませんでした。

私のiOS11 UITableViewStyleGroupedベースのプロジェクトでは、次のようにしました。

self.tableView.separatorColor = self.tableView.backgroundColor;
1
Art

クックの答えに基づいていますが、タイマーはありません:

override func didAddSubview(_ subview: UIView) {
    super.didAddSubview(subview)
    if NSStringFromClass(subview.classForCoder) != "UITableViewCellContentView" && subview.frame.width == frame.width {
        subview.removeFromSuperview()
    }
}

これをセルのサブクラスに追加するだけで、他に何も必要ありません。 iOS 12で動作します。

1
Andrii Liakh

これを試してみると、上部の区切り線が削除されます。

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if(indexPath.row == 0 && indexPath.section == 0) {
        for (UIView *view in  cell.subviews) {
            if ([NSStringFromClass([view class]) containsString:@"CellSeparator"]) {
                if (view.frame.Origin.y == 0 && CGRectGetHeight(view.frame) < 1.01 ) { //Hide first UITableViewCellSeparatorView
                    NSLog(@"%s Remove View From Cell[Section:0 Row:0] for top border [%@]:%@",__FUNCTION__,NSStringFromClass([view class]),view);
                    view.hidden = YES; //Hide
                }
            }
        }
    }
}
0
TARANG GHORI

を使用してビューにアクセスできます

override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {

    let header = view as! UITableViewHeaderFooterView 
    header.backgroundView . .....
0

同様の問題があり、カスタムセルを含むグループ化されたUITableViewがあり、すべてが.xibファイルとしてInterface Buildで設計されていました。セルには白い背景があり、デフォルトのセパレータを削除し、独自のセパレータを追加しました。また、各セクションにカスタムヘッダービューがありました。これらのヘッダービューの高さを44に設定します(何でもかまいません)。私のセクションの間に1ポイントの高さのビューがありましたが、奇妙に見えました。明らかに、カスタムの高さをたとえば44に指定し、返されるカスタムヘッダービューの色が白(または具体的な背景色)であっても、システムはセクション間に明確な背景ビューを追加します。この明確なビューの背後にある色は、実際にはテーブルビューの背景の色です。私の場合、テーブルビューとセルの両方を白色にする必要があり、テーブルビューの背景を白色に設定することで問題を解決しました(少なくとも視覚的には、とにかくそれが望みです)。 2番目の解決策は、Table Viewのスタイルをそのままにして、2つ以上のセクションを返すUITableViewデリゲートメソッドを実装し、必要に応じてカスタムヘッダーを作成することです。しかし、それにより、ヘッダービューがしばらくの間(スクロール中)に固定され、次のセクションのヘッダービューがそれに近づき、それから上昇し始めます(そして、それはあなたが本当に望むものではないかもしれませんが、それを修正する簡単な方法かもしれませんが、確かではありません)。

0
ppalancica