简体   繁体   中英

Unable to scale shapes to match the dimensions of UIView

I have created a custom view that draws shapes of varying sides. The view is added to main view as a subview as given below. The shapes are of different dimensions.

子视图中的多个 UIView 形状

个人子视图

My source code is given below

-(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);
}

This constitutes one single shape. This is how I am drawing the rest of the views.

-(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) I don't know how to make them have the same dimensions. How can I do that? (First image)

2) the images don't scale up to the size of the UIView (Second image).

Your current code makes the radius inversely proportional to the number of sides:

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

so the more sides, the smaller the image. A quick fix would be to just make the radius half the frame width:

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

This will mean shapes with an even number of sides fill the frame width. But those with an odd number of sides will appear to have space to the left. If you want to adjust for that you will need more detailed calculations for the width, and you will also need to move the "centre" of the shape. For an odd number sides, the radius would need to be:

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

and xCoord would need to be:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM