(iphone) добавление тени к слою

Я хотел бы добавить тень к UIImageView, который имеет слои изображения.

Я пробовал маршрут self.layer.shadowOffset / shadowOpacity, но он слишком медленный ..
Когда я хочу добавить тень, я вызываю метод addShadowLayerWithOffset, ниже которого я ожидал вызвать drawRect и добавить тень ..
Но drawRect не вызывается.

Что мне здесь не хватает?

- (void)drawRect:(CGRect)rect
{
    SYSLOG(LOG_DEBUG, "in drawRect, isShadowed: %d", isShadowed);
    if (isShadowed == true)
    {
        CGContextRef currentContext = UIGraphicsGetCurrentContext();
        CGContextSaveGState(currentContext);
        CGContextSetShadow(currentContext, CGSizeMake(100, 100), 3);
        [super drawRect: rect];
        CGContextRestoreGState(currentContext);
    }
    else
        [super drawRect: rect];
}

- (void) addShadowLayerWithOffset: (int)offset
{
//  self.layer.shadowOffset = CGSizeMake(offset,offset);                                                                                                                                                                                                                      
//  self.layer.shadowOpacity = 0.7f;                                                                                                                                                                                                                                          
//  self.layer.shadowRadius = 5.0;                                                                                                                                                                                                                                            
    isShadowed = true;
    [self setNeedsDisplay];
}
  • РЕДАКТИРОВАТЬ

Хорошо, я получил вызов drawLayer. Мне нужен был [self.layer setNeedsDisplay], а не [self.layer setNeedsPlay], где self - это подкласс UIImageView.

Но тень не прорисовывается, фактически не отображается и само изображение (исходный слой).
Что мне изменить?

- (void) drawLayer: (CALayer*) layer inContext: (CGContextRef)context
{
    SYSLOG(LOG_DEBUG, "in drawLayer, isShadowed: %d", isShadowed);
    if(isShadowed == true)
    {
        CGContextSaveGState(context);
        CGContextSetShadow(context, CGSizeMake(10, 10), 3);
        [super drawLayer: layer inContext: context];
        CGContextRestoreGState(context);
    }
    else
        [super drawLayer: layer inContext: context];
}

person eugene    schedule 18.02.2011    source источник


Ответы (3)


ты звонишь:

[super drawRect: rect];

но яблоко говорит:

Никогда не вызывайте этот метод напрямую. Чтобы сделать часть вашего представления недействительной и, таким образом, вызвать перерисовку этой части, вызовите вместо этого метод setNeedsDisplay или setNeedsDisplayInRect :.

вместо drawRect пробовали когда-нибудь drawLayer?

-(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)context
person meronix    schedule 18.02.2011
comment
Я полагаю, что [super drawRect: rect] подойдет, как и [super dealloc]. Во всяком случае, drawLayer тоже не вызывается. Я установил делегат слоев, которые я добавил в представление. - person eugene; 18.02.2011
comment
Спасибо, я получил вызов drawLayer, но изображение не отрисовывается, см. Мои изменения, пожалуйста - person eugene; 18.02.2011
comment
@Eugene: ops, извините, вы правы, я не видел, что это было в методе drawRect ... теперь я смотрю на ваше редактирование ... - person meronix; 18.02.2011

попробуйте вызвать этот метод:

вызывается UIViewController:

[self addShadowedLayer:self.view inRect:( CGRectMake(30, 30, 128, 192))];


- (void)addShadowedLayer:(UIView *)aUIView inRect:(CGRect)aRect {
    CALayer *sublayer = [CALayer layer];
    sublayer.backgroundColor = [UIColor colorWithWhite:1.0 alpha:1.0].CGColor;
    sublayer.shadowOffset = CGSizeMake(0, 3);
    sublayer.shadowRadius = 5.0;
    sublayer.shadowColor = [UIColor blackColor].CGColor;
    sublayer.shadowOpacity = 0.8;
    sublayer.frame = aRect;
    sublayer.cornerRadius = 26.0;
    [aUIView.layer addSublayer:sublayer];
}

он просто добавляет белый закругленный прямоугольник, но вам нужна только его тень ...

person meronix    schedule 18.02.2011

Я думаю, вы лаете не на то дерево. Вы сказали, что указывать тень непосредственно на слое изображения слишком медленно. Это правильно, потому что ОС использует альфа-канал, чтобы определить, где рисовать тень.

Что вы можете сделать для повышения производительности рендеринга в iOS 3.2 и более поздних версиях, так это указать путь тени. Сначала вы создаете CGPathRef и устанавливаете его как теневой путь слоя.

Это должно значительно улучшить рендеринг без необходимости добавления еще одного слоя только для тени.

person GorillaPatch    schedule 18.02.2011