This is a trick I use a lot in android:
I take an image with Image Picker: camera or gallery
I put the image in an ImageView
I also put the image url in the ImageView, in the tag field
so later when I need the url of an image (to send to server), I grab it from the imageView's tag.
But tag in iOS is a bit different from android: in iOS it's just a number. So is there such a way of piggybacking on an UIButton on iOS: basically any field whatsoever that is available for storing a text and which the user cannot see?
I'm not aware of an analogous field on a UIImageView. Your best bet may be to subclass UIImageView to add such a property. In the .h file for the new class, do something like:
#interface SubclassedUIImageView : UIImageView
#property (strong, nonatomic, copy) NSString *url;
#end
Then assign the url value to SubclassedUIImageView in imagePickerController: didFinishPickingMediaWithInfo:. Assuming you're using Interface Builder, to use the subclassed UIImageView, you drop a UIImageView control onto the parent view, go to the Identity inspector, and change the Custom Class field to the name of your subclassed UIImageView.
Natively, there's no way to do this. However, you can use a category and store the text in an associated object:
#interface UIImageView (StringTagAdditions)
#property (nonatomic, copy) NSString *stringTag;
#end
#implementation UIImageView (StringTagAdditions)
static NSString *kStringTagKey = #"StringTagKey";
- (NSString *)stringTag {
return objc_getAssociatedObject(self, kStringTagKey);
}
- (void)setStringTag:(NSString *)stringTag {
objc_setAssociatedObject(self, kStringTagKey, stringTag, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
#end
More info # http://nshipster.com/associated-objects/
This type of thing has been asked before, but you could pull this off with a UIButton category that adds getter/setter like methods that store this value for you:
setting new properties in category interface/implementation
Objective-C: Property / instance variable in category
http://iosdevelopertips.com/objective-c/adding-properties-category-using-associated-objects.html
Or you could subclass UIButton and add the property you need. There are lots of options, but I'm unclear on what you mean by "the user cannot see"?
Related
I have a view controller with different buttons with background images assigned. My header file looks as follows:
#interface ImageSelect : UIViewController
- (IBAction)ImageButton:(id)sender;
- (IBAction)Done:(id)sender;
#property(nonatomic, readonly, retain) UIImage *currentImage;
#end
And the section of my main file that contains the button method looks like:
- (IBAction)ImageButton:(id)sender {
if ([#"railway-336702_1280.jpg" isEqual:self.currentImage]) {
img = #"railway-336702_1280.jpg";
NSLog(#"Test");
}
}
I am wanting to save the image name to a NSString called img. Currently, the code runs but doesn't actually perform the save to img.
A simpler way would be: if you simply wanted to check whether the UIButton contains that image that you set, you could simply use the tag property:
Let say you set its image with an image named: railway-336702_1280.jpg
Set the tag with something simpler like "1280".
Then check this tag against an Integer. And should you change the image again, change the tag correspondingly.
if (((UIButton*)sender).tag == 1280)
{
// Do stuff
}
Once a UIImage is created it loses all connection to the file it was loaded from. You cannot determine at runtime what the background image is.
If you need to get the name at runtime, subclass UIButton and then create a property called imageName and set it using the User Defined Runtime Attributes through Interface Builder.
Example:
In ImageSelectButton.m:
#interface ImageSelectButton ()
#property(nonatomic, retain) NSString *imageName;
#end
In ImageSelect.m:
#interface ImageSelect
...
- (IBAction)ImageButton:(ImageSelectButton*)sender {
if ([sender.imageName isEqualToString:#"railway-336702_1280.jpg"]) {
// Do stuff
}
}
...
In Interface Builder when selecting your UIButton set the Custom Class and runtime attribute:
I am just start studying iOS developing watching Stanford iOS course, but it looks like I have already missing something.
I have a form with UILabel and UIButton. When an user press the button the title of the button must be added to the text of label.
Here is my current CalculatorViewController.h:
#import <UIKit/UIKit.h>
#interface CalculatorViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *display;
#end
and here is a CalculatorViewController.m:
#import "CalculatorViewController.h"
#implementation CalculatorViewController
#synthesize display = _display;
- (IBAction)digitPressed:(UIButton *)sender {
NSString *digit = [sender currentTitle];
UILabel *myDisplay = self.display;
myDisplay.text = [myDisplay.text stringByAppendingString:digit];
}
#end
The problem is that self.display (and myDisplay) variables have a nil value. Looks like I need to do something to link my variable with control on the form. What ?
Thanks in advance.
You need to link the control, the UILabel in Interface Builder to the variable in your CalculatorViewController class.
It is very likely that the file's owner (talking about the Xib file) is your CalculatorViewController, so you need to Control+drag the file's owner (or the object representing your VC) to the control and you will be shown a menu with the possible IBOutlet variables declared in your class, so you select the one you want to represent the control.
You can check if this link is properly set in two ways: (1) Select the UILabel in Interface Builder and see if there's a connection to the variable in the Connections Inspector, or (2) In your code you'll see a bullet near the IBOutlet declaration, if the bullet is hollow the connections is not set, if the bullet is filled the connection is set.
There is no need of this line
UILabel *myDisplay = self.display;
You have already declared your label in your interface file
- (IBAction)digitPressed:(UIButton *)sender
{
NSMutableString *string = [myDisplay.text stringByAppendingString:sender.titleLabel.text];
myDisplay.text = string;
}
Within my iPhone app I have 2 UIControls a ViewController.h and a selectionScreen.h.
The selectionScreen is set as so
#interface selectionScreen : ViewController{
I am trying to change a label that is placed in the main ViewController, from the selectionScreen
So far I have this within the SelectionScreen.m (personTotal1.text is the label in the other UIcontrol)
- (IBAction)Change:(id)sender{
int x=123;
NSString *y =[NSString stringWithFormat:#"%i",x];
personTotal1.text=y;
NSLog(#"%#",personTotal1.text);
}
When I NSLog to check if the value has changed it returns null, how can I make it so interactions(such as a button press) within the Selectionscreen change label text in another screen.
In your View controller:
Did you set your personTotal1 ivar as a property? Just setting the ivar is not enough:
UILabel *personTotal1;
You need to set the property and synthesize the getters and setters like so:
#property(nonatomic, retain) UILabel *personTotal1;
If you are using ARC then it would be like so:
#property(nonatomic, strong) UILabel *personTotal1;
Then be sure to synthesize the label. Now import the ViewController.h into the SelectionScreen file. From there you can access the UILabel properties. Hope this helps, if not let me know and I can clarify.
I want to be able to have a TextField in my static cells so I'm using the StringInputTableViewCell class from this demo: https://github.com/wannabegeek/PickerTableViewCell/tree/master/PickerCellDemo
I'm using storyboards and in my storyboard I got 2 cells that use the StringInputTableViewCell class. As you can see there is a UITextField property
#property (nonatomic, strong) UITextField *textField;
in StringInputTableViewCell.h. On storyboards in MyViewController I can connect the label, etc with a property but I cannot connect the TextField since its added in code and the TextField isn't on my storyboard. So my question is how do I get that property in MyViewController class?
You can make your "StringInputTableViewCell" a property within your "MyViewController", or if you're trying to populate it during "cellForRowAtIndexPath", you can get get access to it through an identifier or a tag.
Once you have a pointer to the "StringInputTableViewCell" object that's being displayed in your table, you can then access the "textField" property of it in your code directly.
Something like:
StringInputTableViewCell * stringInputCell = (StringInputTableViewCell *) cell;
if(stringInputCell)
{
stringInputCell.textField.text = #"Surprise, I can put text in here!";
}
I have 10 UIImageViews which do the same thing (they have some void methods that change their image with a timer).
My UIImageView is an outlet and I want to connect all the 10 imageViews to the same outlet, but interface builder doesn't allow me.
I found that there is a solution, IBOutletCollection. Can anyone explain to me how to use this to connect multiple imageViews to the same outlet?
Declare a property to hold your imageView's and then hook them up in interface builder like normal
#property (nonatomic, strong) IBOutletCollection(UIImageView) NSArray *imageViews;
it's just a normal NSArray but when the nib is loaded it will be populated with your imageView's
Update
In the header file for you view controller which has the multiple imageView's on you need to add the property above - it may look something like this:
#interface MyViewController : UIViewController
#property (nonatomic, strong) IBOutletCollection(UIImageView) NSArray *imageViews;
// other properties
#end
Now in the interface builder you connect all the imageView's to this one property.
Now I just work with the imageViews collection
for (UIImageView *imageView in self.imageViews) {
imageView.image = someImage;
}