سؤال

لدي ضياء بسيط في NSCollectionView في اي NSCollectionViewItemتنفصل بصريًا عندما أقوم بالتمرير النافذة.

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

NSView الخاص بي (عرض مخصص لـ NSCollectionViewItem) لديه خوارزمية رسم بسيطة للغاية - لا شيء معقد للغاية.

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

-(void)drawRect:(NSRect)dirtyRect
{   
    NSRect mOuterFrame = NSMakeRect(dirtyRect.origin.x, dirtyRect.origin.y, 104, 94);
    NSRect mSelectedFrame = NSInsetRect(mOuterFrame, 2, 2);
    NSRect mRedFrame = NSInsetRect(mSelectedFrame, 2, 2);
    NSRect mInnerFrame = NSInsetRect(mRedFrame, 2, 2);

    NSBezierPath * mOuterFramePath = [NSBezierPath bezierPathWithRect:mOuterFrame];
    NSBezierPath * mSelectedFramePath = [NSBezierPath bezierPathWithRect:mSelectedFrame];
    NSBezierPath * mRedFramePath = [NSBezierPath bezierPathWithRect:mRedFrame];
    NSBezierPath * mInnerFramePath = [NSBezierPath bezierPathWithRect:mInnerFrame];

    [mainBackgroundColor set];
    [mOuterFramePath fill];

    if (selected)
        [[NSColor yellowColor] set];
    else
        [mainBackgroundColor set];

    [mSelectedFramePath fill];

    if (isRedBorder)
        [[NSColor redColor] set];
    else
        [mainBackgroundColor set];

    [mRedFramePath fill];

    [[NSColor blackColor] set];
    [mInnerFramePath fill];
}

لقد حاولت قفل التركيز والإفراج قبل وبعد الكود وكذلك تعيين سياق الرسومات واستعادته - لا يبدو أن أي منها يحل المشكلة.

أنا أستخدم Snow Leopard - لا أعتقد أن هذا يحدث فرقًا.

تحديث الحل

لأي شخص مهتم هنا هو الحل للمشكلة على النحو الموصى به من قبل NSResponder. كنت أقوم بإنشاء الأولي mOuterFrame بناء على drawRect: طُرق dirtyRect والتي ، كما أشار ، كان الشيء غير الصحيح الذي يجب القيام به. تغيير سريع من:

NSRect mOuterFrame = NSMakeRect(dirtyRect.origin.x, dirtyRect.origin.y, 104, 94);

إلى نقطة الإنشاء القائمة على 0:

NSRect mOuterFrame = NSMakeRect(0, 0, 104, 94);

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

-(void)drawRect:(NSRect)dirtyRect
{   
    NSRect mOuterFrame = NSMakeRect(0, 0, 104, 94);
    NSRect mSelectedFrame = NSInsetRect(mOuterFrame, 2, 2);
    NSRect mRedFrame = NSInsetRect(mSelectedFrame, 2, 2);
    NSRect mInnerFrame = NSInsetRect(mRedFrame, 2, 2);

    [NSBezierPath setDefaultLineWidth:2.0];

    [mainBackgroundColor set];
    [NSBezierPath strokeRect:mOuterFrame];

    if (selected)
        [[NSColor yellowColor] set];
    else
        [mainBackgroundColor set];

    [NSBezierPath strokeRect:mSelectedFrame];

    if (isRedBorder)
        [[NSColor redColor] set];
    else
        [mainBackgroundColor set];

    [NSBezierPath strokeRect:mRedFrame];

    [[NSColor blackColor] set];
    [NSBezierPath strokeRect:mInnerFrame];
}
هل كانت مفيدة؟

المحلول

أول شيء لاحظته هو أن التعليمات البرمجية الخاصة بك أعلاه مضيعة إلى حد ما ، نظرًا لأنك تقوم بإنشاء مجموعة من المسارات عندما يمكنك فقط استخدام NSFRAMERECT () و NSRECTFILL () بدلاً من ذلك.

ثانياً ، لا ينبغي أن تعتمد هندسة ما ترسمه على المستطيل الذي تم تمريره إلى drawRect :. يخبرك هذا المستطيل فقط ما هي المنطقة التي يتم تحديثها ، بحيث يمكنك أن تكون أكثر كفاءة في تحديد ما يجب رسمه إذا كان عرضك معقدًا.

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