Запретить обратную трассировку в приложении для рисования iOS (Swift)IOS

Программируем под IOS
Ответить Пред. темаСлед. тема
Anonymous
 Запретить обратную трассировку в приложении для рисования iOS (Swift)

Сообщение Anonymous »

Я использую библиотеку SwiftyDraw, чтобы нарисовать путь к своему приложению. Рисование пути работает хорошо, но возникает проблема, если пользователь начинает рисовать путь и перемещает палец вперед и назад в одном и том же положении. Тем не менее он рисует путь и завершает работу. Вот весь мой код.

Код: Выделить всё

lazy var targetView: UIView = {
let sTargetView =  UIView(frame: CGRect(x: 0,
y: 0,
width: self.view.frame.width,
height: self.view.frame.height/1.3))
sTargetView.center = CGPoint(x: UIScreen.main.bounds.size.width/2,
y: UIScreen.main.bounds.size.height/2)
sTargetView.backgroundColor = .clear
sTargetView.isUserInteractionEnabled = true

canvasView.isUserInteractionEnabled = true
canvasView.backgroundColor = .clear
sTargetView.addSubview(canvasView)
canvasView.brush = .thick
canvasView.brush.color =  self.assistiveTouchSwitch.isOn ? Color(.clear) : Color.init(self.accentColor)
canvasView.frame = sTargetView.bounds
canvasView.delegate = self
return sTargetView
}()
var swiped = false
var lastPoint = CGPoint.zero
var accentColor = UIColor.red//UIColor(hex: "00acc1")
let canvasView = SwiftyDrawView()
var isTutorialAnimationInProgresss = false

var strokeAnimationCounter = 0
var currentPathToTrace : CGPath!
var defaultTransform  = CGAffineTransform()
var assistiveDrawLayersArray = [CAShapeLayer()]
var pathToHitTestAgainst : CGPath!
let dashLayer = CAShapeLayer()
let tutorialLayer = CALayer()
var strokePathsArray = [MyBezierPath]()
var strokeIndex = 0 {
didSet {
self.pathToHitTestAgainst = self.strokePathsArray[strokeIndex].cgPath.copy(strokingWithWidth: 10, lineCap: .round, lineJoin: .round, miterLimit: 0, transform: defaultTransform)
}
}
@IBOutlet weak var assistiveTouchSwitch: UISwitch!

override func viewDidload() {
self.view.addSubview(targetView)
let p1 = MyBezierPath(svgPath: "M 55 20 V 90")
let p2 = MyBezierPath(svgPath: "M 55 47 C 10 18 11 90 55 63")
let p3 = MyBezierPath(svgPath: "M 55 47 C 93 25 94 62 71 73")
let p4 = MyBezierPath(svgPath: "M 35 20 H 80")
strokePathsArray.append(p1)
strokePathsArray.append(p2)
strokePathsArray.append(p3)
strokePathsArray.append(p4)
let combinedPath = CGMutablePath()
combinedPath.addPath(p1.cgPath)
combinedPath.addPath(p2.cgPath)
combinedPath.addPath(p3.cgPath)
combinedPath.addPath(p4.cgPath)
defaultTransform = CGAffineTransform(scaleX: self.targetView.frame.width/109, y: self.targetView.frame.width/109)
let shapeLayer = CAShapeLayer()
shapeLayer.backgroundColor = UIColor.cyan.cgColor
shapeLayer.transform = CATransform3DMakeAffineTransform(defaultTransform)
// The Bezier path that we made needs to be converted to
// a CGPath before it can be used on a layer.
shapeLayer.path = combinedPath
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.lineWidth = 10
shapeLayer.lineCap = .round
shapeLayer.strokeColor = UIColor.white.cgColor
self.targetView.layer.addSublayer(shapeLayer)
self.pathToHitTestAgainst = self.strokePathsArray[0].cgPath.copy(strokingWithWidth: 10, lineCap: .round, lineJoin: .round, miterLimit: 0, transform: defaultTransform)
animatePath()
setUpLayersForAssistiveMode(color: accentColor)
self.targetView.layer.addSublayer(self.canvasView.layer)
}
func setUpLayersForAssistiveMode(color: UIColor){
self.assistiveDrawLayersArray.removeAll()
if self.assistiveTouchSwitch.isOn {
self.strokePathsArray.forEach{
let layer = CAShapeLayer()
layer.path = $0.cgPath
layer.fillColor = UIColor.clear.cgColor
layer.lineWidth = 6
layer.strokeStart = 0
layer.strokeEnd = 0
layer.lineCap = .round
layer.strokeColor = color.cgColor
layer.transform = CATransform3DMakeAffineTransform(defaultTransform)
self.targetView.layer.addSublayer(layer)
assistiveDrawLayersArray.append(layer)
}
}
}
func showHint(){
let path = self.strokePathsArray[strokeIndex]
dashLayer.path = path.cgPath
dashLayer.fillColor = UIColor.clear.cgColor
dashLayer.lineDashPattern =  [2,2]
dashLayer.contents = UIImage(named: "pen")?.cgImage
dashLayer.transform = CATransform3DMakeAffineTransform(defaultTransform)
dashLayer.strokeColor = UIColor(hex: "f06292").cgColor
dashLayer.lineWidth = 0.5
self.currentPathToTrace = path.cgPath.copy(strokingWithWidth: 0, lineCap: .round, lineJoin:  .miter, miterLimit: 0, transform: defaultTransform)

if let startPoint = path.startPoint {
let circulPath = UIBezierPath(arcCenter: CGPoint(x: startPoint.x , y: startPoint.y) , radius: 1.5, startAngle: 0, endAngle: 2.0 * CGFloat.pi, clockwise: true)

let circleLayer = CAShapeLayer()
circleLayer.path = circulPath.cgPath
circleLayer.fillColor = UIColor(hex: "f06292").cgColor
circleLayer.transform = CATransform3DMakeTranslation(0, 0, 0)

dashLayer.insertSublayer(circleLayer, at: 0)
}

let secondLastPoint =  path.cgPath.points().count>2 ?  path.cgPath.points()[path.cgPath.points().count-2] : path.cgPath.points()[0]

if let lastPoint = path.cgPath.points().last {
let angle = atan2((lastPoint.y - secondLastPoint.y), (lastPoint.x - secondLastPoint.x))

let distance: CGFloat = 1.0
let path = UIBezierPath()
path.move(to: lastPoint)
path.addLine(to: calculatePoint(from: lastPoint, angle: angle + CGFloat.pi/2, distance: distance)) // to the right
path.addLine(to: calculatePoint(from: lastPoint, angle: angle, distance: distance)) // straight ahead
path.addLine(to: calculatePoint(from: lastPoint, angle: angle - CGFloat.pi/2, distance: distance)) // to the left
path.close()

let  arrowHeadLayer = CAShapeLayer()
arrowHeadLayer.path = path.cgPath
arrowHeadLayer.lineWidth = 1
arrowHeadLayer.strokeColor = UIColor(hex: "f06292").cgColor
arrowHeadLayer.fillColor = UIColor.white.cgColor

dashLayer.insertSublayer(arrowHeadLayer, at: 1)
}
}
func showTutorial(){
if isTutorialAnimationInProgresss {return}   //avoid animation on repeated taps outside boundary

let path = self.strokePathsArray[strokeIndex]
self.tutorialLayer.opacity = 1
tutorialLayer.contents = UIImage(named: "pen")?.cgImage

tutorialLayer.frame = CGRect(x: 0, y: 0, width: 20, height: 20)
tutorialLayer.anchorPoint = CGPoint.zero

let animation = CAKeyframeAnimation(keyPath: #keyPath(CALayer.position))
animation.duration = 1
animation.repeatCount = 0 // just recommended by Apple
animation.path = path.cgPath
animation.calculationMode = .paced
animation.beginTime = 0
animation.fillMode = .forwards
animation.isRemovedOnCompletion = false

CATransaction.begin()
isTutorialAnimationInProgresss = true
CATransaction.setCompletionBlock({
self.tutorialLayer.opacity = 0
self.isTutorialAnimationInProgresss = false
})
tutorialLayer.add(animation, forKey: nil)
CATransaction.commit()
dashLayer.addSublayer(tutorialLayer)
self.targetView.layer.addSublayer(dashLayer)
}
func calculatePoint(from point: CGPoint, angle: CGFloat, distance: CGFloat) ->  CGPoint {
return CGPoint(x: point.x + CGFloat(cosf(Float(angle))) * distance, y: point.y + CGFloat(sinf(Float(angle))) * distance)
}

func animatePath() {
if strokeAnimationCounter == self.strokePathsArray.count { return }

let layer: CAShapeLayer = CAShapeLayer()
layer.strokeColor = self.accentColor.cgColor
layer.lineWidth = 5.0
layer.fillColor = UIColor.clear.cgColor
layer.borderWidth = 0
layer.lineCap = .round
layer.borderColor = UIColor.clear.cgColor
layer.transform = CATransform3DMakeAffineTransform(defaultTransform)
layer.path = self.strokePathsArray[strokeAnimationCounter].cgPath

CATransaction.begin()

let animation: CABasicAnimation = CABasicAnimation(keyPath: "strokeEnd")
animation.fromValue = 0.0
animation.toValue = 1.0
animation.duration = 1.0

CATransaction.setCompletionBlock { [weak self] in
guard let strongSelf = self else {
print("ViewController was deallocated, stopping animation")
return
}

strongSelf.strokeAnimationCounter += 1
if strongSelf.strokeAnimationCounter  [CGPoint]{
var bezierPoints = [CGPoint]()
self.forEach(body: { (element: CGPathElement) in
let numberOfPoints: Int = {
switch element.type {
case .moveToPoint, .addLineToPoint: // contains 1 point
return 1
case .addQuadCurveToPoint: // contains 2 points
return 2
case .addCurveToPoint: // contains 3 points
return 3
case .closeSubpath:
return 0
}
}()
for index in 0.. Void) {
typealias Body = @convention(block) (CGPathElement) -> Void
func callback(info: UnsafeMutableRawPointer?, element: UnsafePointer) {
let body = unsafeBitCast(info, to: Body.self)
body(element.pointee)
}
let unsafeBody = unsafeBitCast(body, to: UnsafeMutableRawPointer.self)
self.apply(info: unsafeBody, function: callback)
}}
extension DrawVC: SwiftyDrawViewDelegate{
func swiftyDraw(didCancelDrawingIn drawingView: SwiftyDrawView, using touch: UITouch) {}

func swiftyDraw(shouldBeginDrawingIn drawingView: SwiftyDrawView, using touch: UITouch) -> Bool {
return true
}

func swiftyDraw(didBeginDrawingIn drawingView: SwiftyDrawView, using touch: UITouch) {}

func swiftyDraw(isDrawingIn drawingView: SwiftyDrawView, using touch: UITouch) {
let point = touch.location(in: drawingView)
let iscontain = pathToHitTestAgainst.contains(point)
if iscontain  {
//  print("contains")
if self.assistiveTouchSwitch.isOn {
if let first = self.currentPathToTrace.points().first{
print("distamce:",   first.distance(to: point))
print("length: ", currentPathToTrace.length/2)
if first.distance(to: point)>=21 &&   assistiveDrawLayersArray[strokeIndex].strokeEnd == 0  {
print("from right")
assistiveDrawLayersArray[strokeIndex].strokeEnd = 0
showTutorial()
return
}
}
if let drawItem = drawingView.drawItems.last {
let offset =     drawItem.path.length/(self.currentPathToTrace.length/2)
//                    print(offset)
if offset >= 0.9{
CATransaction.begin()
CATransaction.setDisableActions(false)
assistiveDrawLayersArray[strokeIndex].strokeEnd = 1
CATransaction.commit()
if strokeIndex == strokePathsArray.count-1{
dashLayer.removeFromSuperlayer()
dashLayer.sublayers?.filter{ $0 is CAShapeLayer }.forEach{ $0.removeFromSuperlayer() }
drawingView.clear()
return
}
dashLayer.sublayers?.filter{ $0 is CAShapeLayer }.forEach{ $0.removeFromSuperlayer() }
drawingView.clear()
self.strokeIndex+=1
showHint()
showTutorial()
}else{
CATransaction.begin()
CATransaction.setDisableActions(true)
assistiveDrawLayersArray[strokeIndex].strokeEnd = offset
CATransaction.commit()
print("hello")
}
}
return
}
}else{
//            drawingView.undo()
if self.assistiveTouchSwitch.isOn {
if let drawItem = drawingView.drawItems.last {
let offset =     drawItem.path.length/(self.currentPathToTrace.length/2)
let progress =    Int(max(0, offset))
//                    print (offset)
if progress != 1{
assistiveDrawLayersArray[strokeIndex].strokeEnd = 0
drawingView.clear()
showTutorial()
}
}
return
}
drawingView.undo()
showTutorial()
}
//        print(drawingView.currentPoint)
}

func swiftyDraw(didFinishDrawingIn drawingView: SwiftyDrawView, using touch: UITouch) {
if self.assistiveTouchSwitch.isOn {
if let drawItem = drawingView.drawItems.last {
let offset =     drawItem.path.length/(self.currentPathToTrace.length/2)
let progress =    Int(max(0, offset))
//                    print("progress :", offset)
if progress == 1{
self.assistiveDrawLayersArray[strokeIndex].strokeEnd = 1
if strokeIndex == strokePathsArray.count-1{
dashLayer.removeFromSuperlayer()
dashLayer.sublayers?.filter{ $0 is CAShapeLayer }.forEach{ $0.removeFromSuperlayer() }
drawingView.clear()
return
}
dashLayer.sublayers?.filter{ $0 is CAShapeLayer }.forEach{ $0.removeFromSuperlayer() }
drawingView.clear()
self.strokeIndex+=1
showHint()
showTutorial()
}else{
//                        print("progress : \(progress)")
drawingView.clear()
self.showTutorial()
assistiveDrawLayersArray[strokeIndex].strokeEnd = 0
}
}
return
}else{
//        print(MyBezierPath(cgPath:  strokePath!).length/2)
if let drawItem = drawingView.drawItems.last{
print(currentPathToTrace.length/2 - drawItem.path.length)
if abs(currentPathToTrace.length/2 - drawItem.path.length) >= 17{
drawingView.undo()
showTutorial()
} else {
let layer = CAShapeLayer()
layer.fillColor = UIColor.clear.cgColor
layer.lineWidth = 10
layer.lineCap = .round
layer.strokeColor = self.accentColor.cgColor
layer.path = drawItem.path
self.canvasView.layer.addSublayer(layer)

drawingView.clear()

dashLayer.sublayers?.filter{ $0 is CAShapeLayer }.forEach{ $0.removeFromSuperlayer() }

if strokeIndex == strokePathsArray.count-1{
dashLayer.removeFromSuperlayer()
return
}

self.strokeIndex+=1
showHint()
showTutorial()
}
}
}
}}
Приведенный выше код представляет собой почти весь код для рисования пути.
В func SwiftyDraw(isDrawingIn DrawingView: SwiftyDrawView, using Touch: UITouch) этот метод в В случае условия self.assistiveTouchSwitch.isOn = true я хочу, чтобы пользователь не прослеживал уже нарисованный путь. Я пытался проверить смещение, чтобы предотвратить эту проблему, но смещение никогда не уменьшает свое значение, даже если пользователь рисует назад.
Я прошу любого гения решить эту проблему для меня. Большое спасибо.

Подробнее здесь: https://stackoverflow.com/questions/793 ... -app-swift
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Запретить обратную трассировку в приложении для рисования iOS (Swift)
    Anonymous » » в форуме IOS
    0 Ответы
    34 Просмотры
    Последнее сообщение Anonymous
  • Как запретить серверу gRPC в Python регистрировать многострочную обратную трассировку
    Anonymous » » в форуме Python
    0 Ответы
    25 Просмотры
    Последнее сообщение Anonymous
  • Невозможно получить обратную трассировку по адресу стека pthread_attr_getstack
    Гость » » в форуме Linux
    0 Ответы
    25 Просмотры
    Последнее сообщение Гость
  • Удалить обратную трассировку ошибок из ответа маяка laravel
    Anonymous » » в форуме Php
    0 Ответы
    24 Просмотры
    Последнее сообщение Anonymous
  • Удалить обратную трассировку ошибок из ответа маяка laravel
    Anonymous » » в форуме Php
    0 Ответы
    19 Просмотры
    Последнее сообщение Anonymous

Вернуться в «IOS»