无法缩放形状以匹配 UIView 的尺寸

Posted

技术标签:

【中文标题】无法缩放形状以匹配 UIView 的尺寸【英文标题】:Unable to scale shapes to match the dimensions of UIView 【发布时间】:2017-09-30 03:57:39 【问题描述】:

我创建了一个自定义视图,可以绘制不同侧面的形状。该视图作为子视图添加到主视图,如下所示。形状具有不同的尺寸。

我的源代码如下

-(instancetype) initWithSides:(NSUInteger) sides andFrame:(CGRect)frame 
        self = [super initWithFrame:frame];
        if (self) 
            [self setBackgroundColor:[UIColor clearColor]];
            self.sides = sides;
            self.radius =  CGRectGetWidth(self.frame) * 1.5 / sides);
        
        return self;


    -(void) drawRect:(CGRect) frame 
// Sides is passed as constructor argument. 4 sides means a quadrilateral etc.
// Get CGPAthRef instance

        CGFloat angle = DEGREES_TO_RADIANS(360 / ((CGFloat) self.sides));
    int count = 0;
    CGFloat xCoord = CGRectGetMidX(self.frame);
    CGFloat yCoord = CGRectGetMidY(self.frame);
    while (count < self.sides) 
        CGFloat xPosition =
            xCoord + self.radius * cos(angle * ((CGFloat) count));
        CGFloat yPosition =
            yCoord + self.radius * sin(angle * ((CGFloat) count));

        [self.points addObject:[NSValue valueWithCGPoint:CGPointMake(xPosition, yPosition)]];

        count ++;
    

    NSValue* v = [self.points firstObject];
    CGPoint first = v.CGPointValue;

    CGMutablePathRef path = CGPathCreateMutable();
     CGPathMoveToPoint(path, nil, first.x, first.y);

    for (int ix = 1; ix < [self.points count]; ix++) 
        NSValue* pValue = [self.points objectAtIndex:ix];
        CGPoint p = pValue.CGPointValue;
        CGPathAddLineToPoint(path, nil, p.x, p.y);
    

    CGPathCloseSubpath(path);


   CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextAddPath(context, path);
    [self colourView:context withPath:path];
  

-(void) colourView:(CGContextRef) context withPath:(CGPathRef) ref 
    NSUInteger num = arc4random_uniform(8) + 1;
    UIColor* color = nil;
    switch (num) 
        case 1:
            color = [UIColor redColor];
            break;
        case 2:
            color = [UIColor greenColor];
            break;
        case 3:
            color = [UIColor yellowColor];
            break;
        case 4:
            color = [UIColor blueColor];
            break;
        case 5:
            color = [UIColor orangeColor];
            break;
        case 6:
            color = [UIColor brownColor];
            break;
        case 7:
            color = [UIColor purpleColor];
            break;
        case 8:
            color = [UIColor blackColor];
            break;
        default:
            break;
    

    CGContextSetFillColorWithColor(context, color.CGColor);
    CGContextFillPath(context);

这构成一个单一的形状。这就是我绘制其余视图的方式。

-(void) initDrawView 
    NSUInteger width = CGRectGetWidth(self.view.bounds) / 8;
    NSUInteger height = (CGRectGetHeight(self.view.frame))/ 8;
    UITapGestureRecognizer *singleFingerTap =
        [[UITapGestureRecognizer alloc] initWithTarget:self
                                            action:@selector(handleSingleTap:)];
    for (int i = 0 ; i < 8; i++) 
        CGFloat yCoord = i * height + i * 15;
        for (int j = 0; j < 8; j ++) 
            int side = 3 + arc4random() % 8;
            CGFloat xCoord = j * width;

            SimpleRegularPolygonView* view =
                [[SimpleRegularPolygonView alloc] initWithSides:side andFrame:CGRectMake(xCoord, yCoord, width, height)];
            [view sizeToFit];
            view.viewEffectsDelegate = self;
            [view setTag: (8 * i + j)];
            [self.view addGestureRecognizer:singleFingerTap];
            [self.view addSubview:view];
        
    

1) 我不知道如何使它们具有相同的尺寸。我怎样才能做到这一点? (第一张图片)

2) 图片未按比例放大到 UIView(第二张图片)的大小。

【问题讨论】:

【参考方案1】:

您当前的代码使半径与边数成反比:

self.radius =  CGRectGetWidth(self.frame) * 1.5 / sides;

所以边数越多,图像越小。一个快速的解决方法是将半径设为框架宽度的一半:

self.radius =  CGRectGetWidth(self.frame) /2;

这意味着具有偶数边的形状会填充框架宽度。但是那些边数为奇数的人似乎在左边有空间。如果您想对此进行调整,您将需要对宽度进行更详细的计算,并且您还需要移动形状的“中心”。对于奇数边,半径需要是:

self.radius =  CGRectGetWidth(self.frame) /(1 + cos(angle / 2));

xCoord 需要:

CGFloat xCoord = CGRectGetMinX(self.frame) + self.radius * cos(angle/2);

【讨论】:

什么样的三角计算?

以上是关于无法缩放形状以匹配 UIView 的尺寸的主要内容,如果未能解决你的问题,请参考以下文章

如何缩放 UIImage 以适应 UIScrollView 的尺寸?

Flutter 尺寸缩放形状颜色阴影变换动画

UIView 高度无法跨设备正确缩放图像

IOS拖放与缩放

UIView中矢量图形的平滑缩放

在方向更改时自动缩放 UIView 以按比例缩放以适合父视图