2017-04-13 47 views
4

我上的交互式動畫現場工作之後。我希望在場上的所有接觸在進入時被禁用。然後,一旦場景中的對象(它是子類節點)完成旋轉/移動,我想重新啓用屏幕上的所有觸摸以允許交互。我使用此代碼禁用的用戶互動:無法禁用,然後重新啓用觸摸,一個SKAction動畫

override func didMove(to view: SKView) { 
    setupNodes() 
    view?.isUserInteractionEnabled = false 
    spinLocations() 
} 

這是代碼,場景文件中,對於spinLocations:

func spinLocations() { 
    var allLocationArrays = [[String : CGPoint]]() 
    var previousArray = hiddenLocationPositions 
    for _ in 0...SearchConstant.numSpins { 
     let freshArray = generateNewLocationArray(previous: previousArray) 
     allLocationArrays.append(freshArray) 
     previousArray = freshArray 
    } 
    for (item, _) in hiddenLocationPositions { 
     let node = fgNode.childNode(withName: item) as! LocationNode 
     node.spin(position: allLocationArrays) // this is function below 
    } 
    hiddenLocationPositions = previousArray 
} 

這是在節點級的動畫代碼:

func spin(position: [[String : CGPoint]]) { 
    var allActions = [SKAction]() 
    for array in position { 
     let action = SKAction.move(to: array[self.name!]!, duration: 2.0) 
     allActions.append(action) 
    } 
    let allActionsSeq = SKAction.sequence(allActions) 
    self.run(SKAction.sequence([SKAction.wait(forDuration: 5.0), allActionsSeq, SKAction.run { 
     self.position = position[position.count - 1][self.name!]! 
     },])) 
} 

這是觸摸從這個類傳回主場景代碼:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
    guard let parent = self.parent else { return } 
} 

正如你所看到的,觸摸這裏沒有禁用。

我不想在上一個操作之後添加「waitForDuration」SKActionrunBlock以更改視圖狀態;我希望程序確定動畫完成執行的時間,然後重新啓用觸摸。

爲了做到這一點,我用理論完成處理可能的工作,但它只是重新啓用觸摸立即(例如處理的處理程序,以旋轉導致要再次檢測到觸摸)。此前,我還嘗試禁用runBlock中的視圖,但當然,這是即時運行的。我如何確保在不使用「waitForDuration」的情況下在動畫之後重新檢測到觸摸?

+0

所以這段代碼是從另一個類不是一個場景,對不對? – Whirlwind

+0

「didMoveToView」來自現場;旋轉函數來自一個節點類,它將所有的觸摸傳遞迴現場。 – illuminatedtype

+0

是啊,對不起,我是不是準確,我只是爲了詢問旋()方法,因爲它看上去就像是從其他類。我只需要知道您當前的設置,以便爲您編寫一些代碼。我還要問一件事......你說,節點*傳遞給現場。你的意思是,你在該自定義節點上有'userInteractionEnabled = false'? – Whirlwind

回答

3

所以,這是一個簡單的例子,說明如何,您可以:

1)完全禁用觸摸

2)旋節點

3)當節點與紡紗做,使倒是

下面是代碼(你可以複製/粘貼嘗試它是如何工作):

class Object:SKSpriteNode{ 

    func spin(times:Int,completion:@escaping()->()) { 

     let duration = 3.0 
     let angle = CGFloat(M_PI) * 2.0 

     let oneRevolution = SKAction.rotate(byAngle: angle , duration: duration) 
     let spin = SKAction.repeat(oneRevolution, count: times) 

     let sequence = SKAction.sequence([spin,SKAction.run(completion)]) 

     run(sequence, withKey:"spinning") 
    } 

} 

class WelcomeScene: SKScene { 


    override func didMove(to view: SKView) { 


     view.isUserInteractionEnabled = false 
     print("Touches Disabled") 

     let object = Object(texture: nil, color: .purple, size: CGSize(width: 200, height: 200)) 

     addChild(object) 

     object.spin(times: 3, completion: {[weak self] in 

      self?.view?.isUserInteractionEnabled = true 
      print("Touches Enabled") 
     }) 

    } 

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
     print("touch detected") 
    } 

    deinit { 
     print("Welcome scene deinited") 
    } 
} 

在這裏,你倒是禁用加載場景時,開始旋轉對象,你傳遞一個完成塊吧...代碼塊用在這裏:

let sequence = SKAction.sequence([spin,SKAction.run(completion)]) 

紡紗操作後,該塊會被執行。現在,有不同的方法來做到這一點我個人而言,我會用代表團,但我認爲這可能是減少混亂......如果需要,我可以寫一個代表團太例子,但基本上,你會做什麼,是將場景設置爲自定義節點的代表,並通知其完成旋轉,以便場景可以告訴視圖重新啓用觸摸。

+0

謝謝!這工作。 – illuminatedtype

+0

@illuminatedtype歡迎您。請注意,使用完成處理程序時,它們應始終是方法的最後一個參數。這是最好的做法,因爲它在使用內聯塊時使代碼可讀。你也應該每個方法只使用一個完成處理程序。 – Whirlwind

相關問題