3D Touch 和 UITableViewCell

Posted

技术标签:

【中文标题】3D Touch 和 UITableViewCell【英文标题】:3D Touch and UITableViewCell 【发布时间】:2015-12-08 18:56:55 【问题描述】:

我在 iPhone 6s 上为 UITableViewController 添加了一些测试 3D Touch 功能。一般来说,它工作正常,但我能够观察到一些 2 个问题,我不确定发生了什么以及如何以正常方式解决它。

1) 我的单元格是可选择的,所以用户可以按下它或使用“3D Touch”。问题是当我对UITableViewCell 使用“Pop”和“Peek”时,它会被选中,我无法使用setSelected:setHighlighted: 方法以正常方式取消选择。即使在previewingContext:commitViewControllerpresentViewController 完成中,我也尝试在不同的地方取消选择它。他们什么都不做,细胞仍然保持在选定状态。我通过调用reviewingContext.sourceView 和其他给我选定单元格的临时代码检索选定的单元格,但这些方法不起作用。

所以问题是当用户应用“弹出”按钮时,是否有一种正常的方法可以取消选择(或者最好不选择)单元格?

2) 我还注意到,有时当我取消“Pop”手势并将单元格恢复到初始状态时(甚至没有调用 previewingContext:viewControllerForLocation 方法时)我的 UI 只是挂起并且根本不响应触摸。我需要杀了它才能让它工作。好像很奇怪,我查了这个Tutorial。它工作得很好,没有提到的问题,但他们不是在单元格上注册代表,而是在 UITableView 上注册代表,所以“弹出”手势突出显示整个 tableView,而不是单元格。

有什么想法吗?这里有什么问题?

这是我在测试UITableViewController 中实现 3D 触摸的方式,它符合 UIViewControllerPreviewingDelegate

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell

    let cell = tableView.dequeueReusableCellWithIdentifier("SomeDemoID",
        forIndexPath: indexPath) as! UITableViewCell

    // Some cell configuration

    if #available(ios 9.0, *) 
        if traitCollection.forceTouchCapability == .Available 
            self.registerForPreviewingWithDelegate(self, sourceView: cell)
        
     else  // Fallback on earlier versions

    return cell;



// MARK: - UIViewControllerPreviewingDelegate

    func previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController?
    
        // Just Test View Controller
        return UIViewController(nibName: nil, bundle: nil)
    

    func previewingContext(previewingContext: UIViewControllerPreviewing, commitViewController viewControllerToCommit: UIViewController)
    
        self.presentViewController(viewControllerToCommit, animated: true, completion: nil)
    

提前致谢!

【问题讨论】:

【参考方案1】: 在表格视图单元格中添加 3D Touch 的简单方法。无需一行代码

更多详情:https://github.com/yudiz-solutions/YM3DTouch

【讨论】:

【参考方案2】:

我注意到了同样的问题。 我认为这个问题是由重复注册引起的。 我添加了标志,然后问题就解决了。

请试试这个(我用的是Objective-C,所以请用swift重写)。

实现类别

@interface UITableViewCell (FourceTouchRegistered)

@property (nonatomic, assign) BOOL fourceTouchRegistered;

@end

#import "UITableViewCell+FourceTouchRegistered.h"
#import <objc/runtime.h>

@implementation UITableViewCell (FourceTouchRegistered)

- (void)setFourceTouchRegistered:(BOOL)fourceTouchRegistered

    objc_setAssociatedObject(self, @"fourceTouchRegistered", @(fourceTouchRegistered), OBJC_ASSOCIATION_ASSIGN);


- (BOOL)fourceTouchRegistered

    return [objc_getAssociatedObject(self, @"fourceTouchRegistered") boolValue];


@end

然后

    if(cell.fourceTouchRegistered == NO) 
        cell.fourceTouchRegistered = YES;
        if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) 
            [self registerForPreviewingWithDelegate:self sourceView:cell];
        
    

【讨论】:

【参考方案3】:

尝试检查您的预览 UIViewController 是否已经出现在您的 previewingContext(_:viewControllerForLocation:) 方法中。

类似

func previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController?

    if self.navigationController.presentedViewController.isKindOfClass(PreviewViewController) 
        return nil
    
    return PreviewViewController()

【讨论】:

以上是关于3D Touch 和 UITableViewCell的主要内容,如果未能解决你的问题,请参考以下文章

3d touch 应用 2 -备用

3D Touch 和状态恢复的问题

午餐后静态 3D Touch 不显示导航和标签栏

检测何时取消 3D Touch Peek 和 Pop View

UITableViewCell 中的 3D Touch Peek 和 Pop 如何将数据移交给其他 UIViewController?

3D Touch 快捷方式小工具