пользовательский NSSliderCell

Я как бы реализовал пользовательскую ячейку ползунка, которая может рисовать с помощью изображений для полосы прокрутки и ручки. Единственное препятствие, которое сейчас мешает, это то, что когда я быстро перетаскиваю ручку, изображения путаются. Я разместил снимок экрана.

Скриншот

Вот код:

#import "customSliderCell.h"
@implementation customSliderCell
- (void)drawKnob:(NSRect)knobRect {

    NSImage * knob = knobImage;
 [[self controlView] lockFocus];
 [knob
 compositeToPoint:NSMakePoint(knobRect.origin.x,knobRect.origin.y+knobRect.size.height)
 operation:NSCompositeSourceOver];

[[self controlView] unlockFocus];
}
- (void)drawBarInside:(NSRect)rect flipped:(BOOL)flipped {
rect.size.height = 8;

    NSRect leftRect = rect;
    leftRect.origin.x=0;
    leftRect.origin.y=2;
    leftRect.size.width = knobrect.origin.x + (knobrect.size.width);
    [leftBarImage setSize:leftRect.size];
    [leftBarImage drawInRect:leftRect fromRect: NSZeroRect operation: NSCompositeSourceOver fraction:1];

    NSRect rightRect = rect;
    rightRect.origin.x=0;
    rightRect.origin.y=2;
    rightRect.origin.x = knobrect.origin.x;
    [rightBarImage setSize:rightRect.size];
    [rightBarImage drawInRect:rightRect fromRect: NSZeroRect operation: NSCompositeSourceOver fraction:1];
}

ах я так близко. любая помощь относительно того, почему это происходит и как это решить, будет очень признательна, спасибо!


person han    schedule 21.10.2010    source источник


Ответы (4)


Хорошо, значит разобрались. видимо ползунок пытался быть умным и рисовать только там, где была ручка. поэтому, по-видимому, мне приходится все время аннулировать прямоугольник, переопределяя setNeedsDisplayInRect в классе ползунка.

#import "customSlider.h"

@implementation customSlider
-(void)setNeedsDisplayInRect:(NSRect)invalidRect{
    [super setNeedsDisplayInRect:[self bounds]];
}
@end
person han    schedule 11.11.2010
comment
Чувак, ты только что спас меня. Я искал решение именно этой проблемы в течение последних нескольких часов. Спасибо! - person eploko; 30.09.2011

Я новичок в Objective-c. Я тоже столкнулся с этой проблемой! Вот такое решение нашел, на что потратил два дня))) Сохраняем и восстанавливаем GraphicsState:

[NSGraphicsContext restoreGraphicsState];
//...
[leftBarImage drawInRect:leftRect fromRect: NSZeroRect operation: NSCompositeSourceOver fraction:1];
//...
[rightBarImage drawInRect:rightRect fromRect: NSZeroRect operation: NSCompositeSourceOver fraction:1];
[NSGraphicsContext saveGraphicsState];

Извините за плохой английский.

person NSLeader    schedule 01.08.2012
comment
Это сработало! Но я никак не могу понять, как это работает! Может ли кто-нибудь помочь объяснить это? - person YuDenzel; 17.03.2014

Удалите все сообщения -lockFocus и -unlockFocus. Платформа позаботится о настройке контекста рисования до того, как будут отправлены -drawBarInside:flipped: или -drawKnob:.

Кроме того, вы не должны создавать какие-либо объекты в методе рисования.

person NSResponder    schedule 21.10.2010
comment
Эй, спасибо NSResponder, я снял блокировку и разблокировал, а также удалил большую часть кода объекта создания. однако проблема все еще сохраняется. В настоящее время я рисую 3 изображения, левую полосу, правую полосу и ручку. Это происходит только тогда, когда я быстро двигаю мышью. Если я перетащу его медленно, то он рисует нормально. - person han; 22.10.2010
comment
Даже когда я использую закрытый метод (который мне не очень нравится) и закомментировал левую панель рисования. кажется, что та же проблема все еще сохраняется, если я быстро перетаскиваю ручку справа налево. И когда я отпускаю мышь, то недостающие пробелы исчезают, и поверх них рисуется красивое изображение. - person han; 22.10.2010

Ха, это другая история. Нет, NSResponder прав, и вы должны удалить весь материал «lockFocus», однако эта проблема является результатом полосы ползунка по умолчанию, нарисованной NSSliderCell где-то за пределами drawBarInside:flipped:flipped. Я тоже столкнулся с этой проблемой не так давно.

Вот обсуждение и решение: http://www.cocoabuilder.com/archive/cocoa/177288-preventing-nsslider-bar-from-drawing.html, короче говоря, вы можете переопределить весь drawCell:inView: или использовать «грязный трюк» с переопределением частного метод. Я лично не люблю хаки, но в данном случае я их

- (BOOL)_usesCustomTrackImage {
return YES;
}

И это решило проблему для меня

person Gobra    schedule 21.10.2010
comment
Привет, Гобра, да, я видел твой пост раньше. Я пробовал этот метод, но, к сожалению, он все еще не работает :( Кстати, левая сторона - это изображение, а не полоса по умолчанию. Это было случайное изображение, которое я взял со своего компьютера для тестирования. - person han; 22.10.2010
comment
О да, и даже если полоса есть, мои изображения кажутся нарисованными поверх нее, и на самом деле полоса не отображается. - person han; 22.10.2010