12

UITableViewカスタムセルとカスタムヘッダーがあります。編集時にセルを 1 つ移動すると、ヘッダー ビューにポップアップ表示されます。すべてのセルの上にヘッダー ビューを表示するにはどうすればよいですか?

違いが生じる場合に備えて、アプリはストーリーボードを使用します。

見た目はこんな感じ?https://www.dropbox.com/s/wg8oiar0d9oytux/iOS%20SimulatorScreenSnapz003.mov

これは私のコードです:

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

    int handleSection = [self sectionToHandle:indexPath.section];

    switch (handleSection)
    {
        case PrivateLists:
        {
            if (tableView.isEditing && (indexPath.row == self.privateLists.count))
            {
                cell.textField.text = NSLocalizedString(@"Lägg till ny lista", nil);
                cell.textField.enabled = NO;
                cell.textField.userInteractionEnabled = NO;
                cell.accessoryType = UITableViewCellAccessoryNone;
                cell.editingAccessoryView.hidden = YES;
            }
            else
            {
                List *list = [self.privateLists objectAtIndex:indexPath.row];
                cell.textField.text = list.name;
                cell.textField.enabled = YES;
                cell.textField.userInteractionEnabled =YES;
                cell.backgroundColor = [UIColor clearColor];

                cell.onTextEntered = ^(NSString* enteredString){
                    list.name = enteredString;
                    UpdateListService *service = [[UpdateListService alloc]initServiceWithList:list];
                    [service updatelistOnCompletion:
                     ^(BOOL success){
                         DLog(@"Updated list");

                         NSIndexPath *newPath = [NSIndexPath indexPathForRow:0 inSection:indexPath.section];
                         [self.tableView moveRowAtIndexPath:indexPath toIndexPath:newPath];

                         [self moveListToTop:list.ListId newIndexPath:newPath];
                         justMovedWithoutSectionUpdate = YES;
                     }
                                                    onError:
                     ^(NSError *error){
                         [[ActivityIndicator sharedInstance] hide];
                         [[ErrorHandler sharedInstance]handleError:error fromSender:self];
                     }];
                };
            }
        }
            break;
        default:
            return 0;
            break;
    }

    return cell;
}

-(UIView *)tableView:(UITableView *)aTableView viewForHeaderInSection:(NSInteger)section
{
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 22)];

    UILabel *textLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 300, 21)];
    [textLabel setFont:[[AXThemeManager sharedTheme]headerFontWithSize:15.0]];
    [textLabel setTextColor:[[AXThemeManager sharedTheme]highlightColor]];
    [textLabel setText:@"SECTION TITLE"];
    [textLabel setBackgroundColor:[UIColor clearColor]];

    UIImageView *backgroundView = [[UIImageView alloc]initWithImage:[AXThemeManager sharedTheme].tableviewSectionHeaderBackgroundImage];
    [backgroundView setFrame:view.frame];
    [view addSubview:backgroundView];
    [view sendSubviewToBack:backgroundView];
    [view addSubview:textLabel];

    return view;
}

- (float)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 22;
}

- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 44;
}
[...]
4

5 に答える 5

10

朗報です!2 つの異なる方法で問題を修正/回避することができました (以下を参照)。

これは確かにOSのバグだと思います。あなたがしていることは、( を使用して) 移動したmoveRowAtIndexPath:セルを z オーダーのヘッダー セルの上 (前) に配置する原因となります。

OS 5 および 6 で、UITextFields があるセルとないセル、および tableView の編集モードのオンとオフを使用して、問題を再現することができました (ビデオでは編集モードになっていることに気付きました)。また、標準のセクション ヘッダーを使用している場合でも発生します。

ポール、あなたはコメントの 1 つで次のように述べています。

reloadData の実行中に、ローダーを使用してテーブルを「ロック」して、ひどく解決しました

「ローダーを使用してテーブルをロックする」とはどういう意味かわかりませんが、reloadDataafterを呼び出すとmoveRowAtIndexPath:問題が解決すると判断しました。それはあなたがしたいことではありませんか?

[self.tableView moveRowAtIndexPath:indexPath toIndexPath:newPath];
//[self.tableView reloadData];
// per reply by Umka, below, reloadSections works and is lighter than reloadData:
[self reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationNone];

あなたがそれをしたくない場合は、私には少しハッキーに感じる別の解決策がありますが、うまくいくようです(iOS 5以降):

__weak UITableViewCell* blockCell = cell;  // so we can refer to cell in the block below without a retain loop warning.
...
cell.onTextEntered = ^(NSString* sText)
{
    // move item in my model
    NSIndexPath *newPath = [NSIndexPath indexPathForRow:0 inSection:indexPath.section];
    [self.itemNames removeObjectAtIndex:indexPath.row];
    [self.itemNames insertObject:sText atIndex:0];

    // Then you can move cell to back
    [self.tableView moveRowAtIndexPath:indexPath toIndexPath:newPath];
    [self.tableView sendSubviewToBack:blockCell];  // a little hacky

    // OR per @Lombax, move header to front
    UIView *sectionView = [self.tableView headerViewForSection:indexPath.section];
    [self.tableView bringSubviewToFront:sectionView];
于 2012-12-30T21:51:20.557 に答える
6

バグです。次の行の後に追加することで、すぐに解決できます。

[self.tableView moveRowAtIndexPath:indexPath toIndexPath:newPath];

この行:

UIView *sectionView = [self.tableView headerViewForSection:indexPath.section];
[self.tableView bringSubviewToFront:sectionView];
于 2013-01-02T16:09:52.563 に答える
3

解決策ではありませんが、コードには多くの問題があります。あなたがそれらを修正するとどうなるか誰が知っていますか;)

(1)次の行の後にセルがnilになっている可能性があります。

ListCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

次のようになります。

ListCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
                cell = [[[ListCell alloc] initWithStyle:style
                                                    reuseIdentifier:cellIdentifier] autorelease];
}

(2)-(UIView *)tableView:(UITableView *)aTableView viewForHeaderInSection:(NSInteger)sectionでの2つのメモリリーク

->>修正(ラベルをサブビューとして追加すると、+ 1 refを取得します)。

UILabel *textLabel = [[[UILabel alloc] initWithFrame:CGRectMake(10, 0, 300, 21)] autorelease];

->>修正(ビューをサブビューとして追加すると、+ 1 refを取得します)。

UIImageView *backgroundView = [[[UIImageView alloc]initWithImage:[AXThemeManager sharedTheme].tableviewSectionHeaderBackgroundImage] autorelease];

(3)欠陥ではありませんが、これはあなたを助けるかもしれません。[tablereloadData]の代わりにこれを使用してみてください。それは物事をうまくアニメーション化することを可能にし、テーブルを更新するためのそれほどハードコアな方法ではありません。私はそれがはるかに軽量であると確信しています。または、他の「更新」メソッドを探してみてください。例で行を削除しない場合、[updateRowsFrom:idxFrom to:idxTo]のようなものが役立ちます。

[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0]
                              withRowAnimation:UITableViewRowAnimationAutomatic];
于 2012-12-30T22:28:00.293 に答える
0
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {

  float  heightForHeader = 40.0;
    if (scrollView.contentOffset.y<=heightForHeader&&scrollView.contentOffset.y>=0) {
        scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0);
    } else if (scrollView.contentOffset.y>=heightForHeader) {
        scrollView.contentInset = UIEdgeInsetsMake(-heightForHeader, 0, 0, 0);
    }

}
于 2014-02-10T11:58:34.127 に答える