2017-02-10 6 views
1

OK。これに触れる多くの質問がありますが、私が必要とするものに実際に対処するものはありません。動的UITableViewプロトタイプの行の高さへのアクセス

私が必要とするのは、ダイナミック(静的でない)テーブルセルプロトタイプの「カスタム行の高さ」に対してIBで設定した値を取得することです。

テーブルが静的プロトタイプを設定する場合、これは自動的に有効になります。ただし、動的プロトタイプを使用する場合、この値はテーブルのメインのrowHeight値を優先して無視されます。

この値にアクセスしたいので、メソッドで返すことができます。私はこれを手動で行うことができます。これは、高さの内部テーブルを持ち、プロトタイプにマッチさせることですが、それは面倒で扱いにくく、プロトタイプが常に特定の行に表示される必要があります。

tableView(_:heightForRowAt:)が呼び出されたとき、私は再利用IDを合成できますが、適切な時刻(tableView(_:cellForRowAt:))までビューセルを読み込む必要はありません。

これにアクセスする良い方法はありますか?プロトタイプへのアクセスについてAppleのドキュメントには何も書かれていません。

答えて

2

編集:はい、あなたの問題は何ですか。 iOS開発では、このようなタスクをUITableCellの異なるサブクラスで処理します。

+ (CGFloat)layoutHeightWithEntity:(id)entity { 
    CGFloat layoutHeight = 0; 
    // use data to calculate layout height dynamically if needed 
    // id data = [entity data]; 
    // layoutHeight = layoutHeight + [data ...]; 

    // or use a static layout height if the height of this kind of cells do not change 
    layoutHeight = 100; 

    return layoutHeight; 
} 

そして、あなたのビューコントローラでは、あなたがこのようなあなたのテーブルビューのデータソースを準備する必要があります:このよう

NSMutableArray *dataList = [NSMutableArray new]; 

NSMutableArray *firstSection = [NSMutableArray new]; 
[firstSection addObject:[XXXTableEntity entityWithReuseCellID:@"nameCell" data:someData cellClass:[XXXNameCell class]]; 
[dataList addObject:firstSection]; 

NSMutableArray *secondSection = [NSMutableArray new]; 
[firstSection addObject:[XXXTableEntity entityWithReuseCellID:@"pickerCell" data:someData cellClass:[XXXPickerCell class]]; 
[dataList addObject:secondSection]; 

[self setDataList:dataList]; 

あなたCustomTableEntityは次のようになります。

+ (instancetype)entityWithEntityID:(NSString *)entityID 
         cellReUseID:(NSString *)cellReUseID 
         cellClass:(Class<XXXBaseTableCellLayout>)cellClass 
         dataEntity:(id)dataEntity 
       precalculateHeight:(BOOL)precalculateHeight { 

    XXXBaseTableCellEntity *entity = [self new]; 

    [entity setEntityID:entityID]; 
    [entity setReuseCellID:cellReUseID]; 
    [entity setDataEntity:dataEntity]; 

    [entity setCellClass:cellClass]; 

    if (precalculateHeight) { 
     [entity setLayoutHeight:[cellClass layoutHeightWithEntity:dataEntity]]; 
    } 

    return entity; 
} 

- (CGFloat)layoutHeight { 
    if (_layoutHeight > 0) { 

     return _layoutHeight; 
    } 

    _layoutHeight = [[self cellClass] layoutHeightWithEntity:[self dataEntity]]; 

    return _layoutHeight; 
} 

あなたのUITableViewDataSourceメソッドで:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 

    return self.dataList.count; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 

    return [self.dataList[section] count]; 
} 

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 

    return [[[[self dataList] objectAtIndex:[indexPath section]] objectAtIndex:[indexPath row]] layoutHeight]; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    XXXTableEntity *entity = [[[self dataList] objectAtIndex:[indexPath section]] objectAtIndex:[indexPath row]]; 

    XXXBaseTableCell *cell = [tableView dequeueReusableCellWithIdentifier:[entity reuseCellID] forIndexPath:indexPath]; 
    [cell configureWithEntity:entity]; 

    return cell; 
} 

上記のコードは、基本的に私の会社のために書いたフレームワークのものですが、あなたはそのアイデアを得るべきです。フレームワークには、テーブルビューに関連する3つのクラスがあります。XXXBaseTableCellXXXBaseTableViewControllerXXXBaseTableCellEntityです。すべてのビューコントローラには、テーブルビューサブクラスXXXBaseTableViewController、すべてのテーブルセルサブクラスXXXBaseTableCell、すべてのテーブルエンティティサブクラスXXXBaseTableCellEntityが含まれます。


なぜこのようにしたいのですか?私はあなたがテーブルビューでいくつかの問題を抱えていると思います。あなたがなぜそれをしたいのか説明することができれば、おそらく私はあなたを助けることができるので、あなたはそれをまったくやる必要はありません。

標準アプローチでプロトタイプセルの高さにアクセスすることはできません。しかし実際にはストーリーボードファイル内のデータにアクセスすることができます。以下はその方法です。

ストーリーボードはXMLファイルです。 IBでストーリーボードファイルを編集するときに行う作業はすべて、XMLファイルにエンコードされています。 XMLファイルを自分で解析することで、必要な情報にアクセスできます。ストーリーボードファイル内のXMLデータを読み取ってXMLパーサに送り、DOMデータを取得することができます。次に、DOMを照会してデータを取得できます。ここには、テーブルビューコントローラを含むテストストーリーボードのXMLビューがあります:

<!--Table View Controller--> 
    <scene sceneID="hbL-mT-mfb"> 
     <objects> 
      <tableViewController id="XNl-aA-YKn" customClass="TableViewController" sceneMemberID="viewController"> 
       <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" id="lX1-Ry-xNl"> 
        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/> 
        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> 
        <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> 
        <prototypes> 
         <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="cell" rowHeight="100" id="4rn-ee-JoI"> 
          <rect key="frame" x="0.0" y="28" width="375" height="100"/> 
          <autoresizingMask key="autoresizingMask"/> 
          <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="4rn-ee-JoI" id="bdN-kI-rps"> 
           <rect key="frame" x="0.0" y="0.0" width="375" height="99"/> 
           <autoresizingMask key="autoresizingMask"/> 
          </tableViewCellContentView> 
         </tableViewCell> 
        </prototypes> 
        <connections> 
         <outlet property="dataSource" destination="XNl-aA-YKn" id="GlZ-SO-7gG"/> 
         <outlet property="delegate" destination="XNl-aA-YKn" id="gqq-QI-tZD"/> 
        </connections> 
       </tableView> 
      </tableViewController> 
      <placeholder placeholderIdentifier="IBFirstResponder" id="RCX-w1-742" userLabel="First Responder" sceneMemberID="firstResponder"/> 
     </objects> 
     <point key="canvasLocation" x="118" y="798"/> 
    </scene> 

このようにしないでください。

+0

心配しないでください。私はそのようにはしません。私がやっていることは、さまざまなコントロールパネルの長いシリーズの表示を管理するためにテーブルビューを使用していることです。それぞれは異なるコントロールセットを持つテーブル行です。たとえば、名前は単純なUITextFieldでもかまいませんが、曜日はUIPickerViewかもしれません。従って、それぞれは異なり、非常に異なるコントロールを含むことができる。私はそれを設定して各行に、その項目のコントロール用のハンドラを持つ関連するクラスがあるようにします。私はXMLパーザの事を使う前に "高さのテーブル"を使います。 –

+1

@MAGNAWS私は私の答えを編集しました。 – jox0

+0

ありがとうございます。私は完全でよく書かれた応答に感謝します。私は緑色のチェックをしますが、それを学び、私のユースケースと比較する機会があるまで、私はそれを使用するという保証はありません。最初の紅潮では、私のアプローチよりも少し複雑に思えますが、私はそれをどのように適用するかを理解することができます。基本的なやり方は、これらのさまざまなパネルの記述プロセスを簡素化したいということです。私の以前のアプリでは、私は高さのセットと一緒にインスタンス化された別の.xibファイルを持っていました。それはあまりにも私のために関与していた。 –

関連する問題