0

I want to extend an existing custom UIViewclass so it can be used in several places within an app. The view has a method that arranges multiple UIButtonsin a circle. The number of UIButtons will vary depending on where the method is called. So too will the size of the UIButton and the radius of the circle. It would also be useful (but not essential) to be able to call the method several times within the same UIView.

Which is the better way ? to make this a category or a sub-class? It would appear I could use either based on this discussion of pros and cons. But my question is more specific.

I’ve made categories for UIColor and UIFontbut so far I have not been able to make this method work as a category just by following Apple's documentation (I tried it both as a class method and as an instance method). Before I try to make it work as a subclass, can someone who has done it before, either way, please recommend the better approach based on my example below.

Here is the method as it was in the CustomView

circleOfButtons

- (void)circleOfButtons {

screenCentre.x                          = CGRectGetWidth  (self.bounds) / 2;
screenCentre.y                          = CGRectGetHeight (self.bounds) / 2;

for (int i = 1; i <= buttonCount; i++) {

    radians                             = 2 * M_PI * i / buttonCount;
    CGFloat arcStartPoint                 = - M_PI / 2; // first point clockwise after 12 o'clock
    buttonCentre.x                      = screenCentre.x + radius * cos(radians + arcStartPoint);
    buttonCentre.y                      = screenCentre.y + radius * sin(radians + arcStartPoint);

    CGPoint target                      = CGPointMake(buttonCentre.x, buttonCentre.y);

    CGFloat x                           = screenCentre.x - buttonSize / 2;
    CGFloat y                           = screenCentre.y - buttonSize / 2;
    CGFloat wide                        = buttonSize;
    CGFloat high                        = buttonSize;
    UIButton *circleButton              = [[UIButton alloc] initWithFrame:CGRectMake(x, y, wide, high)];

    [circleButton setTag:i];        
    circleButton.clipsToBounds          = YES;
    circleButton.layer.masksToBounds    = NO;
    circleButton.layer.borderWidth      = 0.25f;
    circleButton.layer.cornerRadius     = buttonSize/2;
    circleButton.layer.borderColor      = [UIColor blackColor].CGColor;
    circleButton.backgroundColor        = UIColor.whiteColor;
    [circleButton setTitle:[NSString stringWithFormat:@"%i", i] forState:UIControlStateNormal];

    [self addSubview:circleButton];
    // animation 1
    [UIView animateWithDuration:0.5 animations:^{
        circleButton.transform          = CGAffineTransformMakeScale(1.0, 1.0);
        circleButton.center             = screenCentre;
    }
                     completion:^(BOOL finished){}];
    // animation 2
    [UIView animateWithDuration:1.0f animations:^{
        circleButton.transform          = CGAffineTransformIdentity;
        circleButton.center             = target;
    }
                     completion:^(BOOL finished){}];
}

and here is the CustomView

CustomView.m

#import <UIKit/UIKit.h>
#import "CustomView.h"


@implementation CustomView : UIView

- (id)initWithFrame:(CGRect)frame {
    self                                = [super initWithFrame:[UIScreen mainScreen].bounds];
    if (self) {

    self.translatesAutoresizingMaskIntoConstraints = true;
    self.backgroundColor                = [UIColor lightGrayColor];

    buttonCount                         = 5;    //16;
    buttonSize                          = 80;   //41;
    radius                              = 68;   //105;

    [self circleOfButtons];
    }
return self;
}

CustomView.h

#import <UIKit/UIKit.h>

@interface CustomView : UIView {
    CGPoint screenCentre, buttonCentre;
    float   radius, radians, buttonSize;
    int     buttonCount;
}

ViewController.m

#import "ViewController.h"

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    CGRect rect             = [UIScreen mainScreen].bounds;
    float  statusBarHeight  = [[UIApplication sharedApplication] statusBarFrame].size.height;
    CGRect screenFrame      = CGRectMake(0, statusBarHeight, rect.size.width, rect.size.height - statusBarHeight);
    self.view               = [[UIView alloc] initWithFrame: screenFrame];

    CustomView *cv          = [[CustomView alloc]initWithFrame:screenFrame];
    [self.view addSubview:cv];
}
Community
  • 1
  • 1
Greg
  • 1,750
  • 2
  • 29
  • 56
  • Your question isn't clear. What functionality are you asking about? Remember, a category is never used to change the behavior of a class. Only use a category to add something new. – rmaddy Mar 29 '17 at 05:00
  • rmaddy, currently, `circleOfButtons` works as a method within `CustomView` and I want to isolate it into a separate class that I can access from any of several `UIViews` so I don't duplicate the code for `circleOfButtons` in every `UIView` – Greg Mar 29 '17 at 05:19
  • Why not have a "CircleOfButtonsView" that is a subview of UIView? Then you get all the benefits of it being a view and a proper class. – rmaddy Mar 29 '17 at 05:24
  • rmaddy, sounds promising. if I understand you correctly, I’d be able to add it a UIView more than once or add it to a UIView along with a different subview ? – Greg Mar 29 '17 at 07:04

0 Answers0