Pergunta

Eu tenho um gradiente que tem cantos arredondados que eu uso para um plano de fundo personalizado do UitableViewCell. Estou tentando aplicar um golpe no caminho, mas não consigo fazer isso e não consigo ver onde estou dando errado.

  CGFloat minx = CGRectGetMinX(rect) , midx = CGRectGetMidX(rect), maxx = CGRectGetMaxX(rect) ;
  CGFloat miny = CGRectGetMinY(rect) , maxy = CGRectGetMaxY(rect) ;
  minx = minx + 1;
  miny = miny ;

  maxx = maxx - 1;
  maxy = maxy - 1;

  CGContextMoveToPoint(c, minx, miny);
  CGContextAddArcToPoint(c, minx, maxy, midx, maxy, kDefaultMargin);
  CGContextAddArcToPoint(c, maxx, maxy, maxx, miny, kDefaultMargin);
  CGContextAddLineToPoint(c, maxx, miny);
  CGContextAddLineToPoint(c, minx, miny);

  // Fill and stroke the path
  CGContextClip(c);
  CGContextStrokePath(c);  

  CGFloat locations[2] = { 0.0, 1.0 };
  CGFloat mycomponents[8] = TABLE_CELL_BACKGROUND;
  CGColorSpaceRef myColorspace = CGColorSpaceCreateDeviceRGB();
  CGGradientRef myGradient = CGGradientCreateWithColorComponents(myColorspace, mycomponents, locations, 2);
  CGContextDrawLinearGradient(c, myGradient, CGPointMake(minx,miny), CGPointMake(minx,maxy), 0);
  CGGradientRelease(myGradient);
  CGColorSpaceRelease(myColorspace);

Este código arredonda o retângulo à direita e aplica o gradiente, mas não acaricia a linha. Onde está meu erro?

TEXTO DE ALT HTTP://grab.by/26ye



EDITAR:De acordo com as recomendações da Subw, mudei o código para ser:

    CGContextRef c = UIGraphicsGetCurrentContext();
    CGColorSpaceRef myColorspace = CGColorSpaceCreateDeviceRGB();
    CGGradientRef myGradient = nil;
    CGFloat components[8] = TABLE_CELL_BACKGROUND;
    CGContextSetFillColorWithColor(c, [[UIColor redColor] CGColor]);
    CGContextSetStrokeColorWithColor(c, [[UAColor redColor] CGColor]);
    CGContextSetLineWidth(c, 2);

    CGFloat minx = CGRectGetMinX(rect) , midx = CGRectGetMidX(rect), maxx = CGRectGetMaxX(rect) ;
    CGFloat miny = CGRectGetMinY(rect) , maxy = CGRectGetMaxY(rect) ;
    minx = minx + 1;
    miny = miny ;

    maxx = maxx - 1;
    maxy = maxy - 1;

    CGContextMoveToPoint(c, minx, miny);
    CGContextAddArcToPoint(c, minx, maxy, midx, maxy, kDefaultMargin);
    CGContextAddArcToPoint(c, maxx, maxy, maxx, miny, kDefaultMargin);
    CGContextAddLineToPoint(c, maxx, miny);
    CGContextAddLineToPoint(c, minx, miny);

    // Fill and stroke the path
    CGContextSaveGState(c);
    CGContextClip(c);

    CGFloat locations[2] = { 0.0, 1.0 };
    CGFloat mycomponents[8] = TABLE_CELL_BACKGROUND;
    CGColorSpaceRef myColorspace = CGColorSpaceCreateDeviceRGB();
    myGradient = CGGradientCreateWithColorComponents(myColorspace, mycomponents, locations, 2);
    CGContextDrawLinearGradient(c, myGradient, CGPointMake(minx,miny), CGPointMake(minx,maxy), 0);

    CGContextRestoreGState(c);
    CGContextStrokePath(c);

Mas o Rect sai assim ...

TEXTO DE ALT HTTP://grab.by/2714

... sem fronteira. Se eu mudar o CGContextStrokePath(c) ser CGContextStrokeRect(c, rect), o golpe aparece (eu o fiz vermelho para esclarecimentos). Mas de alguma forma, ao acariciar o caminho, não estou recebendo nenhum golpe :(

ALT TEXTO http://grab.by/27am

Foi útil?

Solução

Respondendo ao seu código revisado, cito a documentação:

Ao contrário do caminho atual, o caminho de recorte atual faz parte do estado gráfico. Portanto, para reinscrição da área pintável, restaurando o caminho de recorte para um estado anterior, você deve salvar o estado dos gráficos antes de prender e restaurar o estado gráfico depois de concluir qualquer desenho cortado.

Depois de determinar o novo caminho de recorte, a função redefine o caminho atual do contexto para um caminho vazio.

CGContextClip

Então, o caminho de desenho atual é não parte do estado gráfico. Então aqui está o que você está fazendo:

  1. Construir caminho de desenho
  2. Salve o gstate
  3. Adicione o caminho de desenho atual ao caminho de recorte; Caminho de desenho atual claro
  4. Desenhe gradiente
  5. Restaurar o GSTATE (o caminho de recorte anterior é restaurado; o caminho do desenho permanece vazio)
  6. Acaricie nada

A solução é desenhar o caminho para um objeto CGPath e adicioná -lo como o caminho atual antes de cortar (depois de salvar o GState) e antes de acariciar.

Você também deve decidir se deseja que isso seja um golpe externo, um golpe interno ou um golpe centrado. Para um golpe centrado, o golpe enquanto não estiver preso. Para um golpe interno, golpe enquanto cortou. Para um golpe externo, inverta o caminho, depois prenda e depois o golpe. Você vai querer dobrar a largura da sua linha para as duas últimas formas, pois você estará recortando metade do golpe.

Se eu mudar o CGContextStrokePath(c) ser CGContextStrokeRect(c, rect), o golpe aparece.

Porque essa função adiciona um caminho desse retângulo ao caminho de desenho atual antes de acariciar.

Outras dicas

Não tem certeza, mas talvez você esteja pintando o gradiente sobre o golpe?

Você está desenhando o gradiente sobre o golpe e/ou recorda a região que você acaricia.

Eu acho que o seguinte pode funcionar melhor:

CGContextSaveGState(c);
CGContextClip(c);

//gradient drawing stuff

CGContextRestoreGState(c);
CGContextStrokePath(c);

Obviamente, você também precisa definir a cor e a largura corretamente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top