【问题标题】:Draw Triangle iOS绘制三角形 iOS
【发布时间】:2014-08-30 01:14:03
【问题描述】:

下面的代码给我画了一个圆,如何修改现有的代码来画一个三角形呢?

    _colorDotLayer = [CALayer layer];

    CGFloat width = self.bounds.size.width-6;
    _colorDotLayer.bounds = CGRectMake(0, 0, width, width);
    _colorDotLayer.allowsGroupOpacity = YES;
    _colorDotLayer.backgroundColor = self.annotationColor.CGColor;
    _colorDotLayer.cornerRadius = width/2;
    _colorDotLayer.position = CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2);

【问题讨论】:

  • 这种方法对绘制三角形没有用处。您应该查看 UIBezierPath 来做到这一点。
  • 你也应该看看 CGContext。
  • SO 不是代码翻译服务。

标签: ios objective-c core-graphics


【解决方案1】:

虽然展示了几个核心图形解决方案,但我想添加一个基于核心动画的解决方案。

- (void)viewDidLoad
{
    [super viewDidLoad];
    UIBezierPath* trianglePath = [UIBezierPath bezierPath];
    [trianglePath moveToPoint:CGPointMake(0, view3.frame.size.height-100)];
    [trianglePath addLineToPoint:CGPointMake(view3.frame.size.width/2,100)];
    [trianglePath addLineToPoint:CGPointMake(view3.frame.size.width, view2.frame.size.height)];
    [trianglePath closePath];

    CAShapeLayer *triangleMaskLayer = [CAShapeLayer layer];
    [triangleMaskLayer setPath:trianglePath.CGPath];

    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0,0, size.width, size.height)];

    view.backgroundColor = [UIColor colorWithWhite:.75 alpha:1];
    view.layer.mask = triangleMaskLayer;
    [self.view addSubview:view];
}

代码基于我的博文。

【讨论】:

  • 此网页不可用
  • 如果视图需要调整大小以适应屏幕,这是很常见的(因为它以您在情节提要中使用的任何大小从情节提要中出来)。您需要在布局阶段设置路径(如this answer),或使用基于drawRect: 的解决方案,如this one,内容模式为重绘或缩放。
【解决方案2】:
@implementation TriangleView {
    CAShapeLayer *_colorDotLayer;
}

- (void)layoutSubviews {
    [super layoutSubviews];

    if (_colorDotLayer == nil) {
        _colorDotLayer = [CAShapeLayer layer];
        _colorDotLayer.fillColor = self.annotationColor.CGColor;
        [self.layer addSublayer:_colorDotLayer];
    }

    CGRect bounds = self.bounds;
    CGFloat radius = (bounds.size.width - 6) / 2;
    CGFloat a = radius * sqrt((CGFloat)3.0) / 2;
    CGFloat b = radius / 2;
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(0, -radius)];
    [path addLineToPoint:CGPointMake(a, b)];
    [path addLineToPoint:CGPointMake(-a, b)];
    [path closePath];
    [path applyTransform:CGAffineTransformMakeTranslation(CGRectGetMidX(bounds), CGRectGetMidY(bounds))];
    _colorDotLayer.path = path.CGPath;
}

- (void)awakeFromNib {
    [super awakeFromNib];
    self.annotationColor = [UIColor redColor];
}

@end

结果:

【讨论】:

    【解决方案3】:

    我认为比这个解决方案更容易:

     UIBezierPath *path = [UIBezierPath new];
    [path moveToPoint:(CGPoint){20, 0}];
    [path addLineToPoint:(CGPoint){40, 40}];
    [path addLineToPoint:(CGPoint){0, 40}];
    [path addLineToPoint:(CGPoint){20, 0}];
    
    // Create a CAShapeLayer with this triangular path
    // Same size as the original imageView
    CAShapeLayer *mask = [CAShapeLayer new];
    mask.frame = self.viewTriangleCallout.bounds;
    mask.path = path.CGPath;
    

    这是我的白色三角形: 您可以根据需要更改点或旋转:

    UIBezierPath *path = [UIBezierPath new];
    [path moveToPoint:(CGPoint){0, 0}];
    [path addLineToPoint:(CGPoint){40, 0}];
    [path addLineToPoint:(CGPoint){20, 20}];
    [path addLineToPoint:(CGPoint){0, 0}];
    
    // Create a CAShapeLayer with this triangular path
    // Same size as the original imageView
    CAShapeLayer *mask = [CAShapeLayer new];
    mask.frame = self.viewTriangleCallout.bounds;
    mask.path = path.CGPath;
    

    【讨论】:

    • 最好用closePath代替最后的addLineToPoint。
    【解决方案4】:

    示例代码,它基于这个绘制星星的SO Answer

    @implementation TriangleView
    
    -(void)drawRect:(CGRect)rect {
        CGContextRef context = UIGraphicsGetCurrentContext();
    
        int sides = 3;
        double size = 100.0;
        CGPoint center = CGPointMake(160.0, 100.0);
    
        double radius = size / 2.0;
        double theta = 2.0 * M_PI / sides;
    
        CGContextMoveToPoint(context, center.x, center.y-radius);
        for (NSUInteger k=1; k<sides; k++) {
            float x = radius * sin(k * theta);
            float y = radius * cos(k * theta);
            CGContextAddLineToPoint(context, center.x+x, center.y-y);
        }
        CGContextClosePath(context);
    
        CGContextFillPath(context);           // Choose for a filled triangle
        // CGContextSetLineWidth(context, 2); // Choose for a unfilled triangle
        // CGContextStrokePath(context);      // Choose for a unfilled triangle
    }
    
    @end
    

    【讨论】:

      【解决方案5】:

      使用 UIBezeierPaths

      CGFloat radius = 20;
      CGMutablePathRef path = CGPathCreateMutable();
      CGPathMoveToPoint(path, NULL, (center.x + bottomLeft.x) / 2, (center.y + bottomLeft.y) / 2);
      CGPathAddArcToPoint(path, NULL, bottomLeft.x, bottomLeft.y, bottomRight.x, bottomRight.y, radius);
      CGPathAddArcToPoint(path, NULL, bottomRight.x, bottomRight.y, center.x, center.y, radius);
      CGPathAddArcToPoint(path, NULL, center.x, center.y, bottomLeft.x, bottomLeft.y, radius);
      CGPathCloseSubpath(path);
      
      UIBezierPath *bezierPath = [UIBezierPath bezierPathWithCGPath:path];
      CGPathRelease(path);
      

      【讨论】:

      • 这不是可执行代码。什么是“中心”?什么是“左下角”?
      猜你喜欢
      • 2014-12-10
      • 2014-11-18
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 2020-12-08
      • 2015-05-26
      • 2021-08-03
      • 1970-01-01
      相关资源
      最近更新 更多