Tori
Tori

Reputation: 1356

Objective C how to refer to a view in a class method

My app has multiple views to add buttons programmatically and instead of having the following instance method in each controller, I would like to put the method in a common class as use it as a class method.

+ (void) addLeftImageButton:(UIButton *)leftButton:(float)x:(float)y:(NSString *)name:(int) tag
{
     leftButton = [UIButton buttonWithType:UIButtonTypeCustom];
     [leftButton addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
     [leftButton setTag: tag];
     [leftButton setBackgroundImage:[UIImage imageNamed:name] forState:UIControlStateNormal];
     leftButton.frame = CGRectMake(x, y, 345.0, 345.0);
     [self.view addSubview:leftButton];
}

The question I have is how to refer self.view to the calling view. as self.view is not known in the common class.

Upvotes: 0

Views: 597

Answers (4)

User00
User00

Reputation: 9

There are several ways to implement this . But a common class is not good one.

The best way is that you put this function as a category of UIViewController. This is instant method (-)but not class method(+) You don't need to change others.

#import <UIKit/UIKit.h>
@interface UIViewControl (labels)
-(void) add left...
@end
@implementation UIViewControl (labels)
-(void) add left...{}
@end

Put above code in a file "labelcontrol.h" and "label control.m"

Then in your any viewcontroller.m Add: import "labelcontrol.h" to make it work

Upvotes: 0

Erik B
Erik B

Reputation: 42574

If this is a common method for all your controllers you should add it as an instance method in a base controller that all your other controllers inherit from.

Also, there are a few of weird things about that method:

  1. Why do you pass leftButton as a parameter when the first thing you do is overwriting its value?

  2. Your method declaration is really weird. Did you read the warnings? I think you want it to look more like this:

    - (void)leftButtonWithImageName:(NSString *)name
                                  x:(CGFloat)x
                                  y:(CGFloat)y
                                tag:(int)tag
    {
         UIButton *leftButton = [UIButton buttonWithType:UIButtonTypeCustom];
         [leftButton addTarget:self
                        action:@selector(buttonPressed:)
              forControlEvents:UIControlEventTouchUpInside];
         [leftButton setTag:tag];
         [leftButton setBackgroundImage:[UIImage imageNamed:name]
                               forState:UIControlStateNormal];
         leftButton.frame = CGRectMake(x, y, 345.0, 345.0);
         [self.view addSubview:leftButton];
    }
    

Upvotes: 0

MaxGabriel
MaxGabriel

Reputation: 7707

My personal recommendation is to leave the step of adding the subview to the controller itself, making this the class method:

+ (UIButton *) leftButtonWithImageName:(NSString *)imageName x:(CGFloat)x y:(CGFloat)y tag:(int)tag
{
     UIButton *leftButton = [UIButton buttonWithType:UIButtonTypeCustom];
     [leftButton setTag: tag];
     [leftButton setBackgroundImage:[UIImage imageNamed:name] forState:UIControlStateNormal];
     leftButton.frame = CGRectMake(x, y, 345.0, 345.0);
     return leftButton;
}

In a view controller:

UIButton *leftButton = [MyClass leftButtonWithImageName:@"image.png" x:0 y:0 tag:10];

[leftButton addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:leftButton];

A few reasons behind this:

  • If you're using this for multiple view controllers, your class method doesn't have to assume that they all implement the same buttonPressed: method, which isn't a safe assumption.
  • To someone just looking at your view controller code, it will look like nothing calls the buttonPressed:.
  • Callers of the leftButton... method will have more control over the button. For example, they might want to add the button as a property in viewDidLoad so its properties (like its frame) can be queried, but not actually add it to the screen until after an animation completes.

You might also consider making all the view controllers a subclass of a superclass, but that's a very implementation specific decision.

Upvotes: 0

Tim
Tim

Reputation: 9042

You can't, a class method has no concept of self. You need to pass the view as a parameter.

+ (void)addLeftImageButton:(UIButton *)leftButton:(float)x:(float)y:(NSString *)name:(int) tag forView:(UIView *)view;

Upvotes: 6

Related Questions