2011-11-23 10 views
5

लागू करने में कठिनाई मैं अपने आईओएस ऐप में NSUndoManager को लागू करने की कोशिश कर रहा हूं। मुझे काम करने के लिए पूर्ववत कार्यक्षमता मिली है, लेकिन फिर से नहीं है। मैं आईओएस विकास के लिए काफी नया हूं और यह पहली बार है कि मैंने NSUndoManager का उपयोग किया है, इसलिए यह शायद कुछ मामूली है।NSUndoManager redo function

मेरा ऐप एक पेंटिंग/नोट लेने वाला ऐप है, मेरे पास पिछले दस UIImage एस (मुझे नहीं पता कि यह सबसे प्रभावी तरीका है) के साथ एक पूर्ववत/फिर से स्टैक है। जब उपयोगकर्ता वर्तमान छवि में परिवर्तन करता है, तो पुरानी छवि को ढेर पर धक्का दिया जाता है, और सरणी में पहली छवि हटा दी जाती है यदि सरणी में पहले से ही दस वस्तुएं हैं। मेरे पास int इंस्टेंस वैरिएबल है जो मैं सरणी में ऑब्जेक्ट्स का ट्रैक रखने के लिए उपयोग करता हूं और सुनिश्चित करता हूं कि सही छवि प्रदर्शित होती है। मेरे कोड इस तरह दिखता है:

- (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]; 
} 

जब मैं पूर्ववत क्लिक करें या बटन resetImage बुलाया जाना चाहिए फिर से करना, और (undoRedoStackIndex के वर्तमान मूल्य) मेरी छवि ढेर में अगले या पिछले ऑब्जेक्ट के लिए वर्तमान छवि सेट , यह तब होता है जब मैं पूर्ववत क्लिक करता हूं, लेकिन फिर से नहीं करता।

समाधान & & || इसे करने के बेहतर तरीके की सराहना की जाएगी।

+0

@ जोश कैसवेल मैंने अपने प्रश्न में कुछ स्पष्टीकरण जोड़ा है। – Anders

उत्तर

6

आपको परिवर्तनों का ट्रैक रखने की आवश्यकता नहीं है, यह पूर्ववत प्रबंधक है।

इस तरह एक पूर्ववत करने योग्य विधि बनाएं:

- (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 
    } 
} 

यह बात है। परिवर्तन को पूर्ववत करने के लिए [_undoManager undo] पर कॉल करें, [_undoManager redo] को फिर से कॉल करने के लिए। जब आप पूर्ववत प्रबंधक को पूर्ववत करने के लिए कहते हैं तो यह पुरानी छवि के साथ इस विधि को कॉल करेगा। यदि आप पूर्ववत ऑपरेशन के लिए कस्टम बटन का उपयोग करते हैं तो आप इसे [NSUndoManager canUndo], आदि का उपयोग करके सत्यापित कर सकते हैं।

पूर्ववत संचालन की संख्या के लिए कोई सीमा नहीं है। यदि आपको किसी बिंदु पर पूर्ववत स्टैक को साफ़ करने की आवश्यकता है तो बस removeAllActions विधि पर कॉल करें।

+0

धन्यवाद, इसे काम करने के लिए मिला। संदेह है कि मैंने इसे बनाने से आसान था। धन्यवाद। // एंडर्स – Anders

+0

@ डेविड हाय, क्या आप मेरी मदद कर सकते हैं :) "यूआई अपडेट करने के लिए पोस्ट अधिसूचनाएं पोस्ट करें" UIImage को कैसे अपडेट करें? –

+0

मेरे द्वारा पोस्ट किए गए पूर्व प्रबंधक के साथ एक विधि डेटा मॉडल के भीतर उपयोग की जानी चाहिए। यही कारण है कि मैंने एक अधिसूचना प्रस्तुत करने के बारे में एक टिप्पणी की। उदाहरण के लिए: [[NSNotificationCentre defaultCentre] postNotification: XXMyDataModelDidChangeImageNotification ऑब्जेक्ट: स्वयं]। इसका मतलब यह है कि दृश्य (UIImageView) के साथ कहीं दृश्य नियंत्रक होना चाहिए जो वास्तव में छवि प्रदर्शित करता है। इस दृश्य नियंत्रक को डेटा मॉडल से अधिसूचना की सदस्यता लेनी चाहिए और नोटिफिकेशन प्राप्त होने पर दृश्य को अपडेट करना चाहिए। वैकल्पिक रूप से एक केवीओ का उपयोग किया जा सकता है। आशा है कि ये आपकी मदद करेगा। – Davyd

संबंधित मुद्दे