在XCUITest中使用Force Touch/ 3D Touch

8

我正在尝试为iOS应用添加3D Touch自动化。我查阅了苹果文档,但没有找到有用的信息。我们可以通过辅助触控进行3D Touch,但我正在寻找像点击(tap())操作一样简单的解决方案。是否有任何可用于forceTouch的东西?

非常感谢您的任何帮助!谢谢!


https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/Adopting3DTouchOniPhone/ - trndjc
@ slickdaddy 我已经在开发代码中实现了它。我想使用xctest框架运行UITest自动化。 - Kushal Jogi
2个回答

4
触摸关联的原始力值可在UITouch对象的force属性中获取。您可以将该值与maximumPossibleForce属性中的值进行比较,以确定相对力量的大小。
//Without this import line, you'll get compiler errors when implementing your touch methods since they aren't part of the UIGestureRecognizer superclass
//Without this import line, you'll get compiler errors when implementing your touch methods since they aren't part of the UIGestureRecognizer superclass
import UIKit.UIGestureRecognizerSubclass

//Since 3D Touch isn't available before iOS 9, we can use the availability APIs to ensure no one uses this class for earlier versions of the OS.
@available(iOS 9.0, *)
public class ForceTouchGestureRecognizer: UIGestureRecognizer {
  //Because we don't know what the maximum force will always be for a UITouch, the force property here will be normalized to a value between 0.0 and 1.0.
  public private(set) var force: CGFloat = 0.0
  public var maximumForce: CGFloat = 4.0

  convenience init() {
    self.init(target: nil, action: nil)
  }

  //We override the initializer because UIGestureRecognizer's cancelsTouchesInView property is true by default. If you were to, say, add this recognizer to a tableView's cell, it would prevent didSelectRowAtIndexPath from getting called. Thanks for finding this bug, Jordan Hipwell!
  public override init(target: Any?, action: Selector?) {
    super.init(target: target, action: action)
    cancelsTouchesInView = false
  }

  public override func touchesBegan(_ touches: Set, with event: UIEvent) {
    super.touchesBegan(touches, with: event)
    normalizeForceAndFireEvent(.began, touches: touches)
  }

  public override func touchesMoved(_ touches: Set, with event: UIEvent) {
    super.touchesMoved(touches, with: event)
    normalizeForceAndFireEvent(.changed, touches: touches)
  }


  public override func touchesEnded(_ touches: Set, with event: UIEvent) {
    super.touchesEnded(touches, with: event)
    normalizeForceAndFireEvent(.ended, touches: touches)
  }

  public override func touchesCancelled(_ touches: Set, with event: UIEvent) {
    super.touchesCancelled(touches, with: event)
    normalizeForceAndFireEvent(.cancelled, touches: touches)
  }

  private func normalizeForceAndFireEvent(_ state: UIGestureRecognizerState, touches: Set) {
    //Putting a guard statement here to make sure we don't fire off our target's selector event if a touch doesn't exist to begin with.
    guard let firstTouch = touches.first else { return }

    //Just in case the developer set a maximumForce that is higher than the touch's maximumPossibleForce, I'm setting the maximumForce to the lower of the two values.
    maximumForce = min(firstTouch.maximumPossibleForce, maximumForce)

    //Now that I have a proper maximumForce, I'm going to use that and normalize it so the developer can use a value between 0.0 and 1.0.
    force = firstTouch.force / maximumForce

    //Our properties are now ready for inspection by the developer. By setting the UIGestureRecognizer's state property, the system will automatically send the target the selector message that this recognizer was initialized with.
    self.state = state
  }

  //This function is called automatically by UIGestureRecognizer when our state is set to .Ended. We want to use this function to reset our internal state.
  public override func reset() {
    super.reset()
    force = 0.0
  }
}

0

我已经尝试过了。但是它没有起作用。它就像对元素的普通点击一样。 - Kushal Jogi
你的手势识别器是否配置为接受力触控?我通常使用2秒的持续时间来触发文本字段上的力触控。 - ablarg
是的,它已经配置好了。我可以通过使用我的Mac触控板在模拟器中进行强制触摸。当我运行UIAutomation测试时,我想执行强制触摸。我尝试过press(forDuration)但没有起作用。 - Kushal Jogi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接