Hy again, I am still new to objective c and Xcode. I am building a small app and need to use a variable in a Method. I don't know where to put it so I can use it in the Method.
I have a button which starts the whole process but the Method of this button needs a variable which only should be created once (because its a random number) and be saved so the "Button Method" can use it to compare it. Where do I place it so my variable stays the same while my Method can use it?
Thx
- (IBAction)guessButton:(id)sender {
NSLog(#"Answer = %i", answer);
NSLog(#"Button Pressed");
float guess = [[self.guessTextField text] floatValue];
NSLog(#"Guess = %f", guess);
}
Create in .h file like this....
#import <UIKit/UIKit.h>
#interface GoogleMapsViewController : UIViewController
#property int answer;//If it's int. Here mention your variable type(If it string #Property NSString * answer;)
#end
And call with self.answer
- (IBAction)guessButton:(id)sender {
NSLog(#"Answer = %i", self.answer);
NSLog(#"Button Pressed");
float guess = [[self.guessTextField text] floatValue];
NSLog(#"Guess = %f", guess);
}
It is recommended to store private variables in implementation class. We can define variable in .m file like this
#interface ViewController (){
NSString *stringTodefineAge;
}
#property (readonly, strong, nonatomic) ModelController *modelController;
#end
#implementation RootViewController
....
Related
My problem may be so simple but I'm so lost in it.
Any comment, idea, help, prediction would be so useful.
Here are my classes
TrialSwiftClass.swift
import Foundation
#objc public class TrialSwiftClass : NSObject{
var first : String?
var second : NSString?
var third : NSNumber = 0
override init(){
super.init()
}
init(data:NSArray){
self.first = data[0] as? String
self.second = data[1] as? NSString
self.third = data[2] as! NSNumber
}
}
TrialObjectiveCClass.h
#import <Foundation/Foundation.h>
#interface TrialObjectiveCClass : NSObject
#property (nonatomic, strong) NSString *first;
#property (nonatomic, strong) NSString *second;
#property (nonatomic, assign) NSNumber *third;
- (instancetype)initWithArray:(NSArray *)data;
#end
TrialObjectiveCClass.m
#import "TrialObjectiveCClass.h"
#implementation TrialObjectiveCClass
- (instancetype)initWithArray:(NSArray *)data{
self.first = data[0];
self.second = data[1];
self.third = data[2];
return self;
}
#end
Now here comes the problem.When I use these two classes in my ViewController.m which has following code in it:
#import "ViewController.h"
#import "TrialObjectiveCClass.h"
#import "Codemaster-Swift.h" //Automatically created header to use Swift code in Objective-C
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *trialArray = #[#"FirstString", #"SecondString", #99];
//First the Swift part
TrialSwiftClass *obj = [[TrialSwiftClass alloc] initWithData:trialArray];
NSLog(#"%#", obj.first);
NSLog(#"%#", obj.second);
NSLog(#"%#", obj.third);
//Now the Objective-C part
TrialObjectiveCClass *obj2 = [[TrialObjectiveCClass alloc] initWithArray:trialArray];
NSLog(#"%#", obj2.first);
NSLog(#"%#", obj2.second);
NSLog(#"%#", obj2.third);
}
If I put a breakpoint in the last NSLog in ViewController.m, here is what i see in debug area:
My logs are showing the right value of my object's properties.
Why can't i see the hierarchy of my Swift class but can see my Objective-C class? How to solve this problem?
The variables in your Swift class get exposed to ObjC as properties. At present the Locals view does not show the properties of an object, only its ivars. This is true regardless of whether the class comes from ObjC or Swift. That's why the swift variables don't show up in the locals view.
You can work around this by using the expression command in the lldb console to view the object's properties. For instance, stopped in your example, you can do:
(lldb) expr obj.first
(__NSCFConstantString *) $0 = 0x00000001002d1498 #"FirstString"
etc.
You can't see the hierarchy of your Swift class in that point. When you bridge your swift class to an obj-c file something happening and the debugger can't see anymore your properties. This is a bug or something else, I can't figure out yet. But if you would like to see your hierarchy you can see that in your Swift file.
Another solution if you create a swift project and initialize there the objective-c classes. So if you can create on the opposite way, the properties and hierarchy will appear in the debug field.
This is not an explanation for that, why your solution not working but I hope this will help you a little bit.
I have looked through the other topics on this matter and I have not been able to determine my error.
I am very new to IOS programming. I am trying to create a program that looks at the selected state of 2 buttons and determines whether the buttons selected state are the same.
I am currently trying to use a model to determine the buttons selected state and then pass the state to a label. I have an error which says:
No visible #interface for 'MatchTest' declares the selector 'doesItMatch'
I'd appreciate any help that may be offered.
Thanks!
this is the MatchTest.h file
// MatchTest.h
#import <Foundation/Foundation.h>
#interface MatchTest : NSObject
#end
this is the MatchTest.m file
// MatchTest.m
#import "MatchTest.h"
#implementation MatchTest
-(NSString*)doesItMatch:(UIButton *)sender
{
NSString* tempString;
if(sender.isSelected)
{
tempString = #"selected";
}
else
{
tempString = #"not selected";
}
return tempString;
}
#end
this is the MatchViewController.h file
// MatchViewController.h
#import <UIKit/UIKit.h>
#import "MatchTest.h"
#interface MatchViewController : UIViewController
#end
this is the MatchViewController.m file
// MatchViewController.m
#import "MatchViewController.h"
#interface MatchViewController ()
#property (weak, nonatomic) IBOutlet UILabel *matchLabel;
#property (strong, nonatomic) MatchTest *match;
#end
#implementation MatchViewController
-(MatchTest *)match
{
if(!_match) _match = [[MatchTest alloc] init];
return _match;
}
- (IBAction)button:(UIButton *)sender
{
sender.selected = !sender.isSelected;
self.matchLabel.text = [self.match doesItMatch:sender];
}
#end
declare doesItMatch method in MatchTest.h file
like
in MatchTest.h
-(NSString*)doesItMatch:(UIButton *)sender;
compiler is not able to file doesItMatch method's declaration in .h file that's why that error is there.
You have not defined your method -(NSString*)doesItMatch:(UIButton *)sender in MatchTest.h file.
You are importing MatchTest.h file in MatchViewController.h file so you need to define your methods or variables or property to make available this method.
Therefore according to your error log viewController wasn't able to find the interface where this method is declared.
I'm having trouble making a shopping cart sort-of concept in my app. I have my AppDelegate (named ST2AppDelegate) that contains an NSMutableArray called myCart. I want RecipeViewController.m to pass an NSString object to myCart, but every time I pass it the NSString and use NSLog to reveal the contents of the array, it is always empty.
Can anyone please tell me what I am doing wrong? I have worked on this code for days, and there is a line of code in which I don't understand at all what's going on (in the RecipeViewController.m, labeled as such).
Any help would be so appreciated... I'm just a beginner. Here are the relevant classes:
ST2AppDelegate.h:
#import <UIKit/UIKit.h>
#interface ST2AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) NSMutableArray* myCart;
- (void)addToCart:(NSString*)item;
- (void)readCartContents;
#end
ST2AppDelegate.m:
#import "ST2AppDelegate.h"
#implementation ST2AppDelegate
#synthesize myCart;
// all the 'applicationDid...' methods...
- (void)addToCart:(NSString *)item
{
[self.myCart addObject:item];
}
- (void)readCartContents
{
NSLog(#"Contents of cart: ");
int count = [myCart count];
for (int i = 0; i < count; i++)
{
NSLog(#"%#", myCart[count]);
}
}
#end
RecipeDetailViewController.h:
#import <UIKit/UIKit.h>
#import "ST2AppDelegate.h"
#interface RecipeDetailViewController : UIViewController
#property (nonatomic, strong) IBOutlet UILabel* recipeLabel;
#property (nonatomic, strong) NSString* recipeName;
#property (nonatomic, strong) IBOutlet UIButton* orderNowButton;
- (IBAction)orderNowButtonPress:(id)sender;
#end
RecipeDetailViewController.m:
#import "RecipeDetailViewController.h"
#implementation RecipeDetailViewController
#synthesize recipeName;
#synthesize orderNowButton;
// irrelevant methods...
- (IBAction)orderNowButtonPress:(id)sender
{
// alter selected state
[orderNowButton setSelected:YES];
NSString* addedToCartString = [NSString stringWithFormat:#"%# added to cart!",recipeName];
[orderNowButton setTitle:addedToCartString forState:UIControlStateSelected];
// show an alert
NSString* addedToCartAlertMessage = [NSString stringWithFormat:#"%# has been added to your cart.", recipeName];
UIAlertView* addedToCartAlert = [[UIAlertView alloc] initWithTitle:#"Cart Updated" message:addedToCartAlertMessage delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[addedToCartAlert show];
// add to cart (I don't understand this, but it works)
[((ST2AppDelegate*)[UIApplication sharedApplication].delegate) addToCart:recipeName];
// read cart contents
[((ST2AppDelegate*)[UIApplication sharedApplication].delegate) readCartContents];
}
#end
You need to initialize myCart when your application launches:
self.myCart = [[NSMutableArray alloc] init];
otherwise you are just attempting to add objects to a nil object which while it won't throw an exception because of the way objective-c handles nil objects it will not function as expected until you initialize it.
Do you ever initalize the shopping cart variable?
Try doing lazy instantiation.
-(NSMutableArray *) myCart{
if (!_myCart){
_myCart = [[NSMutableArray alloc] init];
}
return _myCart;
}
This way you will know it will always get allocated. Basically, this method makes it so that whenever someone calls your classes version of the object it checks to see if that object has been allocated and then allocates it if it has not. It's a common paradigm that you should employ with most of your objects.
This method should go in the app delegate (where the object was declared).
I have faced a problem I can not see the problem to. I am trying to pass a simple NSString to a child variable but it continues to return as null even when I use NSLog to show there is a string in the variable.
The variable finalDate will not pass to the child view.
Parent View
ChangeTimeViewController *ChangeTimeView = [[ChangeTimeViewController alloc] init];
NSLog(#"%#", date);
ChangeTimeView.finalDate = date;
[ChangeTimeView setDelegate:self];
[self.navigationController pushViewController:ChangeTimeView animated:YES];
Child View .H
#import <UIKit/UIKit.h>
#protocol ChangeTimeViewControllerDelegate;
#interface ChangeTimeViewController : UIViewController <UIPickerViewDelegate, UIPickerViewDataSource>
#property (nonatomic, weak) id <ChangeTimeViewControllerDelegate> delegate;
#property (nonatomic) NSString *enteredTime;
#property (nonatomic, strong) UIPickerView *UIPicker;
#property (nonatomic, strong) NSString *finalDate;
#end
#protocol ChangeTimeViewControllerDelegate <NSObject>
- (void)childTimeViewController:(ChangeTimeViewController *)viewController didChooseValue:(NSString *)string;
#end
Child View .M
NSLog(#"%#", self->finalDate);
What you are doing is perfectly fine. You should insert the NSLog in the view(Did/Will)Appear or some similar method and you may use the self.finalDate notation to make sure you don't try to read some uninitialized ivar.
Note: properties synthesize ivars with _ as prefix (_finalDate is the correct storage unless you synthesized it it with some other name)
If you want to make sure that all input parameters are passed to the view controller, then create an init method for it. Similar to this:
- (id)initWithDate:(NSDate*)date delegate:(id)delegate
Pass NSString As ChangeTimeView.finalDate = #"This Is my Simple String"; and use/put NSLog in viewDidLoad method for show is it rich at nextViewController or not ?? Otherwise if your date (NSString) is proper then Your code is correct.
Check what is happening if you set like,
ChangeTimeView.finalDate = #"MyString";
and in view.m log NSLog(#"%#", self.finalDate);
I created a method to calculate a simple calculation.
I want the method to return an int and take 2 int parameters.
I created a class called calculation. I imported calculation into the viewController.m and created an action 2 textFields and a text Label. I am using this view for testing the method.
My method return 0 in the calculation. What am I doing wrong? It's so simple but I can't seem to figure out where I'm making my mistake. Here is the code.
Calculation.h
#import <Foundation/Foundation.h>
#interface Calculation : NSObject
#property (nonatomic) int odometerStart;
#property (nonatomic) int odometerEnd;
#property (nonatomic) int odometerTotal;
- (int)mileageStart:(int)start mileageEnd: (int)end;
#end
Calculation.m
#import "Calculation.h"
#implementation Calculation
#synthesize odometerEnd, odometerStart, odometerTotal;
- (int)mileageStart:(int)start mileageEnd:(int)end
{
odometerStart = start;
odometerEnd = end;
odometerTotal = end - start;
return odometerTotal;
}
#end
viewController.h
#import <UIKit/UIKit.h>
#interface MileageViewController : UIViewController
- (IBAction)calculateMileage:(id)sender;
#property (strong, nonatomic) IBOutlet UITextField *startLabel;
#property (strong, nonatomic) IBOutlet UITextField *endLabel;
#property (strong, nonatomic) IBOutlet UILabel *displayLabel;
#end
viewController.m
#import "MileageViewController.h"
#import "Calculation.h"
#implementation MileageViewController
#synthesize startLabel;
#synthesize endLabel;
#synthesize displayLabel;
- (void)viewDidUnload
{
[self setStartLabel:nil];
[self setEndLabel:nil];
[self setDisplayLabel:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (IBAction)calculateMileage:(id)sender {
Calculation *mileage = [[Calculation alloc] init];
int odomStart = [[startLabel text] intValue];
int odomEnd = [[endLabel text ] intValue];
[mileage mileageStart:odomStart mileageEnd:odomEnd];
mileage.odometerTotal = displayLabel.text.intValue;
NSLog(#"THe total is %d", mileage.odometerTotal);
My total keeps equaling 0. The calculation isn't being calculated.
Your statement is backwards. You're trying to set the value of odometerTotal to the value of your label, but you want it the other way around. It should be:
displayLabel.text = [NSString stringWithFormat:#"%d",mileage.odometerTotal];
However, mileage returns an int value, so you don't really need the odometerTotal property in your Calculation class . You could do it like this:
displayLabel.text = [NSString stringWithFormat:#"%d",[mileage mileageStart:odomStart mileageEnd:odomEnd]];
I saw the whole program, and the assignment you did seemed wrong,
the bold pointed was as below:
mileage.odometerTotal = displayLabel.text.intValue;
you want to use the calculate class to calculate the total value. while the order should be opposite.
How about this:
displayLabel.text.iniValue = mileage.odometerTotal;
then use the NSLog method to print your expected result.