102

UITableViewCellオブジェクトにリンクされている があり、セルが表示されているかどうかを確認する必要があります。私が行った調査から、これは何らかのUITableView方法でそれを含む にアクセスする必要があることを意味します (そこから、表示されているかどうかを確認する方法がいくつかあります)。UITableViewCellへのポインターがあるUITableViewかどうか、またはセルからポインターを取得する他の方法があったかどうか疑問に思っていますか?

4

21 に答える 21

157

iOS のバージョンをチェックしないようにするには、UITableView が見つかるまで、セルのビューからスーパービューを繰り返します。

Objective-C

id view = [cellInstance superview];

while (view && [view isKindOfClass:[UITableView class]] == NO) {
    view = [view superview]; 
}

UITableView *tableView = (UITableView *)view;

迅速

var view = cellInstance.superview
while (view != nil && (view as? UITableView) == nil) {
  view = view?.superview
}
        
if let tableView = view as? UITableView {
   tableView.beginUpdates()
   tableView.endUpdates()
}
于 2013-09-13T06:59:52.263 に答える
48

iOS7 beta 5UITableViewWrapperViewでは、UITableViewCell. のスーパービューもあります。UITableViewUITableViewWrapperView

したがって、iOS 7の場合の解決策は

UITableView *tableView = (UITableView *)cell.superview.superview;

したがって、iOS 6 までの iOS の場合、解決策は次のとおりです。

UITableView *tableView = (UITableView *)cell.superview;

于 2013-08-23T16:53:29.633 に答える
25

iOS7 より前は、セルのスーパービューはUITableViewそれを含む でした。iOS7 GM の時点で (おそらくパブリック リリースにも含まれるでしょう)、セルのスーパービューは でありUITableViewWrapperView、そのスーパービューはUITableView. この問題には 2 つの解決策があります。

解決策 1:UITableViewCellカテゴリを作成する

@implementation UITableViewCell (RelatedTable)

- (UITableView *)relatedTable
{
    if ([self.superview isKindOfClass:[UITableView class]])
        return (UITableView *)self.superview;
    else if ([self.superview.superview isKindOfClass:[UITableView class]])
        return (UITableView *)self.superview.superview;
    else
    {
        NSAssert(NO, @"UITableView shall always be found.");
        return nil;
    }

}
@end

これは を使用するための適切なドロップイン置換でありcell.superview、既存のコードを簡単にリファクタリングできます。検索して に置き換え[cell relatedTable]、アサートをスローして、将来ビュー階層が変更または元に戻された場合にすぐに表示されるようにします。あなたのテストで。

解決策 #2: への弱いUITableView参照を追加するUITableViewCell

@interface SOUITableViewCell

   @property (weak, nonatomic) UITableView *tableView;

@end

これははるかに優れた設計ですが、既存のプロジェクトで使用するにはもう少しコードのリファクタリングが必要になります。SOUITableViewCelltableView:cellForRowAtIndexPathをセル クラスとして使用するか、カスタム セル クラスがサブクラス化されていることを確認しSOUITableViewCell、tableView をセルの tableView プロパティに割り当てます。セル内では、 を使用して含まれているテーブルビューを参照できますself.tableView

于 2013-09-15T14:33:53.693 に答える
7

Swift 2.2 ソリューション。

特定のタイプのビューを再帰的に検索する UIView の拡張機能。

import UIKit

extension UIView {
    func lookForSuperviewOfType<T: UIView>(type: T.Type) -> T? {
        guard let view = self.superview as? T else {
            return self.superview?.lookForSuperviewOfType(type)
        }
        return view
    }
}

またはよりコンパクト (カビロベライに感謝):

import UIKit

extension UIView {
    func lookForSuperviewOfType<T: UIView>(type: T.Type) -> T? {
        return superview as? T ?? superview?.superviewOfType(type)
    }
}

あなたのセルでは、それを呼び出すだけです:

let tableView = self.lookForSuperviewOfType(UITableView)
// Here we go

UITableViewCell は cellForRowAtIndexPath の実行後にのみ UITableView に追加されることに注意してください。

于 2016-08-10T14:58:35.073 に答える
7

表示されている場合は、スーパービューがあります。そして...驚き...スーパービューはUITableViewオブジェクトです。

ただし、スーパービューがあるからといって、画面に表示される保証はありません。ただし、UITableView には、どのセルが表示されているかを判断するメソッドが用意されています。

いいえ、セルからテーブルへの専用の参照はありません。しかし、UITableViewCell をサブクラス化すると、作成時にそれを導入して設定することができます。(サブビュー階層について考える前に、私は自分でそれをたくさんしました。)

iOS7 の更新: Apple はここでサブビュー階層を変更しました。詳細に文書化されていないものを扱うときはいつものように、物事が変わるリスクが常にあります。UITableView オブジェクトが最終的に見つかるまで、ビュー階層を「クロール」する方がはるかに節約になります。

于 2013-03-29T21:32:08.223 に答える
7

スーパー ビューを呼び出したり、レスポンダー チェーンを介して実行したりすることは、非常に脆弱です。セルが何かを知りたがっている場合、これを行う最善の方法は、セルが尋ねたい質問に答える何らかのメソッドに応答するオブジェクトをセルに渡し、何を答えるべきかを決定するロジックをコントローラーに実装させることです。 (あなたの質問から、セルは何かが見えるかどうかを知りたがっていると思います)。

セルにデリゲート プロトコルを作成し、セルのデリゲートを tableViewController に設定し、すべての UI の「制御」ロジックを tableViewCotroller に移動します。

テーブル ビューのセルは、情報のみを表示するダム ビューにする必要があります。

于 2013-03-29T22:43:35.310 に答える
6

UITableViewCell にカテゴリを作成して、親の tableView を取得しました。

@implementation UITableViewCell (ParentTableView)


- (UITableView *)parentTableView {
    UITableView *tableView = nil;
    UIView *view = self;
    while(view != nil) {
        if([view isKindOfClass:[UITableView class]]) {
            tableView = (UITableView *)view;
            break;
        }
        view = [view superview];
    }
    return tableView;
}


@end

一番、

于 2013-09-28T00:47:28.793 に答える
2

上記の回答から少し借りて変更し、次のスニペットを考え出しました。

- (id)recursivelyFindSuperViewWithClass:(Class)clazz fromView:(id)containedView {
    id containingView = [containedView superview];
    while (containingView && ![containingView isKindOfClass:[clazz class]]) {
        containingView = [containingView superview];
    }
    return containingView;
}

クラスで渡すと、他の場合に UITableView 以外のビューをトラバースして取得するための柔軟性が提供されます。

于 2014-07-29T06:58:37.517 に答える
2

この問題に対する私の解決策は、他の解決策と多少似ていますが、洗練された for ループを使用しており、短いものです。また、将来的にも保証されている必要があります。

- (UITableView *)tableView
{
    UIView *view;
    for (view = self.superview; ![view isKindOfClass:UITableView.class]; view = view.superview);
    return (UITableView *)view;
}
于 2014-08-18T20:17:34.880 に答える
1

スーパービューの代わりに、["UItableViewvariable" visibleCells] を使用してみてください。

これを foreach ループで使用して、アプリが認識したセルをループし、機能しました。

for (UITableView *v in [orderItemTableView visibleCells])//visibleCell is the fix.
{
  @try{
    [orderItemTableView reloadData];
    if ([v isKindOfClass:[UIView class]]) {
        ReviewOrderTableViewCell *cell = (ReviewOrderTableViewCell *)v;
        if (([[cell deleteRecord] intValue] == 1) || ([[[cell editQuantityText] text] intValue] == 0))
            //code here 
    }
  }
}

魅力のように機能します。

于 2013-12-09T18:52:15.923 に答える
1

最小限のテストですが、この非汎用の Swift 3 の例は機能しているようです。

extension UITableViewCell {
    func tableView() -> UITableView? {
        var currentView: UIView = self
        while let superView = currentView.superview {
            if superView is UITableView {
                return (superView as! UITableView)
            }
            currentView = superView
        }
        return nil
    }
}
于 2016-11-09T20:49:30.073 に答える
0

このコード`UITableView *tblView=[cell superview];は、タブ ビュー セルを含む UItableview のインスタンスを提供します。

于 2013-04-02T07:49:23.273 に答える
0

この方法でビュー階層をトラバースして、親 UITableView を見つけることをお勧めします。

- (UITableView *) findParentTableView:(UITableViewCell *) cell
{
    UIView *view = cell;
    while ( view && ![view isKindOfClass:[UITableView class]] )
    {
#ifdef DEBUG
        NSLog( @"%@", [[view  class ] description] );
#endif
        view = [view superview];
    }

    return ( (UITableView *) view );
}

そうしないと、Apple がビュー階層を再度変更したときにコードが壊れます。

階層を横断する別の答えは再帰的です。

于 2013-09-01T17:26:47.420 に答える
0
extension UIView {
    func parentTableView() -> UITableView? {
        var viewOrNil: UIView? = self
        while let view = viewOrNil {
            if let tableView = view as? UITableView {
                return tableView
            }
            viewOrNil = view.superview
        }
        return nil
    }
}
于 2016-08-19T20:05:45.540 に答える