ios – 在UIViewController显示为3DTouch预览时检测UITouches

是否有可能从UIViewController检测触摸并获取触摸的位置,UIViewController当前用作3D Touch的previewingContext视图控制器? (当触摸从左向右移动时,我想更改预览控制器内的图像)

我尝试了两个touchesBegan和touchesMoved都没有被解雇.

class ThreeDTouchPreviewController: UIViewController {

func getLocationFromTouch(touches: Set<UITouch>) -> CGPoint?{
        guard let touch  = touches.first else { return nil }
        return touch.location(in: self.view)
    }
    //Not fired
    override func touchesBegan(_ touches: Set<UITouch>,with event: UIEvent?) {

        let location = getLocationFromTouch(touches: touches)
        print("LOCATION",location)
    }
    //Not fired
    override func touchesMoved(_ touches: Set<UITouch>,with event: UIEvent?) {
        let location = getLocationFromTouch(touches: touches)
        print("LOCATION",location)
    }
}

甚至尝试添加UIPanGesture.

尝试复制FaceBook的3D Touch功能,用户可以从左向右移动手指以更改当前显示的图像.
上下文视频:https://streamable.com/ilnln

解决方法

如果您想获得与FaceBook的3D Touch功能相同的结果,您需要创建自己的3D Touch手势类
import UIKit.UIGestureRecognizerSubclass

class ForcetouchGestureRecognizer: UIGestureRecognizer {

    var forceValue: CGFloat = 0
    var isForcetouch: Bool = false

    override func touchesBegan(_ touches: Set<UITouch>,with event: UIEvent) {
        super.touchesBegan(touches,with: event)
        handleForceWithtouches(touches: touches)
        state = .began
        self.isForcetouch = false
    }

    override func touchesMoved(_ touches: Set<UITouch>,with event: UIEvent) {
        super.touchesMoved(touches,with: event)
        handleForceWithtouches(touches: touches)
        if self.forceValue > 6.0 {
            state = .changed
            self.isForcetouch = true
        }
    }

    override func touchesEnded(_ touches: Set<UITouch>,with event: UIEvent) {
        super.touchesEnded(touches,with: event)
        state = .ended
        handleForceWithtouches(touches: touches)
    }

    override func touchesCancelled(_ touches: Set<UITouch>,with event: UIEvent) {
        super.touchesCancelled(touches,with: event)
        state = .cancelled
        handleForceWithtouches(touches: touches)
    }

    func handleForceWithtouches(touches: Set<UITouch>) {
        if touches.count != 1 {
            state = .Failed
            return
        }

        guard let touch = touches.first else {
            state = .Failed
            return
        }
        forceValue = touch.force
    }
}

现在,您可以在viewDidLoad方法的ViewController中添加此手势

override func viewDidLoad() {
    super.viewDidLoad()
    let gesture = ForcetouchGestureRecognizer(target: self,action: #selector(imagepressed(sender:)))
    self.view.addGestureRecognizer(gesture)
}

现在,您可以在Storyboard中管理控制器UI.在中心添加UICollectionView和UIImageView上方的封面视图,并在代码中将其与IBOutlets连接.

现在您可以为手势添加处理程序方法

func imagepressed(sender:ForcetouchGestureRecognizer){

let location = sender.location(in: self.view)

guard let indexPath = collectionView?.indexPathForItem(
    at: location) else { return }

让image = self.images [indexPath.row]

switch sender.state {
case .changed:
    if sender.isForcetouch {
        self.coverView?.isHidden = false
        self.selectedImageView?.isHidden = false
        self.selectedImageView?.image = image
    }

case .ended:
    print("force: \(sender.forceValue)")
    if sender.isForcetouch {
        self.coverView?.isHidden = true
        self.selectedImageView?.isHidden = true
        self.selectedImageView?.image = nil
    } else {
        //Todo: handle selecting items of UICollectionView here,//you can refer to this SO question for more info: https://stackoverflow.com/questions/42372609/collectionview-didnt-call-didselectitematindexpath-when-superview-has-gesture
        print("Did select row at indexPath: \(indexPath)")
        self.collectionView?.selectItem(at: indexPath,animated: true,scrollPosition: .centeredVertically)
    }

default: break
}

}

从这一点开始,您需要自定义视图,使其外观与Facebook一样.

我还在GitHub https://github.com/ChernyshenkoTaras/3DTouchExample上创建了一个小示例项目来演示它

相关文章

当我们远离最新的 iOS 16 更新版本时,我们听到了困扰 Apple...
欧版/美版 特别说一下,美版选错了 可能会永久丧失4G,不过只...
一般在接外包的时候, 通常第三方需要安装你的app进行测...
前言为了让更多的人永远记住12月13日,各大厂都在这一天将应...