Подтвердить что ты не робот

Вычеркните треугольный вырез для индикации выбора в UIView

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

Custom UI design

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

Я понимаю, что subview облегчит анимацию, но усложнит рисунок; прямой рисунок, вероятно, сделает анимацию немного сложнее. И я не слишком хорошо знаком с Quartz, поэтому не уверен, как идти с прямым маршрутом рисования.

Спасибо заранее!

Обновление: Я посмотрел сообщение Мэтта Галлахера на рисование фигур с отверстиями, но это не "Я действительно отвечаю на мой вопрос. Есть ли способ для меня" увидеть" то, что под определенным путем в моей форме, и скопировать это?... А потом поддерживать анимацию?

Обновление 2: Я выполнил частичную работу, просто нарисовав дополнительный путь. Результат выглядит следующим образом: http://dl.dropbox.com/u/7828009/Category%20Selector.mov

Код:

CGRect cellRect = [self rectForCategoryNumber:(selectedCategoryIndex + 1)];
[[UIColor scrollViewTexturedBackgroundColor] setFill];
CGContextMoveToPoint(currentContext, self.frame.size.width, (cellRect.origin.y + cellRect.size.height * 0.15));
CGContextAddLineToPoint(currentContext, self.frame.size.width, (cellRect.origin.y + cellRect.size.height * 0.65));
CGContextAddLineToPoint(currentContext, self.frame.size.width * 0.8, (cellRect.origin.y + cellRect.size.height * 0.4));
CGContextClosePath(currentContext);
CGContextFillPath(currentContext);
[[UIColor darkGrayColor] setStroke];
CGContextSetLineCap(currentContext, kCGLineCapRound);
CGContextMoveToPoint(currentContext, self.frame.size.width, (cellRect.origin.y + cellRect.size.height * 0.15));
CGContextAddLineToPoint(currentContext, self.frame.size.width * 0.8, (cellRect.origin.y + cellRect.size.height * 0.4));
CGContextSetLineWidth(currentContext, 2.5);
CGContextStrokePath(currentContext);
[[UIColor lightGrayColor] setStroke];
CGContextMoveToPoint(currentContext,self.frame.size.width * 0.8, (cellRect.origin.y + cellRect.size.height * 0.4));
CGContextAddLineToPoint(currentContext, self.frame.size.width, (cellRect.origin.y + cellRect.size.height * 0.65));
CGContextSetLineWidth(currentContext, 1.0);
CGContextStrokePath(currentContext);

Очевидно, что в этом случае он работает только потому, что я использую тот же цвет заливки в обоих случаях; Я хотел бы устранить эту зависимость, если это возможно. Кроме того, конечно, я хотел бы оживить положение этого треугольника.

Обновление 3:. Что я пытался сделать для анимации:

static CALayer *previousLayer = nil;
static CGMutablePathRef previousPath = nil;
// … Get context, etc.
CAShapeLayer *shapeLayer = [[CAShapeLayer alloc] init];
shapeLayer.path = shapePath;
[shapeLayer setFillColor:[[UIColor redColor] CGColor]];
[shapeLayer setStrokeColor:[[UIColor blackColor] CGColor]];
[shapeLayer setBounds:self.bounds];
[shapeLayer setAnchorPoint:self.bounds.origin];
[shapeLayer setPosition:self.bounds.origin];
if (previousPath) {     // Animate change
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"changePath"];
    animation.duration = 0.5;
    animation.fromValue = (id)previousPath;
    animation.toValue = (id)shapePath;
    [shapeLayer addAnimation:animation forKey:@"animatePath"];
    previousPath = shapePath;
}

if (previousLayer)
    [previousLayer removeFromSuperlayer];
previousLayer = shapeLayer;
[self.layer addSublayer:shapeLayer];
4b9b3361

Ответ 1

Вы посмотрели на CAShapeLayer? Вы можете создать путь для своей панели выбора, которая определяет весь контур, включая исключение треугольника для каждого состояния, которое нужно маскировать. Затем вы можете обвести слой, если вы хотите, чтобы контур, который вы показываете на своем изображении, установил свойства lineWidth и strokeColor. Это должно быть в состоянии дать вам то, что вам нужно. Свойство path в CAShapeLayer является анимированным, что означает, что все, что вам нужно сделать, это установить свойство path и оно будет анимироваться (предполагая, что ваши слои являются подслоями представления, а не корневым слоем).

С наилучшими пожеланиями.

Обновление с кодом

Этот код:

- (void)viewDidLoad
{
  [super viewDidLoad];

  [[self view] setBackgroundColor:[UIColor blueColor]];

  CGMutablePathRef path = CGPathCreateMutable();
  CGPathMoveToPoint(path,NULL,0.0,0.0);
  CGPathAddLineToPoint(path, NULL, 160.0f, 0.0f);  
  CGPathAddLineToPoint(path, NULL, 160.0f, 100.0f);
  CGPathAddLineToPoint(path, NULL, 110.0f, 150.0f);
  CGPathAddLineToPoint(path, NULL, 160.0f, 200.0f);
  CGPathAddLineToPoint(path, NULL, 160.0f, 480.0f);
  CGPathAddLineToPoint(path, NULL, 0.0f, 480.0f);
  CGPathAddLineToPoint(path, NULL, 0.0f, 0.0f);


  CAShapeLayer *shapeLayer = [CAShapeLayer layer];
  [shapeLayer setPath:path];
  [shapeLayer setFillColor:[[UIColor redColor] CGColor]];
  [shapeLayer setStrokeColor:[[UIColor blackColor] CGColor]];
  [shapeLayer setBounds:CGRectMake(0.0f, 0.0f, 160.0f, 480)];
  [shapeLayer setAnchorPoint:CGPointMake(0.0f, 0.0f)];
  [shapeLayer setPosition:CGPointMake(0.0f, 0.0f)];
  [[[self view] layer] addSublayer:shapeLayer];

  CGPathRelease(path);

}

приводит к этому отображению:

enter image description here

И вы можете скачать образец проекта здесь:

http://cl.ly/3J1B1f1l2423142l3X35