2016-04-08 16 views
3

Swift kapanışlarını kullanarak NSLayoutManager'u nasıl kullanacağımı anlatmaya çalışıyorum. aşağıdaki gibi başarıyla bir undo kayıt olabilirsiniz: ElbetteNSUndoManager'ı kullanarak, Swift kapanışlarını kullanarak geri yükleme nasıl yapılır

doThing(); 
undoManager?.registerUndoWithTarget(self, handler: { _ in 
    undoThing(); 
} 
undoManager?.setActionName("do thing") 

Bir geri alma bir geri alma tutarındaki redo desteklemesi gerekir. Tamam .... Ama şimdi Yinele ... hmmm bir geri alma desteklemek gerekir

doThing(); 
undoManager?.registerUndoWithTarget(self, handler: { _ in 
    undoThing(); 

    undoManager?.registerUndoWithTarget(self, handler: { _ in 
     doThing(); 
    } 
    undoManager?.setActionName("do thing") 
} 
undoManager?.setActionName("do thing") 

: Bunu yapabilirim

doThing(); 
undoManager?.registerUndoWithTarget(self, handler: { _ in 
    undoThing(); 

    undoManager?.registerUndoWithTarget(self, handler: { _ in 
     doThing(); 

     undoManager?.registerUndoWithTarget(self, handler: { _ in 
      undoThing(); 
     } 
     undoManager?.setActionName("do thing") 
    } 
    undoManager?.setActionName("do thing") 
} 
undoManager?.setActionName("do thing") 

onun "kaplumbağalar tüm yol görebileceğiniz gibi aşağı." Bu delilikten nasıl kurtulurum? yani, bulabildiğim tüm örnek kodda, insanlar kendi kendine geri alabilecek bir yöntemi kaydetmek için kodun seçici sürümünü kullanırlar - bu benim kullanıyorum kapatma yöntemi ile açık bir şekilde yapılabilir ... Kapatma nasıl kullanılır? sürüm ve sınırsız geri al/yeniden yap?

cevap

8

Aradığın şey, karşılıklı tekrarlama. Her biri diğerine çağrı yapan iki fonksiyona ihtiyacınız var. İşte farklı şekillerde bir çift onu yapılandırmaya şunlardır:

doThing() yılında
  1. , undoThing() aramaya geri alma işlemini kaydeder. undoThing'da, doThing() numaralı telefonu aramak için eylemi geri alın. Yani: Eğer değil sen weak ile yakalamak sürece kapatılmasıyla self başvurmalıdır

    @IBAction func doThing() { 
        undoManager?.registerUndoWithTarget(self, handler: { me in 
         me.undoThing() 
        }) 
        undoManager?.setActionName("Thing") 
    
        // do the thing here 
    } 
    
    @IBAction func undoThing() { 
        undoManager?.registerUndoWithTarget(self, handler: { me in 
         me.doThing() 
        }) 
        undoManager?.setActionName("Thing") 
    
        // undo the thing here 
    } 
    

Not şiddetle yakalayan çünkü (varsayılan) bir muhafaza döngüsü yaratabilir. Geri alma yöneticisine target olarak self geçişi yaptığınız için zaten zayıf bir başvuru kaynağı tutuyorsunuz ve geri alma bloğuna (güçlü bir şekilde) aktarıyorsunuz. Bu nedenle, geri alma bloğundaki self numaralı referansı kullanıp kullanamayabilirsiniz.

  1. Wrap ayrı kayıt işlemini geri ve bu yeni fonksiyonlara kullanıcı eylemleri bağlamak işlemek fonksiyonlarda doThing() ve undoThing() için çağrılar:

    private func doThing() { 
        // do the thing here 
    } 
    
    private func undoThing() { 
        // undo the thing here 
    } 
    
    @IBAction func undoablyDoThing() { 
        undoManager?.registerUndoWithTarget(self, handler: { me in 
         me.redoablyUndoThing() 
        }) 
        undoManager?.setActionName("Thing") 
        doThing() 
    } 
    
    @IBAction func redoablyUndoThing() { 
        undoManager?.registerUndoWithTarget(self, handler: { me in 
         me.undoablyDoThing() 
        }) 
        undoManager?.setActionName("Thing") 
        undoThing() 
    } 
    
+0

teşekkür! Bunlar harika cevaplar. Kendinden bahşiş için teşekkür ederim - başka yerde sızıntı olduğumu merak ediyorum. – wcochran

İlgili konular