Как нарисовать треугольник над UIImage в UIImageView

У меня проблемы с рисованием поверх изображения в UIImageView, я уже просмотрел " Нарисуйте еще одно изображение на UIImage " Но это было не так уж важно. Вот мой сценарий: у меня есть UIPopoverController с UITableView в нем, и я хочу отображать треугольник, указывающий вверх, когда пользователь находится внизу прокручиваемого табличного представления.

Мой код:

- (UIImage *) drawTriangleInViewForSize:(CGSize)sizeOfView
                     imageToDrawOn:(UIImage *)underImage
                           isAtTop:(BOOL)top{
CGPoint firstPoint;
CGPoint secondPoint;
CGPoint thirdPoint;

if(!top){
 //I want to draw a equilateral triangle (side length 10) in the center of the image in
 //the imageView, these are the coordinates I am using.
    firstPoint = CGPointMake(underImage.size.width * 0.5 + 5, underImage.size.height * 0.5 - 5);
    secondPoint = CGPointMake((firstPoint.x - 10), firstPoint.y);
    thirdPoint = CGPointMake(underImage.size.width * 0.5,
                             underImage.size.width * 0.5 + 5);

}
*/
**DISREGARD**
else{
    firstPoint = CGPointMake(sizeOfView.width * 0.5 + 5,
                             self.tableViewChoices.rowHeight * 0.5 - 5);
    secondPoint = CGPointMake((firstPoint.x - 10), firstPoint.y);
    thirdPoint = CGPointMake(sizeOfView.width * 0.5,
                             self.tableViewChoices.rowHeight * 0.5 + 5);
}*/
//get the size of the image for the drawInRect: method
CGFloat imageViewWidth = sizeOfView.width;
CGFloat imageViewHeight = self.tableViewChoices.rowHeight;

//set the graphics context to be the size of the image
UIGraphicsBeginImageContextWithOptions(underImage.size, YES, 0.0);

[underImage drawInRect:CGRectMake(0.0, 0.0, imageViewWidth, imageViewHeight)];

//set the line attributes
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(ctx, [UIColor blackColor].CGColor);
CGContextSetFillColorWithColor(ctx, [UIColor clearColor].CGColor);
CGContextSetLineWidth(ctx, 0.05);

UIGraphicsPushContext(ctx);
    //draw the triangle
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, firstPoint.x, firstPoint.y);
CGContextAddLineToPoint(ctx, secondPoint.x, secondPoint.y);
CGContextAddLineToPoint(ctx, thirdPoint.x, thirdPoint.y);
CGContextAddLineToPoint(ctx, firstPoint.x, firstPoint.y);
CGContextClosePath(ctx);

UIGraphicsPopContext();

//get the image
UIImage *rslt = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

return rslt;
}

Кажется, я не могу нарисовать треугольник для UIImage в imageView, конечный результат - либо полностью черный ImageView (UIImage - это просто white.png), либо одна строка в верхней части изображения (в зависимости от использую ли я drawInRect: или drawAtPoint: и какие координаты использую). Все, что мне нужно сделать, это нарисовать треугольник, направленный вверх, это не сложно, и действительно похоже, что я делаю это «по инструкции».


person Sakiboy    schedule 22.07.2013    source источник
comment
Я не уверен, но думаю, вам придется поместить треугольник в его собственное представление и добавить его в imageView.   -  person Jamie    schedule 22.07.2013
comment
Спасибо, я разберусь с этим.   -  person Sakiboy    schedule 23.07.2013


Ответы (2)


Ваш код выглядит слишком сложным для такого рода задач. Почему бы вам не использовать простой UIImageView с любым изображением треугольника, которое вам когда-либо понадобится? Просто покажи это, когда таблица внизу и все.

Обратите внимание: когда вы реализуете делегат для UITableView, вы также можете перехватывать сообщения делегата UIScrollView, такие как scrollView:didEndDecelerating: и т. Д.

Что касается вашего кода, вы пропустили фактическое рисование пути:

CGContextAddPath(context, trianglePath);
CGContextFillPath(context);

Чтобы сделать это возможным, вы должны использовать функции, связанные с путями. Использование функций, связанных с CGContext, кажется неправильным, поскольку такой подход может удалить старый путь. Итак, лучший способ - создать свой собственный изменяемый путь в контексте, нарисовать в нем свой треугольник, а затем нарисовать этот путь в контексте с помощью функций, упомянутых выше.

person Andrey Chevozerov    schedule 22.07.2013
comment
Не могли бы вы объяснить, как использовать «CGContextAddPath (context, TrianglePath);» ?? В те несколько раз, когда мне приходилось рисовать с использованием операций CGContext, я никогда не использовал CGContextAddPath () (у меня есть только опыт рисования линий и прямоугольников в pdf с помощью CGContext ..). Спасибо за ваш ответ, если я не могу заставить это работать, я просто добавлю простой треугольник .png в свой imageView. Мне просто нужен некоторый опыт рисования компьютерной графики. - person Sakiboy; 23.07.2013
comment
Теперь я вижу, как использовать CGContextAddPath (), и понимаю, что забыл добавить CGContextDrawPath (ctx, kCGPathFillStroke); в моем коде тоже ... Спасибо за ответ. - person Sakiboy; 23.07.2013

Вот мой завершенный код для рисования треугольника на UIImage в UIImageView.

//draws triangle up or down on a UIImage.
+(UIImage *) drawTriangleInViewForSize:(CGSize)sizeOfView
                     imageToDrawOn:(UIImage *)underImage
                           isAtTop:(BOOL)top
{
CGFloat rowHeight = underImage.size.height; //44; //self.tableViewChoices.rowHeight;
CGPoint firstPoint;
CGPoint secondPoint;
CGPoint thirdPoint;

CGFloat imageViewWidth = sizeOfView.width;
CGFloat imageViewHeight = rowHeight;


if(!top){
    //draw a upward facing triangle in the center of the view.
    firstPoint = CGPointMake(imageViewWidth * 0.5 + 15, imageViewHeight * 0.5 - 5);
    secondPoint = CGPointMake((firstPoint.x - 30), firstPoint.y);
    thirdPoint = CGPointMake(imageViewWidth * 0.5,
                             imageViewHeight * 0.5 + 5);

}else{
    //disregard this 'else'
    firstPoint = CGPointMake(sizeOfView.width * 0.5 + 15,
                             rowHeight * 0.5 - 5);
    secondPoint = CGPointMake((firstPoint.x - 10), firstPoint.y);
    thirdPoint = CGPointMake(sizeOfView.width * 0.5,
                             rowHeight * 0.5 + 5);

}


//get the image context with options(recommended funct to use)
//get the size of the imageView
UIGraphicsBeginImageContextWithOptions(CGSizeMake(imageViewWidth, imageViewHeight), YES, 0.0);

//use the the image that is going to be drawn on as the receiver
[underImage drawInRect:CGRectMake(0.0, 0.0, imageViewWidth, imageViewHeight)];



CGContextRef ctx = UIGraphicsGetCurrentContext();

CGContextSetLineWidth(ctx, 0.5);

//UIGraphicsPushContext(ctx);

//uses path ref
CGMutablePathRef path = CGPathCreateMutable();
//draw the triangle
CGPathMoveToPoint(path, NULL, firstPoint.x, firstPoint.y);
CGPathAddLineToPoint(path, NULL, secondPoint.x, secondPoint.y);
CGPathAddLineToPoint(path, NULL, thirdPoint.x, thirdPoint.y);
CGPathAddLineToPoint(path, NULL, firstPoint.x, firstPoint.y);
//close the path
CGPathCloseSubpath(path);
//add the path to the context
CGContextAddPath(ctx, path);
CGContextSetFillColorWithColor(ctx, [UIColor whiteColor].CGColor);
CGContextSetStrokeColorWithColor(ctx, [UIColor blackColor].CGColor);
CGContextFillPath(ctx);
CGContextAddPath(ctx, path);
CGContextStrokePath(ctx);
CGPathRelease(path);

//UIGraphicsPopContext();

//get the new image with the triangle
UIImage *rslt = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

return rslt;

}
person Sakiboy    schedule 29.07.2013