1

現在、iPhone 用の音楽プレーヤー アプリケーションを作成しようとしています。デザインの一部は、曲リストの単一のエントリをスワイプして追加のオプションを表示する機能です (iOS 7 の Mail.app のように)。

カスタム UIScrollView と 2 つの UIView (1 つは実際のコンテンツ用、もう 1 つは "background-menu" 用) を含むカスタム UITableViewCell の助けを借りてこれを実現しました。UIScrollView が TableViewCells のすべてのタッチを取得しているように見えたため、実際に曲を再生するオプションが無効になったため、タッチイベントを転送しました (たとえば、ここで提案されているように)。

CellScrollView.m

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    if (![self isDragging]){
        [[self superview] touchesBegan:touches withEvent:event];
    }
    [super touchesBegan: touches withEvent: event];
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    if (![self isDragging]){
        [[self superview] touchesMoved:touches withEvent:event];
    }
    [super touchesMoved: touches withEvent: event];
}

-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event{
    if (![self isDragging]){
        [[self superview] touchesCancelled:touches withEvent:event];
    }
    [super touchesCancelled: touches withEvent: event];
}

- (void) touchesEnded: (NSSet *) touches withEvent: (UIEvent *) event{
    if (![self isDragging]){
        [[self superview] touchesEnded:touches withEvent:event];
    }
    [super touchesEnded: touches withEvent: event];
}

今、私の問題は次のとおりです。リスト内のセルを押したままにしてスクロールを開始すると、メディアプレーヤーが(期待どおりに)再生を開始しません。しかし、リストの他のエントリをタップすると、タップしたタイトルではなく、最初に押したままにしてからスクロールを開始したタイトルが再生されます。これは、スクロールせず、タップ アンド ホールドの後にタップしてスクロールを停止した場合にのみ発生します (これにより、ログに「スクロール中に予期しないタッチ フェーズ」が表示されます。これが最終的にタップをキャンセルするものだと思います。 -所有)。

この動作を修正する方法はありますか (通常の UITableViewCell を使用するだけですべて正常に動作するため、UIScrollView がすべてを壊すと思います)。

4

1 に答える 1

1

私はあなたとまったく同じ問題を抱えていました。

それを修正するために私がしたことは、テーブルビューを含むビューコントローラーをセルのデリゲートとして設定することです。

次に、セルにデリゲート セレクターを設定して、テーブルビューを含むビュー コントローラーにタップ ジェスチャを渡します。

@class GameSequenceCell;

@protocol CustomCellDelegate <NSObject>
- (void)didSelectCell:(CustomCell *)sender;
@end

@interface CustomCell : UITableViewCell
/*
 * Some stuffs
 */
@end

次に、セルに UITapGestureRecognizer を直接追加しました。これは、セルの初期化時に行う必要があります。

- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier];
    if (self) [self prepareForFirstUse];
    return self;
}

-(id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) [self prepareForFirstUse];
    return self;
}

-(void)prepareForFirstUse
{
    /*
     * The tap gesture recognizer is needed to be able to tap on the scroll view in the cell
     * Calling the singleTapGestureCaptured will trigger the tableView:didSelectRowAtIndexPath:
     * of the EventPanelVC tableview delegate.
     */
    UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapGestureCaptured:)];
    [self addGestureRecognizer:singleTap];
}

次に、セルに実装しました:

- (void)singleTapGestureCaptured:(UITapGestureRecognizer *)gesture
{
    [self.delegate didSelectCell:self];
}

デリゲートは、セルがあるテーブルビューを含むビュー コントローラーです。

これで、セル内のすべてのタップ ジェスチャがキャッチされ、View Controller で実装します。

- (void)didSelectCell:(CustomCell *)sender;
{
    NSIndexPath *indexPathOfTouchedCell = [self.fetchedResultsController indexPathForObject:sender.object];
    if(indexPathOfTouchedCell)
    {
        [self.tableView selectRowAtIndexPath:indexPathOfTouchedCell animated:YES scrollPosition:UITableViewScrollPositionNone];
        [self tableView:self.tableView didSelectRowAtIndexPath:indexPathOfTouchedCell];
    }
} 

これが私がこの問題を修正した方法です。

于 2013-10-25T09:00:37.913 に答える