UITcrollView里面的UITableViewCell触摸检测

mas*_*gar 22 iphone uitableview uiscrollview

我有一个包含8个自定义单元格的tableview.在第8个单元格中,我添加了一个启用了分页的scrollView,这样我就可以显示第1页和第2页(或3,4 ... 10)而没有非常高的单元格.

问题是scrollView我不能使用didSelectRowAtIndexPath,因为单元格在scrollView后面,所以我试图检测scrollView tap(不刷卡).

我玩touchesBegan和touchesEnded,但他们从未被调用过(我知道触摸仅与UIView合作,但也许.....)

非常感谢任何帮助.

谢谢,马克斯

Ana*_*sia 78

苹果公司建议在这种情况下使用技巧,在他们的WWDC 2014会话 "高级滚动视图"中(参见从8:10开始的演示):

[cell.contentView addSubview:_scrollView];
[_scrollView setUserInteractionEnabled:NO];
[cell.contentView addGestureRecognizer:_scrollView.panGestureRecognizer];
Run Code Online (Sandbox Code Playgroud)

这就是需要做的所有事情,无需覆盖touchesBegan:,touchesMoved:以及其他人.


我用的解决方案基础上,压倒一切的touchesBegan:,touchesMoved:,touchesEnded:touchesCancelled:前面,但有时它造成一个奇怪的现象:当选择特定的细胞,方法-tableView:didSelectRowAtIndexPath:被称为具有不同indexPath细胞.

Apple的解决方案到目前为止没有任何副作用,看起来更优雅.

  • 这个解决方案的唯一缺点是它禁止在滚动视图内的任何`UIButton'上进行交互.我回过头来使用`touchesBegan:`和`touchesEnded:`我自己. (5认同)

Dan*_*Liu 14

此外,还有一个优雅的分辨率:

从创建一个的UIScrollView子类,并重写下列方法

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

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

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

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    [[self superview]touchesEnded:touches withEvent:event];
}
Run Code Online (Sandbox Code Playgroud)

每一个接触传递到滚动视图的上海华盈,然后didSelectRowAtIndexPath方法会被调用.


mas*_*gar 5

解决了子类化uitableviewcell和uiscrollview的问题.

它符合我的需求.希望它可以提供帮助.

马克斯


myScrollView.h


#import <UIKit/UIKit.h>
@interface myScrollView : UIScrollView {
}

@end

Run Code Online (Sandbox Code Playgroud)

myScrollView.m


#import "myScrollView.h"
@implementation myScrollView


- (id)initWithFrame:(CGRect)frame {

    return [super initWithFrame:frame];
}

- (void) touchesEnded: (NSSet *) touches withEvent: (UIEvent *) event 
{   
    NSLog(@"touch scroll");
    // If not dragging, send event to next responder
    if (!self.dragging) 
        [self.nextResponder touchesEnded: touches withEvent:event]; 
    else
        [super touchesEnded: touches withEvent: event];
}
Run Code Online (Sandbox Code Playgroud)

myCell.h


#import <UIKit/UIKit.h>


@interface myCell : UITableViewCell {

}

@end
Run Code Online (Sandbox Code Playgroud)

myCell.m



#import "myCell.h"


@implementation myCell


- (id)initWithFrame:(CGRect)frame {

    return [super initWithFrame:frame];
}

- (void) touchesEnded: (NSSet *) touches withEvent: (UIEvent *) event 
{   
    NSLog(@"touch cell");
    // If not dragging, send event to next responder
    [super touchesEnded: touches withEvent: event];
}
Run Code Online (Sandbox Code Playgroud)

RootViewController.h



#import <UIKit/UIKit.h>

@class myCell;
@class myScrollView;

@interface RootViewController : UITableViewController {

    myCell *cell;
    myScrollView *scrollView;
}

@end
Run Code Online (Sandbox Code Playgroud)

RootViewController.m



#pragma mark -
#pragma mark Table view data source

// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}


// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 3;
}


// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";

    // my custom cell
    cell = [[myCell alloc] init];
    if (cell == nil) {
        cell = [[[myCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }


    // the custom scroll view
    scrollView = [[myScrollView alloc] initWithFrame:cell.frame];
    scrollView.contentSize = CGSizeMake(640, 40);
    [cell.contentView addSubview:scrollView];

    //something to add in scrollView
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 150, 20)];
    label.text = @"some text";
    [scrollView addSubview:label];

    // Configure the cell.

    return cell;
}
Run Code Online (Sandbox Code Playgroud)


mas*_*gar -1

我找到了满足我需求的最简单的解决方案:

子类 UIScrollView TouchsEnded 方法并发布通知。

在UITableview中在viewdidAppear中添加一个观察者(在viewdiddisappear中将其删除)来调用调用tableview didSelectRowForIndexPath的函数。

像这样的东西(快速版本)

// myScrollView.swift

import UIKit

class myScrollView: UIScrollView {
    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
            NSNotificationCenter.defaultCenter().postNotificationName("selectTVRow", object: nil)
    }
}
Run Code Online (Sandbox Code Playgroud)

在你的表视图中:

// ItemsList.swift

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "selectFourthRow", name: "selectTVRow", object: nil)
    }

    override func viewDidDisappear(animated: Bool) {
        super.viewDidDisappear(animated)
        NSNotificationCenter.defaultCenter().removeObserver(self, name: "selectfourthrow", object: nil)
    }

    func selectFourthRow() {
        let rowToSelect:NSIndexPath = NSIndexPath(forRow: 4, inSection: 0);
        self.tableView(self.tableView, didSelectRowAtIndexPath: rowToSelect);
    }

    /*
    .... rest of your tableview Datasource and Delegate methods...
    numberOfSectionsInTableView, numberOfRowsInSection, cellForRowAtIndexPath
    */
Run Code Online (Sandbox Code Playgroud)