40

Interface Builderで作成された静的テーブルがあり、6つのセクションがあり、すべて行数が異なります。次に、行数を変えて7番目のセクションを追加します。

まず、Xcodeによって挿入された標準のテーブルデリゲートメソッドのコメントを解除するとすぐに、self.tableView.tableHeaderView=containerViewでクラッシュします。ここで、テーブルにヘッダーを追加しました。

さらに重要なことに、次のコードでクラッシュします

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 7;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (section==6) {
        return 4;
    } else {
        return [super tableView:tableView numberOfRowsInSection:section];
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{/*
    if (indexPath.section == 6) {
        static NSString *CellIdentifier = @"cellWireless";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

        // Configure the cell...

        return cell;
    }*/
    return [super tableView:tableView cellForRowAtIndexPath:indexPath];
}

既存のセクションをそのままにして、セルをいくつか追加してセクションを追加するにはどうすればよいですか?

4

7 に答える 7

50

動的セルを静的セルテーブルに追加するには、indexPathを持つすべてのUITableViewデリゲートメソッドをオーバーライドする必要があります。

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

-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath

-(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath

-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
-(NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
     return NO;
}

-(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{     
     return NO;
}

-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{     
     return UITableViewCellEditingStyleNone;     
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
     int section = indexPath.section;

     // if dynamic section make all rows the same height as row 0
     if (section == self.dynamicSection) {
          return [super tableView:tableView heightForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]];
     } else {
          return [super tableView:tableView heightForRowAtIndexPath:indexPath];
     }
}

- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath
{
     int section = indexPath.section;

     // if dynamic section make all rows the same indentation level as row 0
     if (section == self.dynamicSection) {
          return [super tableView:tableView indentationLevelForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]];
     } else {
          return [super tableView:tableView indentationLevelForRowAtIndexPath:indexPath];
     }
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
     if (section == self.dynamicSection ) {
          return [self.dataListArray count];
     } else {
          return [super tableView:tableView numberOfRowsInSection:section];
     }
}

-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
     int section = indexPath.section;
     int row = indexPath.row;


     if (section == self.dynamicSection) {
          // make dynamic row's cell
          static NSString *CellIdentifier = @"Dynamic Cell";
          UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

          if (!cell) {
               cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
          }

          cell.textLabel.text = [self.dataListArray objectAtIndex:row];
          return cell;
    } else {
          return [super tableView:tableView cellForRowAtIndexPath:indexPath];
    }
}

すべてのメソッドをオーバーライドすると、テーブルが機能し始めます。静的セクションを参照する場合は、[super]を参照してください。

于 2012-04-08T07:00:14.280 に答える
11

ダレンの答えは私に何がうまくいくかについての考えを私に与えました、しかし私はすべての単一のtableViewデリゲートメソッドを実装するまで行く必要はありませんでした。実際には、numberOfRowsInSectionとcellForRowAtIndexPathをオーバーライドするだけで済みます。

最初に、Interface Builderで静的テーブルを定義しました。セクションは4つで、セクションごとに2〜4個のセルがあります。セクション0、2、3は静的で、IBの場合とまったく同じように見えるようにしたいのですが、セクション1には、値の配列に基づいて各セルにカスタム表示するカスタムの行数を設定したいと思いました。

静的テーブルのビューコントローラで、動的セクションに返されるセルの数を上書きしますが、他のすべてのセクションのデフォルトを受け入れます(これらはIB値にフォールバックします)。cellForRowAtIndexPathについても同じことを行い、セクション1を除くすべてのセクションの[super]実装を返します。

@implementation myMostlyStaticTableViewController
@synthesize myFancyArray;

- (NSInteger) tableView:(UITableView *) tableView numberOfRowsInSection:(NSInteger) section
{
    if (section == 1)
        return [myFancyArray count]; // the number of rows in section 1
    else
        return [super tableView:tableView numberOfRowsInSection:section];
}

- (UITableViewCell *) tableView:(UITableView *) tableView cellForRowAtIndexPath:(NSIndexPath *) indexPath
{
    // for cells not in section 1, rely on the IB definition of the cell
    if (indexPath.section != 1)
        return [super tableView:tableView cellForRowAtIndexPath:indexPath];

    // configure a task status cell for section 1
    MyCustomTableViewCell *cell;
    cell = [tableView dequeueReusableCellWithIdentifier:@"myCustomCell"];
    if (!cell)
    {
        // create a cell
        cell = [[MyCustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"myCustomCell"];
    }
    cell.myCustomLabel.text = [myFancyArray objectAtIndex:indexPath.row];
    return cell;
}
@end

そしてもちろん、カスタムセルが必要です。

@implementation MyCustomTableViewCell

- (UITableViewCell *) initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    // initialize cell and add observers
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (!self)
        return self;
    self.clipsToBounds = YES;
    self.selectionStyle = UITableViewCellSelectionStyleNone;

    // configure up some interesting display properties inside the cell
    _label = [[UILabel alloc] initWithFrame:CGRectMake(20, 9, 147, 26)];
    _label.font = [UIFont fontWithName:@"HelveticaNeue-Medium" size:17];
    _label.textColor = [UIColor colorWithWhite:0.2 alpha:1];
    [self.contentView addSubview:_label];

    return self;
}

@end
于 2012-10-08T02:18:11.550 に答える
9

回答はSwiftに投稿しますが、Objective-Cでも機能するはずです。

UITableViewController私の経験では、これらのメソッドを次のようにオーバーライドするだけで十分でした。

tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
tableView(tableView: UITableView, indentationLevelForRowAtIndexPath indexPath: NSIndexPath) -> Int

UITableViewCellテーブルビューにカスタムテーブルビューセルを含める場合は、nibを使用してのサブクラスを作成し、テーブルビューに登録する必要があります。

私のコントローラー全体は次のようになります。

var data = ["Ahoj", "Hola", "Hello"]

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.registerNib(UINib(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: "reuseIdentifier")
}

// MARK: - Table view data source

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if section == 1 {
        return data.count
    }
    return super.tableView(tableView, numberOfRowsInSection: section)
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    if indexPath.section == 1 {
        let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) as! CustomCell
        cell.titleLabel.text = data[indexPath.row]
        return cell
    }
    return super.tableView(tableView, cellForRowAtIndexPath: indexPath)
}

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return 44
}

override func tableView(tableView: UITableView, indentationLevelForRowAtIndexPath indexPath: NSIndexPath) -> Int {
    return 0
}

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    tableView.deselectRowAtIndexPath(indexPath, animated: true)
    if indexPath.section == 1 {
        print(data[indexPath.row])
    }
}

@IBAction func addItem() {
    data.append("Item \(data.count)")
    tableView.beginUpdates()
    tableView.insertRowsAtIndexPaths([NSIndexPath(forRow: data.count - 1, inSection: 1)], withRowAnimation: .Left)
    tableView.endUpdates()
}

@IBAction func removeItem() {
    if data.count > 0 {
        data.removeLast()
        tableView.beginUpdates()
        tableView.deleteRowsAtIndexPaths([NSIndexPath(forRow: data.count, inSection: 1)], withRowAnimation: .Left)
        tableView.endUpdates()
    }
}
于 2015-12-01T12:01:47.863 に答える
7

@Darrenの優れた回答に基づいて更新された回答を追加すると思いました。ほとんどのデリゲートメソッドは必須ではありません。そこで、必要なものを追加しました。必要に応じて、nibファイルを使用しても、カスタムセルを簡単に追加できます。この画像は、3つのセクションを持つ静的テーブルを示しています。最後のセクションは、実行時の動的です。これは非常に便利です。これはios7BTWで動作しています。

ここに画像の説明を入力してください

#define DYNAMIC_SECTION 2

#import "MyTableViewController.h"

@interface MyTableViewController ()
@property (strong, nonatomic)NSArray *myArray;
@end

@implementation MyTableViewController

- (id)initWithCoder:(NSCoder *)aDecoder
    {
        if (self = [super initWithCoder:aDecoder]) {
            _myArray = @[@"ONE", @"TWO", @"THREE", @"FOUR"];
        }
        return self;
    }

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
        return [super numberOfSectionsInTableView:tableView];
    }

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        if (section != DYNAMIC_SECTION) {
            return [super tableView:tableView numberOfRowsInSection:section];
        }
        return [self.myArray count];
    }

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if (indexPath.section != DYNAMIC_SECTION) {
            return [super tableView:tableView cellForRowAtIndexPath:indexPath];
        }
        static NSString *id = @"MyCell";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:id];
        if (!cell) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:id];
        }
        cell.textLabel.text = self.myArray[indexPath.row];
        return cell;
    }

        // required
    -(NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        int section = indexPath.section;
        if (section == DYNAMIC_SECTION) {
            return [super tableView:tableView indentationLevelForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]];
        } else {
            return [super tableView:tableView indentationLevelForRowAtIndexPath:indexPath];
        }
    }

            // Not required
    - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
    {
        if (section != DYNAMIC_SECTION) {
            return [super tableView:tableView titleForHeaderInSection:section];
        }
        return @"some title";
    }
于 2014-07-16T20:25:38.647 に答える
0

UITableViewを動的にする必要があると思います。「不明な」行数があるため、デリゲートメソッドを次のように設定する可能性があります。

 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [someArray count];
}
于 2012-04-06T20:01:16.287 に答える
0

私はかなり面白いものを発見しました。それは「コメント」よりも答える価値があります。動的行を含むこの静的tableViewが機能していましたが、機能しなくなりました。理由は簡単です。私は以前持っていた

[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]

その後、StoryBoardでデザインし、アウトレットをUITableViewサブクラスにのみ設定するカスタムセルが必要/必要であると判断しました。だから私は他のテクニックを使いました

[super tableView:tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:indexPath.section]];

ここでの問題は、このセルが再利用されるため、一度に1つのセルしか表示されないことです。いつかあなたは何も見えないでしょう、それらはすべて空になります!スクロールすると、他のセルがすぐに表示されてから消えるのがわかります(ちらつきのように!)。

これは、私が(不可能な)可能性があることに気付くまで、私を真剣に狂わせました。さらに、やろうとしないでください

[super.tableView dequeueReusableCellWithIdentifier:CellIdentifier]

他の人が言ったように、これは常にnil静的なtableViewで返されるからです。

——— </ p>

だから私は何をすべきかわからない。私は「静的プロトタイプ」ルートを使用すると思います。

  • セクション3の行1に「31」などのセル識別子を含むプロトタイプテーブルビューを使用すると、次のようなことができます。
NSString*識別子=[NSStringstringWithFormat:@ "%d%d"、indexPath.section、indexPath.row];
cell = [tableView dequeueReusableCellWithIdentifier:identifier];
  • ヘッダーにもプロトタイプセルを使用します。セクション1のヘッダーのセル識別子に使用する"Cell1-Header"と、次のようになります。
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{{
    NSString*識別子=[NSStringstringWithFormat:@ "Cell%d-Header"、セクション];
    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    cell.contentViewを返します。
}

ここでの基本的なことは、常に静的なtableViewから始めることができるということですが、動的なものが必要になることに気付いた瞬間に、それをPrototypeに交換します(行は保持されますが、何をするのかは覚えていません)セクションで!)そしてこのKISSテクニックを使用してください。

于 2013-02-17T22:47:12.657 に答える
0

IBの「ファントム」セクションまたは行を使用して、より適切で簡単な解決策を見つけたと思います。

セクション7で使用するセルの最大数(たとえば10)がわかっている場合は、IBでセクション7を構成するときに、行数を10に設定する必要があります。

セクション内の10行すべてを使用する必要はありません。これは、次のように設定できます。

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

たとえば、section == 6(実際には7番目のセクション)のときに5を返すと、5行のみが表示されます。

私はそれが言葉の絶対的な意味で動的ではないことを認めますが、おそらくほとんどの場合を解決します。

于 2014-02-07T11:06:45.223 に答える