J'écris une interface graphique d'échecs dans Swift 3 et j'utilise nvzqz/Sage comme modèle/bibliothèque d'échecs. Maintenant, je suis confronté à un problème avec une fermeture Sage utilisé pour la promotion de la pièce.Comment faire une fermeture attendre que le joueur appuie sur un bouton dans un autre contrôleur de vue?
Sage utilise (dans son jeu classe) la execute (mouvement: promotion :) méthode pour l'exécution de mouvement de promotion qui a une fermeture qui retourne une sorte de pièce de promotion. Cela permet de demander à l'utilisateur un morceau de promotion ou effectuer d'autres opérations avant de choisir un morceau de promotion genre, comme suit:
try game.execute(move: move) {
...
return .queen
}
Je mis en place un contrôleur de vue de la promotion (« PVC ») qui est appelé dans cette fermeture si que le joueur peut sélectionner la nouvelle pièce:
// This is in the main View Controller class
/// The piece selected in promotionViewController into which a pawn shall promote
var newPiece: Piece.Kind = ._queen // default value = Queen
try game.execute(move: move) {
boardView.isUserInteractionEnabled = false
// promotionview controller appears to select new promoted piece
let pvc = PromotionViewController(nibName: nil, bundle: nil)
pvc.delegate = self
pvc.modalPresentationStyle = .overCurrentContext
self.present(pvc, animated:true)
return newPiece
}
Lorsque le bouton de la nouvelle pièce dans le PVC est pressée, le PVC lui-même est rejeté et les données de la pièce sélectionnée (la constante de selectedType) est de nouveau transféré au contrôleur principal par délégation:
// This is in the sending PVC class
protocol PromotionViewControllerDelegate {
func processPromotion(selectedType: Piece.Kind)
}
func buttonPressed(sender: UIButton) {
let selectedType = bla bla bla ...
delegate?.processPromotion(selectedType: selectedType)
presentingViewController!.dismiss(animated:true)
}
// This is in the receiving main View Controller class
extension GameViewController: PromotionViewControllerDelegate {
func processPromotion(selectedType: Piece.Kind) {
defer {
boardView.isUserInteractionEnabled = true
}
newPiece = selectedType
}
Le problème que j'ai est que la fermeture (dans le game.execute méthode) ne pas attendre que le joueur a fait sa sélection dans le PVC (et retourne immédiatement la variable de newpiece qui est toujours la valeur par défaut valeur) de sorte que je ne reçois jamais une autre pièce de promotion traitée autre que la valeur par défaut. Comment puis-je faire la fermeture attendre jusqu'à ce que le joueur a appuyé sur un bouton dans le pvc?
Bien sûr, j'ai essayé de trouver une solution et de lire à propos des rappels, des gestionnaires de complétion ou des observateurs de propriété. Gestionnaire de réalisation: le pvc se ferme automatiquement à la suite d'un événement de pression de bouton, de sorte que le gestionnaire de complétion ne se trouve pas dans le contrôleur de vue (principal) de réception. Comment puis-je faire face à cela?
observateur Propriété: Je pourrais appeler la méthode game.execute try (déplacement) seulement après la pièce de promotion a été fixé (avec didset) mais qui amélioreraient le code difficile à lire et ne pas utiliser la fermeture belle la game.execute méthode fournit.
Les rappels peuvent être liés aux gestionnaires d'achèvement, mais je ne suis pas sûr.