How to give an external property to UIButton - objective-c

I am new in iOS development. Now I want to give an external property(similar to tag) to a UIButton. Is it is possible? If it is possible ,how to do this?
If any body know, please help me.

You can use a NSArray, and the index of the array is the UIButton's tag.

You can either create a UIButton subclass, or use Obj-C runtime associations like this
#import <objc/runtime.h>
static char kMyExtendedPropKey;
objc_setAssociatedObject(myButton,
&kMyExtendedPropKey,
yourObjectToAssociate,
OBJC_ASSOCIATION_RETAIN);
Note that associations can be used in conjunction with categories to add new properties to existing classes! But use with caution, subclassing is the preferred way.

Subclass UIButton, assuming you want an NSString in your button:
.h
#interface MyAttributedButton : UIButton {
NSString *myExternalProperty;
}
#property(nonatomic, retain) NSString *myExternalProperty;
#end
.m
#implementation MyAttributedButton
#synthesize myExternalProperty;
#end

Related

Assign to UIImageView a string tag

Is it possible to assign a text tag to any UIObject? If not is there another way I can do it? Can I do for example:
image.tag = [NSString stringWithFormat: #"Hello"];
Thanks for any help!
The tag property is an NSInteger - therefore this is not possible.
You can create a subclass and add an NSString property.
No, the tag is an integer.
Consider subclassing UIImageView class and just adding a NSString property. It is really simple these days.
Example:
#interface TaggedImageView : UIImageView
#property (nonatomic, strong) NSString *tagString;
#end
#implementation TaggedImageView
#end
Then just use TaggedImageView in place of UIImageView.
If you only access the MyImageView from one .m file you can just put these lines just after the #import statements.

.h instance variable declaration

I'm having a hard time understanding why the following textfield is declared twice in some tutorials.
In the .h file:
# include <UIKit/UIKit.h>
#interface MyViewController : UIViewController {
UITextField *name; // <----- What do I need this for? Is it the same as below?
}
#property (nonatomic, strong) IBOutlet UITextField *name; // <----- Same as this?
#end
At first I thought this would be something like an instance variable, but they are only declared here in the .m file, right?
.m file
#import "MyViewController.h"
#implementation UIViewController {
NSString *myString; // <----- This is an instance variable, right?
}
What's the "UITextField *name;" for? Don't I only need the second one with the #property in front? Thank you.
This is an old way, just use property is OK.
If you declare both, you must use #synthesize name; in your .m file to make self.name same as name.
XCode4.2 auto synthesize name = _name. So use self.name as much as possible in your .m file.
Variable in {} just use for internal or private, when you don't want implement setter and getter.
If you are targeting iPhone OS or 64-bit Mac OS X then you do not need to define ivars for your properties. Take a look at Dynamic ivars: solving a fragile base class problem

Accessor method is not called

I'm trying to build a dynamic marquee using the solution provided in this article:
How To Create Dynamic more than one uiview with Marquee Effect in iphone
The problem ins that method accessor. Thats how I implemented in my view controller:
gridViewController.h
#import "CrawlView.h"
CrawlView *marquee;
#property (strong, nonatomic) CrawlView *marquee;
gridViewController.m
#synthesize marquee;
....
[marquee setMessages:self.noticiasArray];
[marquee go];
I put a break point in the accessor method, but it's never called:
- (void)setMessages:(NSMutableArray *)messages {
if (_messages != messages) {
_messages = messages;
[self buildSubviews];
}
}
So the marquee is not shown.
I will appreciate your help on this.
thnaks
You need to set it to #dynamic
#dynamic marquee;
instead of #synthesize marquee; in order to use your custom setter
Try self.marquee to call the accessor method.

is it right way in obj-c programming

i wonder if the way i programm is right way or not. can you help me?
#interface ViewController : UIViewController
{
UILabel *messageLabel;
}
#end
when i declare new object in .h and create in .m i have to use #property (nonatomic, retain) UILabel *messageLabel? i saw few listings where when object are created by code #property doesn't exist and few where does exist and i'm confused.
is it correct when i don't use #property (in example for UILabel, UIImageView, UIButton) when i create objects by code?
#property is a key word useful to create setter/getter methods automatically for that field. If you don't need to access your label from outside your view controller you won't need to use #property and your code is fine.
Your code is correct. #property is used globally throughout your app, rather than being specific to your UIViewController. If you are only planning on referring or changing the label/other component define it within the { } otherwise #property should be used

variable accessing

I have a variable x in one class.And I want to access the updated x value in some other class.
There is so much of confusion.Can I use property?.Please help me.
Thanks in advance
Do you mean that you want to be told when the value changes? Have a look at Key Value Observing
To simply access an iVar in one class from another, a property is exactly what you want.
The syntax is :
in your .h
#interface myclass : NSObject {
UIWindow *window;
}
#property (nonatomic, retain) UIWindow *window;
#end
in your .m
#implementation myclass
#synthesize window;
...
#end
The #synthesize directive instructs the compiler to produce a lot of boilerplate code (as directed by the (nonatomic, retain) specifiers. In this case to handle thread safety and memory management.
Also note that in Objective-C 2.0 the iVar declaration UIWindow *window; is not required.
If you want to be notified in your second class when an iVar is updated, you need to look at key value observing. Unless you are writing a framework or some very dynamic code, that is probably overkill.
Maybe this tutorial will help you out..
If this is not what you mean, please rephrase the question, because i don't understand it..
Edit: Or a shared Instance can be used
you could access it by #import Classname, and then just use the getter that is created with the property. but first initialize the class you have imported..
#import "ClassY.h"
#implementation ClassX
ClassY * classY;
NSString * name;
...
name = [classY name];
...
#end