как избежать переопределения drawRect при отсечении

На данный момент я переопределяю drawRect в представлении, чтобы иметь возможность обрезать цветной прямоугольник маской (используя CGContextClipToMaskinside drawRect). Иногда я меняю цвет этого обрезанного прямоугольника. В этом случае drawRect вызывается снова, перерисовывая и обрезая прямоугольник новым цветом. Теперь я хочу не сразу менять цвет, а анимировать это. Проблема в том, что анимация не выполняется при переопределении drawRect (drawRect вызывается только один раз и сразу).

Есть ли способ выполнить эту анимацию, возможно, путем создания подкласса представления, чтобы я по-прежнему переопределял drawRect в суперклассе, но анимация каким-то образом выполнялась через подкласс, чтобы drawRect из суперкласса выполнялся несколько раз во время анимации?

Или также возможно вообще не переопределять drawRect, и все же иметь возможность как-то обрезать этот прямоугольник с маской? drawRectвыглядит примерно так:

CGContextRef ctx = UIGraphicsGetCurrentContext();
CGImageRef maskImage = [[UIImage imageNamed:maskName] CGImage];
CGContextClipToMask(ctx, rect, maskImage);

CGContextSetFillColorWithColor(ctx, self.currentColor);
CGContextFillRect( ctx, rect );

person JayAr    schedule 17.02.2012    source источник


Ответы (2)


Я думаю, что лучше использовать CALayer для маскировки вашего вида (не забудьте импортировать QuartzCore):

maskLayer.contents = (id)[UIImage imageNamed:maskName].CGImage; // maskLayer is a CALayer
view.layer.mask = maskLayer;

Теперь предположим, что у вас есть метод -(void)animate в вашем контроллере представления, вы выполнили его несколько раз, используя таймер или используя рекурсивные вызовы performSelector:withObject:afterDelay.

person sch    schedule 17.02.2012
comment
Круто, с вашим подходом мне не пришлось переопределять drawRect, поэтому я наконец-то могу использовать анимацию. Мне не нужно было использовать таймер или рекурсивно выполнять метод анимации, потому что теперь я могу использовать стандартную CoreAnimation. Большое спасибо! Следует отметить, что вы должны использовать изображения в формате png или некоторые изображения с чистым цветом (черно-белые маски больше не работают, но это не проблема). Также вы должны установить рамку слоя на границы вида, который вы хотите замаскировать, используя maskLayer.frame = [self bounds]; - person JayAr; 20.02.2012

Одним из решений было бы иметь таймер, который срабатывает для многократной перерисовки с течением времени всякий раз, когда изменяется цвет. Когда пользователь выбирает новый цвет, помечайте звездочкой NSTimer, которая срабатывает, скажем, 10 раз в секунду. Когда таймер сработает, обновите текущий цвет так, чтобы он находился на полпути от начального к конечному цвету, и сделайте представление недействительным. После того, как вы достигнете окончательного цвета, убейте таймер.

person user1118321    schedule 17.02.2012
comment
спасибо, похоже, что это должно работать, но также звучит как изобретение велосипеда (анимации). Если нет другого варианта, я воспользуюсь этим. - person JayAr; 17.02.2012