web-dev-qa-db-ja.com

iPhone UITableView-削除ボタン

UITableViewの「スワイプして削除」機能を使用しています。

問題は、アイテムごとに作成されたカスタマイズされたUITableViewCellを使用していることです。

- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

削除ボタンの位置を変更する必要があります(単に10pxほど左に移動するだけです)。これを行うにはどうすればよいですか?

セルを作成するための既存のコードは次のとおりです。

- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"cellForRowAtIndexPath");
#if USE_CUSTOM_DRAWING
    const NSInteger TOP_LABEL_TAG = 1001;
    const NSInteger BOTTOM_LABEL_TAG = 1002;
    UILabel *topLabel;
    UILabel *bottomLabel;
#endif

    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
    {
        //
        // Create the cell.
        //
        cell =
        [[[UITableViewCell alloc]
          initWithFrame:CGRectZero
          reuseIdentifier:CellIdentifier]
         autorelease];

#if USE_CUSTOM_DRAWING


        const CGFloat LABEL_HEIGHT = 20;
        UIImage *image = [UIImage imageNamed:@"trans_clock.png"];

        //
        // Create the label for the top row of text
        //
        topLabel =
        [[[UILabel alloc]
          initWithFrame:
          CGRectMake(
                     image.size.width + 2.0 * cell.indentationWidth,
                     0.5 * (aTableView.rowHeight - 2 * LABEL_HEIGHT),
                     aTableView.bounds.size.width -
                     image.size.width - 4.0 * cell.indentationWidth
                     ,
                     LABEL_HEIGHT)]
         autorelease];
        [cell.contentView addSubview:topLabel];

        //
        // Configure the properties for the text that are the same on every row
        //
        topLabel.tag = TOP_LABEL_TAG;
        topLabel.backgroundColor = [UIColor clearColor];
        topLabel.textColor = fontColor;
        topLabel.highlightedTextColor = [UIColor colorWithRed:1.0 green:1.0 blue:0.9 alpha:1.0];
        topLabel.font = [UIFont systemFontOfSize:[UIFont labelFontSize]];

        //
        // Create the label for the top row of text
        //
        bottomLabel =
        [[[UILabel alloc]
          initWithFrame:
          CGRectMake(
                     image.size.width + 2.0 * cell.indentationWidth,
                     0.5 * (aTableView.rowHeight - 2 * LABEL_HEIGHT) + LABEL_HEIGHT,
                     aTableView.bounds.size.width -
                     image.size.width - 4.0 * cell.indentationWidth
                     ,
                     LABEL_HEIGHT)]
         autorelease];
        [cell.contentView addSubview:bottomLabel];

        //
        // Configure the properties for the text that are the same on every row
        //
        bottomLabel.tag = BOTTOM_LABEL_TAG;
        bottomLabel.backgroundColor = [UIColor clearColor];
        bottomLabel.textColor = fontColor;
        bottomLabel.highlightedTextColor = [UIColor colorWithRed:1.0 green:1.0 blue:0.9 alpha:1.0];
        bottomLabel.font = [UIFont systemFontOfSize:[UIFont labelFontSize] - 2];

        //
        // Create a background image view.
        //
        cell.backgroundView =
        [[[UIImageView alloc] init] autorelease];
        cell.selectedBackgroundView =
        [[[UIImageView alloc] init] autorelease];
#endif
    }

#if USE_CUSTOM_DRAWING
    else
    {
        topLabel = (UILabel *)[cell viewWithTag:TOP_LABEL_TAG];
        bottomLabel = (UILabel *)[cell viewWithTag:BOTTOM_LABEL_TAG];
    }
    topLabel.text  = @"Example Text";
    topLabel.textColor = fontColor;

    bottomLabel.text = @"More Example Text";
    bottomLabel.textColor = fontColor;

    //
    // Set the background and selected background images for the text.
    // Since we will round the corners at the top and bottom of sections, we
    // need to conditionally choose the images based on the row index and the
    // number of rows in the section.
    //
    UIImage *rowBackground;
    UIImage *selectionBackground;
    NSInteger sectionRows = [aTableView numberOfRowsInSection:[indexPath section]];
    NSInteger row = [indexPath row];
    if (row == 0 && row == sectionRows - 1)
    {
        rowBackground = [UIImage imageNamed:@"topAndBottomRow.png"];
        selectionBackground = [UIImage imageNamed:@"topAndBottomRowSelected.png"];
    }
    else if (row == 0)
    {
        rowBackground = [UIImage imageNamed:@"topRow.png"];
        selectionBackground = [UIImage imageNamed:@"topRowSelected.png"];
    }
    else if (row == sectionRows - 1)
    {
        rowBackground = [UIImage imageNamed:@"bottomRow.png"];
        selectionBackground = [UIImage imageNamed:@"bottomRowSelected.png"];
    }
    else
    {
        rowBackground = [UIImage imageNamed:@"middleRow.png"];
        selectionBackground = [UIImage imageNamed:@"middleRowSelected.png"];
    }
    ((UIImageView *)cell.backgroundView).image = rowBackground;
    ((UIImageView *)cell.selectedBackgroundView).image = selectionBackground;

    cell.imageView.image = [UIImage imageNamed:@"Example_Image.png"];
#else
    cell.text = @"Example";
#endif
    return cell;
}
27
Mick Walker

Iwatのコードは私には機能しません。しかし、これは機能します。

-(void)willTransitionToState:(UITableViewCellStateMask)state {
 
 [super willTransitionToState:state]; 
 
 if((state&UITableViewCellStateShowingDeleteConfirmationMask)== UITableViewCellStateShowingDeleteConfirmationMask){ 
 
 for(UIView * subview in self.subviews){
 
 if([[NSStringFromClass([subview class])isEqualToString:@ "UITableViewCellDeleteConfirmationControl"]){ 
 
 subview.hidden = YES; 
 subview.alpha = 0.0; 
} 
} 
} 
 } 
 
-(void)didTransitionToState:(UITableViewCellStateMask)state {
 
 [super didTransitionToState:state]; 
 
 if (state == UITableViewCellStateShowingDeleteConfirmationMask || state == UITableViewCellStateDefaultMask){
 for(UIView * subview in self.subviews){
 
 if([NSString FromClass([サブビュークラス])isEqualToString:@ "UITableViewCellDeleteConfirmationControl"]){
 
UIView * deleteButtonView =(UIView *)[subview.subviews objectAtIndex:0 ]; 
 CGRect f = deleteButtonView.frame; 
 f.Origin.x-= 20; 
 deleteButtonView.frame = f;
 
 subview.hidden = NO; 
 
 [UIView beginAnimations:@ "anim" context:nil]; 
 subview.alpha = 1.0; 
 [UIView commitAnimations]; 
} 
} 
} 
}
23
nonamelive

私にとってこれを解決する最良の方法は、_MyCell:UITableViewCell_の-(void)layoutSubviewsをオーバーライドすることでした

ここでは、[削除]ボタンのカスタム位置だけでなく、編集コントロールと並べ替えコントロールの位置もEditモードで確認できます。

_- (void)layoutSubviews
{
    [super layoutSubviews];

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:0.0f];

    for (UIView *subview in self.subviews) {


        if ([NSStringFromClass([subview class]) isEqualToString:@"UITableViewCellDeleteConfirmationControl"]) { 
            CGRect newFrame = subview.frame;
            newFrame.Origin.x = 200;
            subview.frame = newFrame;
        }
        else if ([NSStringFromClass([subview class]) isEqualToString:@"UITableViewCellEditControl"]) {             
            CGRect newFrame = subview.frame;
            newFrame.Origin.x = 100;
            subview.frame = newFrame;
        }
        else if ([NSStringFromClass([subview class]) isEqualToString:@"UITableViewCellReorderControl"]) {             
            CGRect newFrame = subview.frame;
            newFrame.Origin.x = 200;
            subview.frame = newFrame;
        }
    }
    [UIView commitAnimations];
}
_
58
Remizorrr

削除ボタンの実際の外観を変更することはできませんでしたが、テキストを変更できます。おそらくこれを使用して、探している効果を得ることができますか?

UITableViewDelegateプロトコルの次のメンバーを確認してください。

- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath

さらに、UITableViewCellをサブクラス化して以下をオーバーライドすることにより、削除ボタンが表示されていることを検出できます。

- (void)willTransitionToState:(UITableViewCellStateMask)state
- (void)didTransitionToState:(UITableViewCellStateMask)state

どちらの場合も、削除ボタンが表示されているときの状態マスクはUITableViewCellStateShowingDeleteConfirmationMaskになります。

うまくいけば、これらの手がかりはあなたを正しい方向に向けることでしょう。

2
Ethan

私は一見するとハックに見えますが、トリックを行い、文書化されていないAPIに依存しないソリューションを使用します。

/**
 * Transition to state
 */
-(void)willTransitionToState:(UITableViewCellStateMask)state {

    if(state & UITableViewCellStateShowingDeleteConfirmationMask)
        _deleting = YES;
    else if(!(state & UITableViewCellStateShowingDeleteConfirmationMask))
        _deleting = NO;
    [super willTransitionToState:state];

}

/**
 * Reset cell transformations
 */
-(void)resetCellTransform {

    self.transform = CGAffineTransformIdentity;
    _background.transform = CGAffineTransformIdentity;
    _content.transform = CGAffineTransformIdentity;
}

/**
 * Move cell around if we are currently in delete mode
 */
-(void)updateWithCurrentState {

    if(_deleting) {

        float x = -20;
        float y = 0;
        self.transform = CGAffineTransformMakeTranslation(x, y);
        _background.transform = CGAffineTransformMakeTranslation(-x, -y);
        _content.transform = CGAffineTransformMakeTranslation(-x, -y);
    }
}

-(void)setFrame:(CGRect)frame {

    [self resetCellTransform];
    [super setFrame:frame];
    [self updateWithCurrentState];
}

-(void)layoutSubviews {

    [self resetCellTransform];
    [super layoutSubviews];
    [self updateWithCurrentState];
}

基本的に、これはセルの位置をシフトし、可視部分を再調整します。 WillTransitionToStateは、セルが削除モードかどうかを示すインスタンス変数を設定するだけです。電話を横向きに、またはその逆に回転させることをサポートするには、setFrameのオーバーライドが必要でした。ここで、_backgroundはセルの背景ビュー、_contentはセルのcontentViewに追加されたビューで、すべてのラベルなどを保持しています。

2
Stefan

「削除ボタンを左に10ピクセル移動する」方法がわかりません。ただし、UITableViewCellサブクラスからのwillTransitionToState:メッセージをリッスンすることにより、移動できない削除ボタンの静的な位置を中心にテーブルセルのカスタムコンテンツをアニメーション化できます。参照 こちら =。

ドキュメントを引用するには:

UITableViewCellのサブクラスは、このメソッドを実装して、状態が変化しているときにセルへの追加の変更をアニメーション化できます。 UITableViewCellは、セルが通常の状態(デフォルト)から編集モードへなど、状態間で遷移するたびにこのメソッドを呼び出します。カスタムセルは、新しい状態で表示される新しいビューをセットアップして配置できます。次に、セルは、これらの新しいビューを新しい状態の最終的な場所に配置できるlayoutSubviewsメッセージ(UIView)を受け取ります。このメソッドをオーバーライドする場合、サブクラスは常にスーパーを呼び出す必要があります。

あなたが探しているのはUITableViewCellStateShowingDeleteConfirmationMaskの値です。これは、UITableViewCellサブクラスを作成する方がよい場合があるため、コントローラーからカスタムセルのインスタンスを作成するだけです。次に、セルはanimateLeftおよびanimateRightのように自分自身を調整し、独自のサブビューを調整する内部処理を処理できます。

1
slf

最終的な解決策はわかりませんが、私が試した限りでは、次のコードが役立つかもしれません。

// subclass UITableViewCell

- (void)willTransitionToState:(UITableViewCellStateMask)state
{
    [super willTransitionToState:state];

    if ((state & UITableViewCellStateShowingDeleteConfirmationMask) == UITableCellStateShowingDeleteConfirmationMask)
    {
        for (UIView *subview in self.subviews)
        {
            if ([NSStringFromClass([subview class]) isEqualToString:@"UITableViewCellDeleteConfirmationControl"])
            {
                subview.hidden = YES;
                subview.alpha = 0;
            }
        }
    }
}

- (void)didTransitionToState:(UITableViewCellStateMask)state
{
    [super willTransitionToState:state];

    if ((state & UITableViewCellStateShowingDeleteConfirmationMask) == UITableCellStateShowingDeleteConfirmationMask)
    {
        for (UIView *subview in self.subviews)
        {
            if ([NSStringFromClass([subview class]) isEqualToString:@"UITableViewCellDeleteConfirmationControl"])
            {
                subview.frame = CGRectMake(subview.frame.Origin.x - 10, subview.frame.Origin.y, subview.frame.size.width, subview.frame.size.height);
                subview.hidden = NO;

                [UIView beginAnimations:@"anim" context:nil];
                subview.alpha = 1;
                [UIView commitAnimations];
            }
        }
    }
}
0
iwat