3D Touch и UITableViewCell

Я добавил тест 3D Touch функциональность для UITableViewController на iPhone 6s. В целом все работает нормально, но я смог наблюдать некоторые 2 проблемы, и я не уверен, что происходит и как это исправить обычным способом.

1) Моя ячейка доступна для выбора, поэтому пользователь может нажать на нее или использовать "3D Touch". Проблема в том, что когда я использую "Pop" и "Peek" для UITableViewCell это становится выбранным, и я не могу отменить выделение обычным способом, используя setSelected: или же setHighlighted: методы. Я пытался отменить его в разных местах, даже в previewingContext:commitViewController в presentViewController завершение. Они просто ничего не делают, а клетки все еще остаются в выбранном состоянии. Я получил выбранную ячейку, позвонив reviewingContext.sourceView и другой временный код, который дал мне выбранную ячейку, но эти методы не работали.

  • Таким образом, вопрос в том, существует ли нормальный способ отменить выделение (или лучше не выделять) ячейку, когда пользователь нажал на нее "Pop"?

2) Я также заметил, что иногда, когда я отменяю жест "Pop" и приводю ячейку в исходное состояние (когда previewingContext:viewControllerForLocation метод даже не вызывался) мой интерфейс просто зависает и вообще не реагирует на прикосновения. Мне нужно убить, чтобы это сработало. Это кажется очень странным, я проверил этот урок. Это прекрасно работает, без упомянутых проблем, но они регистрируют делегата не на ячейке, а на UITableView поэтому жест "Pop" выделяет весь tableView, но не ячейку.

  • Есть мысли и что тут может быть не так?

Вот как я реализовал 3D Touch в моем тесте UITableViewController который соответствует 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)
    }

Заранее спасибо!

3 ответа

  • Простой способ добавить 3D Touch в ячейку таблицы. без одной строки кода

изображение раскадровки

Я заметил ту же проблему. Я думаю, что проблема вызвана дублированием регистрации. Я добавил флаг, тогда проблема устранена.

Пожалуйста, попробуйте это (я использую 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];
        }
    }

Попробуйте проверить, представлен ли ваш предварительный просмотр UIViewController в вашем previewingContext(_:viewControllerForLocation:) метод.

Что-то вроде

func previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController?
{
    if self.navigationController.presentedViewController.isKindOfClass(PreviewViewController) {
        return nil
    }
    return PreviewViewController()
}
Другие вопросы по тегам