Assign value to a objective-c variable from swift - ios

What I want to do is when user select a district from UITableView in Swift, I'm taking the district name and add .png to it and send the image name variable into Objective-C file and inside it I'm creating UIImageView.
This is my code inside my Objective-C .h file,
#property (weak, nonatomic) NSString *mapImage;
This is how I assign value to it from Swift UITableView when user click on UITableView (didSelectItemAtIndexPath),
selectesState = namesArray[indexPath.row]
let temp :String = selectesState + ".png"
let instanceOfCustomObject: StateMapPinView = StateMapPinView()
instanceOfCustomObject.mapImage = temp
This is the Objective-C code I'm setting the image in .m file (ViewDidLoad),
UIImage *image = [UIImage imageNamed:_mapImage];
_myView = [[VIPhotoView alloc] initWithFrame:self.view.bounds andImage:image];
_myView.autoresizingMask = (1 << 6) -1;
[self.view addSubview:_myView];
But it keeps returning null value.
Whats wrong with my code?

You have to change the declaration of the property to:
#property (copy, nonatomic) NSString *mapImage;
This will make sure that value is copied when assigned. In your case you use weak and therefore the value is deallocated at the end of the execution of the current scope.

Makesure , you have the same 'instanceOfCustomObject' instance.
If it is instantiated again, then you will get null for 'mapImage'.
Use the same instance of 'instanceOfCustomObject' and try in your Obj-c.
CustomObjectClass *instanceOfCustomObject = (CustomObjectClass *) 'same_instanceOfCustomObject';
[UIImage imageNamed: instanceOfCustomObject.mapImage];

Related

Can I use an IBOutlet property throughout my code?

I need to connect an IBOutlet from this UIImageView to my ViewController in order to perform animations on it (just swiping a stone-like block around a grid).
However, I already have a category file that has an (+instancetype) method to create the UIImage programmatically, so I can use it to set an instance variable (usable throughout other files). Problem is (and bear with me because I am new to performing animation methods on movable objects) I can't use that instance variable (which is a UIView*) to do any animations. Actually, let me know if there is a way (to be used with the +(void)animateWithDuration.... method) because it would be beneficial.
+ (instancetype)stoneOneCreator {
UIImage* stoneOneImage = [UIImage imageNamed:#"Stone.png"];
UIImageView* stoneOneView = [[UIImageView alloc] initWithImage:
stoneOneImage];
return stoneOneView;
}
I call this method in my ViewController, set it to an IV, then use that IV throughout the other files where needed.
#implementation
{
UIView* _one;
}
_one = [UIView stoneOneCreator];
Then use _one by passing into other methods that are implemented in other files etc. etc.
My outlet property though when I'm working with the storyboard is
#property (weak, nonatomic) IBOutlet UIImageView* stoneOne;
Is there a way to use the 'stoneOne' property for IV purposes similar to '_one'? Or, is there a way to tie together the '_one' IV with the 'stoneOne' property?
Thanks,
Anthony

Assigning image from another class

For some reason the image is not showing with this code:
YellowClass.h
#property (strong, nonatomic) IBOutlet UIImageView *myImage;
BlueClass.m
YellowClass *yellowClass = [[YellowClass alloc] init];
yellowClass.myImage.image = [UIImage imageNamed:#"Img.png"];
Two things. The instance of YellowClass that you create with alloc init is probably not the one you have on screen (though I can't be sure with that small snippet of code). Secondly, the view of yellowClass has not yet been loaded at the time you access its IBOutlet (myImage), so that outlet will be nil.

How do i save strings to an array and display the strings in an label?

I'm a rookie at iOS and Objective-C programming, trying (HARD) to learn it, so i've enrolled in a basic course. I'm trying to implement two IBAcions in my ViewController.m file but i seem to have problems regarding my way of thinking about this problem and the difficulties understanding the scope, e.g what i can and cannot call and such.
One of this IBActions will throw a dice, getting the right images, and another that will save the outcome and display the latest 10 throws.
Please do not get discouraged by what seems to be a lot of code.
These are the following properties i've declared in the #interface(.h file)
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet UIImageView *dieOne;
#property (weak, nonatomic) IBOutlet UIImageView *dieTwo;
#property (weak, nonatomic) IBOutlet UILabel *latestTenThrows;
#property (nonatomic) NSUInteger dieValue1;
#property (nonatomic) NSUInteger dieValue2;
#property (nonatomic) NSUInteger totalValue;
#property (nonatomic) NSMutableArray *rolledDiceArray;
#property (nonatomic) NSMutableString *rolledDiceString;
#end
And this is my implementation
- (IBAction)throwDice {
NSMutableArray *dieArray = [[NSMutableArray alloc] initWithObjects:
#"one", #"two", #"three", #"four", #"five", #"six", nil];
NSUInteger dieIndex1 = arc4random_uniform(6);
NSUInteger dieIndex2 = arc4random_uniform(6);
UIImage *image1 = [UIImage imageNamed:[dieArray objectAtIndex:dieIndex1]];
UIImage *image2 = [UIImage imageNamed:[dieArray objectAtIndex:dieIndex2]];
self.dieOne.image = image1;
self.dieTwo.image = image2;
So far so good, the right images are showing but here is where it gets tricky for me. I am trying to "save" the rolled dices value and show them in a lable like this: 5 + 2 = 7 in the view, and it should diplay the latest 10 throws.
self.dieValue1 = (dieIndex1+1);
self.dieValue2 = (dieIndex2+1);
self.totalValue = self.dieValue1 + self.dieValue2;
NSMutableString *rolledDiceString = [[NSMutableString alloc] init];
[rolledDiceString appendString:[NSString stringWithFormat:
#"%d + %d = %d",
self.dieValue1,self.dieValue2,self.totalValue]];
How will i get permission to this array in my other functicion, - (IBAction)saveThrow{} below?
NSMutableArray *rolledDiceArray = [[NSMutableArray alloc]init];
[rolledDiceArray addObject:rolledDiceString];
If i add this NSLog call i will only get 1, no matter how many times i hit "Roll dice" in the interface", which means that when i hit "Roll dice" in the interface it's not putting the values, created into a string, in the array correctly.
How do i add the strings correctly to my array so that i later can retrieve that information from another IBAction? And do i have permission to this array in my function below?
NSLog(#"%d",rolledDiceArray.count);
} // End for -(IBAction)throwDice{
In my second and last IBAction, i'm trying to add the strings to the label, but having issues here since my array doesn't getting the strings.
- (IBAction)saveThrow {
NSMutableArray *savedThrowsArray = [[NSMutableArray alloc] init];
[savedThrowsArray addObject:self.rolledDiceArray];
self.latestTenThrows.text = [// Latest 10 items (strings) in savedThrowsArray];
}
Don't flail; think what you are doing. Your words (in your code) have meaning. The computer can only do what you tell it to do...! So, let's look:
NSMutableArray *rolledDiceArray = [[NSMutableArray alloc]init];
[rolledDiceArray addObject:rolledDiceString];
Every time you run that code, you are creating a completely new empty mutable array (that is what = [[NSMutableArray alloc] init] means in the first line). Therefore no matter how many times you run it, the resulting array will contain only one object (the object you add in the second line with addObject).
NSMutableArray *savedThrowsArray = [[NSMutableArray alloc] init];
[savedThrowsArray addObject:self.rolledDiceArray];
Same deal.
And meanwhile, you've got these completely different instance variable sitting unused:
#property (nonatomic) NSMutableArray *rolledDiceArray;
#property (nonatomic) NSMutableString *rolledDiceString;
But none of your code ever talks to / about them. They are just sitting there going to waste. You need to initialize them and put your data in them - not in these local automatic variables that you keep creating and throwing away.
I think the error is here:
NSMutableString *rolledDiceString = [[NSMutableString alloc] init];
this creates a variable local to the method which overrides the class property. So when it goes out of scope (i.e. the method returns) it is deallocated.
Simply replace with
self.rolledDiceString = [[NSMutableString alloc] init];
and the same happens for the array - you should allocate it once (in init or viewDidLoad) and just use
[self.rolledDiceArray addObject:self.rolledDiceString];

XCode - Referring to a UIImageView variable through another string variable?

Is it possible to use a string variable to refer to a UIImageView variable and change the image? The string variable is created by adding an "s" to the start of the tag of the button pressed. This is also the name of a specific UIImageView.
So one of the UIImageView declared in the .h file looks like this:
#property (retain, nonatomic) IBOutlet UIImageView *s11;
And in the .m file so far:
NSString *lastpressnum = [#(sender.tag) stringValue];
NSString *lastpressed = [NSString stringWithFormat:#"%s%#", "s", lastpressnum];
[lastpressed setImage:image];
KVC is the tool you need.
UIImageView * theImageView = [self valueForKey:lastpressed];
[theImageView setImage:image];

Passing string value to viewcontroller but getting EXC_BAD_ACCESS

I am trying to print (nslog) the name of a photo embedded in PhotoView object that I created. I have created 2 viewcontrollers class and the PhotoView class extending the UIButton class to populate a grid in one of the former viewcontrollers.
In PhotoView.h I have
#interface PhotoView : UIButton
#property (assign, nonatomic) NSString *photoName;
...
in PhotoView.m I have
self.tag = [[data objectForKey:#"PhotoID"] intValue];
self.photoName = [data objectForKey:#"PhotoName"];
After printing out the value of tag and photoName on the same file, everything looks good.
Problem start when I try to print the value of photoName from another class after clicking on the PhotoView
-(void)didSelectPhoto:(PhotoView*)sender
{
NSLog(#"%#", [NSString stringWithFormat:#"%#", sender.photoName]);
}
After clicking on the photoView, I get EXC_BAD_ACCESS error.
However, If I do
NSLog(#"%#",[NSNumber numberWithInt:sender.tag]])
I don't get this error.
What could possibly be wrong?
Thanks in advance.
Two remarks:
[NSString stringWithFormat:#"%#", sender.photoName] - No please! No! Don't do that! It's not only superfluous and wastes CPU cycles, but it also heavily decreases readability. if you have a string, you don't have to duplicate it like this, just use the string object directly:
NSLog(#"%#", sender.photoName);
The actual error you have is this:
#property (assign, nonatomic) NSString *photoName;
I. e. you have an assign property, so it doesn't retain its value. When your string object goes out of scope, it's deallocated (and since it's not weak, it isn't automatically set to nil, but it holds whatever garbage value that invalid pointer is, hence the crash). Write instead
#property (retain, nonatomic) NSString *photoName;
if you're not using ARC, and
#property (strong, nonatomic) NSString *photoName;
if you are.

Resources