لا يتم استدعاء الماوس عندما يترك الماوس منطقة التتبع أثناء التمرير

StackOverflow https://stackoverflow.com/questions/8979639

سؤال

لماذا لا يتم استدعاء الماوس/الماوس عند خروج الماوس من منطقة نستراكينجاريا عن طريق التمرير أو القيام بالرسوم المتحركة?

أقوم بإنشاء رمز مثل هذا:

دخل الماوس وخرج:

-(void)mouseEntered:(NSEvent *)theEvent {
    NSLog(@"Mouse entered");
}

-(void)mouseExited:(NSEvent *)theEvent
{
    NSLog(@"Mouse exited");
}

منطقة التتبع:

-(void)updateTrackingAreas
{ 
    if(trackingArea != nil) {
        [self removeTrackingArea:trackingArea];
        [trackingArea release];
    }

    int opts = (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways);
    trackingArea = [ [NSTrackingArea alloc] initWithRect:[self bounds]
                                             options:opts
                                               owner:self
                                            userInfo:nil];
    [self addTrackingArea:trackingArea];
}

مزيد من التفاصيل:

لقد أضفت نسفيوس كما سوبفيوس في عرض نسكرولفيو.كل نسفيو لديها منطقة تتبع الخاصة به وعندما انتقل سكرولفيو بلدي وترك منطقة تتبع" موسكسيتد " لا يسمى ولكن دون التمرير كل شيء يعمل بشكل جيد.المشكلة هي أنه عندما انتقل "أوبداتتراكينغارياس" يسمى وأعتقد أن هذا يجعل المشاكل.

* نفس المشكلة مع نسفيو فقط دون إضافته كما سوبفيو بحيث ليست مشكلة.

هل كانت مفيدة؟

المحلول

كما لاحظت في عنوان السؤال، يتم استدعاء Mouseentered و MouseXTORE فقط عند تحركات الماوس. لمعرفة سبب هذا هو الحال، دعنا ننظر أولا إلى عملية إضافة Nstrackingareas لأول مرة.

كحل بسيط، دعنا ننشئ طريقة عرض يقوم عادة بتقسيم خلفية بيضاء، ولكن إذا كان المستخدم يحوم فوق الرأي، فإنه يرسم خلفية حمراء. يستخدم هذا المثال ARC. giveacodicetagpre.

هناك مشكلتان مع هذا الرمز. أولا، عند استدعاء -Aakefromnib، إذا كان الماوس موجود بالفعل داخل الرأي، فلن يتم استدعاء -Mouseered. هذا يعني أن الخلفية ستظل بيضاء، على الرغم من أن الماوس قد انتهى العرض. يتم ذكر ذلك بالفعل في وثائق NSView لمعلمة Assuminside of -addrackingRect: المالك: UserData: AssumineInside:

إذا كانت الإجابة بنعم، فسيتم إنشاء الحدث الأول عندما يترك المؤشر ARCES، بغض النظر عما إذا كان المؤشر داخل ARCE عند إضافة مستطيل التتبع. إذا لم يكن هناك حدث أول، فسيتم إنشاء الحدث الأول عندما يترك المؤشر ARCE إذا كان المؤشر في البداية في البداية، أو عندما يدخل المؤشر ARECT إذا كان المؤشر في البداية في البداية.

في كلتا الحالتين، إذا كان الماوس داخل منطقة التتبع، فلن يتم إنشاء أي أحداث حتى يترك الماوس منطقة التتبع.

حتى إصلاح هذا، عندما نضيف منطقة التتبع، نحتاج إلى معرفة ما إذا كان المؤشر في الداخل في منطقة التتبع. وهكذا أصبحت طريقة - خلاصة giveacodicetagpre.

المشكلة الثانية هي التمرير. عند التمرير أو نقل طريقة عرض، نحتاج إلى إعادة حساب Nstrackingareas في هذا الرأي. يتم ذلك عن طريق إزالة مجالات التتبع ثم إضافةها مرة أخرى. كما لاحظت، يتم استدعاء updatetrackingareas عند التمرير العرض. هذا هو المكان لإزالة وإعادة إضافة المنطقة. giveacodicetagpre.

وهذا يجب أن يعتني بمشكلتك. من المسلم به، يحتاج إلى العثور على موقع الماوس ثم قم بتحويله لعرض الإحداثيات في كل مرة تقوم فيها بإضافة منطقة تتبع هو شيء يكتسب بسرعة، لذلك أود أن أوصي بإنشاء فئة على NSView التي تعالج هذا تلقائيا. لن تكون دائما قادرا على الاتصال [Self Mouseentered: NIL] أو [Self MouseXOrted: Nil]، لذلك قد ترغب في جعل الفئة تقبل كتل زوجين. واحد لتشغيل إذا كان الماوس في Nstrackingarea، ويتم تشغيله إذا لم يكن كذلك.

نصائح أخرى

@مايكل يقدم إجابة كبيرة ، وحل مشكلتي.ولكن هناك شيء واحد,

if (CGRectContainsPoint([self bounds], mouseLocation))
{
    [self mouseEntered: nil];
}
else
{
    [self mouseExited: nil];
}

لقد وجدت CGRectContainsPoint يعمل في صندوقي ، وليس CGPointInRect,

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top