2011-11-23 12 views
5

iOS uygulamasında bir NSUndoManager kullanmayı deniyorum. İşe alınma işlevselliğini geri aldım, ama yineleme kısmı değil. IOS geliştirmede oldukça yeniyim ve bu ilk kez NSUndoManager kullanıyorum, bu yüzden muhtemelen önemsiz bir şey.Zorlama NSUndoManager yineleme işlevinin uygulanması

Uygulamam bir resim/not alma uygulamasıdır, bir dizide son on UIImage s (bunun en verimli yol olup olmadığını bilmiyorum) ile bir geri alma/yineleme yığını var. Kullanıcı geçerli görüntüde değişiklikler yaptığında, eski görüntü yığının üzerine itilir ve dizi zaten on nesneye sahipse dizideki ilk görüntü kaldırılır. Dizideki nesneleri takip etmek ve doğru görüntünün görüntülendiğinden emin olmak için kullandığım int örnek değişkenim var. Benim kod şöyle görünür:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 

    if (oldImagesArrays.count >= 10) { 
     [oldImagesArrays removeObjectAtIndex:0]; 
    } 
    UIImage * currentImage = pageView.canvas.image; 
    if (currentImage != nil) { 
     [oldImagesArrays addObject:currentImage]; 
     undoRedoStackIndex = oldImagesArrays.count -1; 
    } 
    [...] 
} 

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 

    UIImage * currentImage = [oldImagesArrays lastObject]; 
    if (currentImage != pageView.canvas.image) { 
     [undoManager registerUndoWithTarget:self selector:@selector(resetImage) 
     object:currentImage]; 
    } 
} 

// Gets called when the undo button is clicked 
- (void)undoDrawing 
{ 
    [undoManager undo]; 
    [undoManager registerUndoWithTarget:self 
          selector:@selector(resetImage) 
          object:pageView.canvas.image]; 
    undoRedoStackIndex--; 
} 

// Gets called when the redo button is clicked 
- (void)redoDrawing 
{ 
    [undoManager redo]; 
    undoRedoStackIndex++; 
} 

- (void)resetImage 
{ 
    NSLog(@"Hello"); // This NSLog message only appears when I click undo. 
    pageView.canvas.image = [oldImagesArrays objectAtIndex:undoRedoStackIndex]; 
} 

Ben geri alma tıklayın ya resetImage denilen almalısınız yeniden yapma düğmeleri ve benim görüntü yığınında (undoRedoStackIndex geçerli değerini) önceki veya sonraki nesneye geçerli görüntüyü ayarlandığında Bu yalnızca, geri almayı tıklattığımda ancak yinelemediğimde olur.

Çözümler & & || Bunu yapmak için daha iyi yollar takdir edilecektir.

+0

@JoshCaswell Soruma bazı açıklamalar ekledim. – Anders

cevap

6

Değişiklikleri izlemeniz gerekmez, geri alma yöneticisi bunun için.

bir geri alınabilir yöntem şöyle yapın: Bu

- (void)setImage:(UIImage*)image 
{ 
    if (_image != image) 
    { 
     [[_undoManager prepareWithInvocationTarget:self] setImage:_image]; // Here we let know the undo managed what image was used before 
     [_image release]; 
     _image = [image retain]; 

     // post notifications to update UI 
    } 
} 

olduğunu. Değişikliği geri almak için [_undoManager redo] numaralı telefonu tekrar aramak için [_undoManager undo] numaralı telefonu arayın. Geri alma yöneticisinin geri almasını söylerken, eski görüntü ile bu yöntemi çağırır. Geri Al işlemi için özel düğmeler kullanırsanız, [NSUndoManager canUndo], vb. Kullanarak doğrulayabilirsiniz. Geri yükleme işlemlerinin sayısı için sınır yoktur. Geri alma kümesini bir noktada temizlemeniz gerekiyorsa, yalnızca removeAllActions yöntemini arayın.

+0

Teşekkür ederim, işe koyuldun. Yaptığımdan daha kolay olduğundan şüpheleniyorum. Teşekkürler. // Anders – Anders

+0

@Davyd merhaba, bana bu yardımcı olabilir :) "UI güncellemesi için bildirim gönder" UIImage nasıl güncellenir? –

+0

Gönderdiğim gibi bir yönetici geri alma yöntemi, bir veri modeli içinde kullanılmalıdır. Bu yüzden bir bildirim oluşturmayla ilgili bir yorumda bulunmuştum. Örneğin: [[NSNotificationCentre defaultCentre] postNotification: XXMyDataModelDidChangeImageNotification object: self]. Bu, gerçekte görüntüyü görüntüleyen bir görünüm (UIImageView) ile bir yerde bir görünüm denetleyicisi olması gerektiği anlamına gelir. Bu görünüm denetleyicisi, veri modelinden gelen bildirime abone olmalı ve bildirimler alındığında görünümü güncelleştirmelidir. Alternatif olarak bir KVO kullanılabilir. Umarım bu yardımcı olur. – Davyd