2011-08-25 13 views
9

मेरे पास एक NSView है जिसे मैं किसी अन्य NSView के सबव्यूव के रूप में जोड़ रहा हूं। मैं मूल दृश्य के आस-पास पहला एनएसवी व्यू खींचने में सक्षम होना चाहता हूं। मेरे पास कुछ कोड है जो आंशिक रूप से काम कर रहा है लेकिन एनएसवी व्यू के साथ मेरे माउस ड्रैग से वाई अक्ष पर विपरीत दिशा में चल रहा है। (यानी मैं नीचे खींचता हूं, यह ऊपर जाता है और इसके विपरीत)। ,NSView: दृश्य को खींचें

// -------------------- MOUSE EVENTS ------------------- \\ 

- (BOOL) acceptsFirstMouse:(NSEvent *)e { 
return YES; 
} 

- (void)mouseDown:(NSEvent *) e { 

//get the mouse point 
lastDragLocation = [e locationInWindow]; 

} 

- (void)mouseDragged:(NSEvent *)theEvent { 

NSPoint newDragLocation = [theEvent locationInWindow]; 
NSPoint thisOrigin = [self frame].origin; 
thisOrigin.x += (-lastDragLocation.x + newDragLocation.x); 
thisOrigin.y += (-lastDragLocation.y + newDragLocation.y); 
[self setFrameOrigin:thisOrigin]; 
lastDragLocation = newDragLocation; 
} 

दृश्य रूप से फ़्लिप किया, हालांकि मुझे लगता है कि वापस डिफ़ॉल्ट करने के लिए बदल गया है और यह एक फर्क नहीं लगता था:

यहाँ मेरी कोड है। मैं क्या गलत कर रहा हूं?

उत्तर

13

इस समस्या से संपर्क करने का सबसे अच्छा तरीका समन्वय रिक्त स्थान की ठोस समझ से शुरू करना है।

सबसे पहले, यह समझना महत्वपूर्ण है कि जब हम खिड़की के "फ्रेम" के बारे में बात करते हैं, तो यह पर्यवेक्षण के समन्वय स्थान में है। इसका मतलब यह है कि दृश्य की फ़्लिपनेस को समायोजित करने से वास्तव में कोई फर्क नहीं पड़ता है, क्योंकि हम दृश्य के अंदर कुछ भी नहीं बदल रहे हैं।

लेकिन आपकी अंतर्ज्ञान कि यहां फ़्लिपनेस महत्वपूर्ण है, यह सही है।

डिफॉल्ट रूप से आपका कोड टाइप किया गया है, ऐसा लगता है जैसे यह काम करेगा; शायद आपका पर्यवेक्षण फ़्लिप किया गया है (या फ़्लिप नहीं किया गया है), और यह अपेक्षा की तुलना में एक अलग समन्वय अंतरिक्ष में है।

यादृच्छिक रूप से केवल फ़्लिपिंग और अप्रचलित विचारों की बजाय, उन बिंदुओं को परिवर्तित करना सबसे अच्छा है जिन्हें आप किसी ज्ञात समन्वय स्थान में बदल रहे हैं।

मैंने आपके उपरोक्त कोड को हमेशा पर्यवेक्षण के समन्वय स्थान में परिवर्तित करने के लिए संपादित किया है, क्योंकि हम फ्रेम मूल के साथ काम कर रहे हैं। यह काम करेगा यदि आपका ड्रैगगेबल दृश्य फ़्लिप या गैर-फ़्लिप किए गए पर्यवेक्षण में रखा गया है।

// -------------------- MOUSE EVENTS ------------------- \\ 

- (BOOL) acceptsFirstMouse:(NSEvent *)e { 
    return YES; 
} 

- (void)mouseDown:(NSEvent *) e { 

    // Convert to superview's coordinate space 
    self.lastDragLocation = [[self superview] convertPoint:[e locationInWindow] fromView:nil]; 

} 

- (void)mouseDragged:(NSEvent *)theEvent { 

    // We're working only in the superview's coordinate space, so we always convert. 
    NSPoint newDragLocation = [[self superview] convertPoint:[theEvent locationInWindow] fromView:nil]; 
    NSPoint thisOrigin = [self frame].origin; 
    thisOrigin.x += (-self.lastDragLocation.x + newDragLocation.x); 
    thisOrigin.y += (-self.lastDragLocation.y + newDragLocation.y); 
    [self setFrameOrigin:thisOrigin]; 
    self.lastDragLocation = newDragLocation; 
} 

साथ ही, मैं अपने कोड पुनर्रचना बस मूल माउस से नीचे स्थान, और सूचक की वर्तमान स्थान के बजाय सौदा mouseDragged घटनाओं के बीच डेल्टा के साथ से निपटने के लिए सलाह देते हैं। इससे लाइन के नीचे अप्रत्याशित परिणाम हो सकते हैं।

इसके बजाए ड्रैग किए गए दृश्य और माउस पॉइंटर (जहां माउस पॉइंटर दृश्य में है) की उत्पत्ति के बीच ऑफसेट को स्टोर करें, और फ्रेम पॉइंटर को माउस पॉइंटर के स्थान पर सेट करें, ऑफसेट को घटाएं।

यहाँ कुछ अतिरिक्त पढ़ने है:

Cocoa Drawing Guide

Cocoa Event Handling Guide

0

मुझे लगता है कि आप, माउस की स्थिति के अनुसार गणना का कारण होना चाहिए अपने परीक्षण के अनुसार, यह अधिक smooth.Because तरह से हो जाता है जैसे नीचे एप्लिकेशन की विंडो समन्वय प्रणाली के अंदर स्थिति प्रदान करें:

[[self superview] convertPoint:[theEvent locationInWindow] fromView:nil]; 

डब्ल्यू टोपी मैं सुझाव दे रहा हूं:

lastDrag = [NSEvent mouseLocation]; 

अन्य कोड समान हैं।