I am pretty new for cocoa programming.
I am learning binding, trying to make a simple binding code as:
- (void)awakeFromNib
{
self.aValue = [[Model alloc] init];
NSString *aKey = #"value";
NSDictionary *aDic = [[NSDictionary alloc] initWithObjectsAndKeys:self.aValue, aKey, nil];
self.anObjctCtrler = [[NSObjectController alloc] initWithContent:nil];
[self.anObjctCtrler setContent:aDic];
NSLog(#"%ld", [[[[self.anObjctCtrler content] valueForKey:#"value"] number] integerValue]);
}
The anObjectCtrler is an NSObjectController in the Interface Builder, and I "bind" a NSTextField to Object Controller, the class of anObjectCtrler, at a model key path of "value" and controller key of "selection"; the Obeject Controller has referencing outlet to File's Owner as anObeject.
When I run the codes, the NSTextField displays "No Selection", not as expected as the value of "self.aValue". You can see I check the content of the object controller by using an output of "NSLog...", it shows the correct value.
Anyone can help me to solve this, please?
Many Thanks.
Related
I have 2 views, a login view and a main view.
I use SWRevealViewController, and I want automatically display my menu at the startup of the app. I know how display my menu but I don't know how display it just once at startup.
I want to pass a simple String between my Login view and my Main view but without segue, and made a simple test :
if (myPreviousView == "LoginView")
{
// display my menu
}
Another method would be to use NSUserDefault to store your string, which than can be accessed from anywhere within the application.
So, you put your string into NSUserDefaults in your first view:
// Initialize the NSUserDefaults object and an array for data storage
NSUserDefaults *defsData = [NSUserDefaults standardUserDefaults];
NSMutableArray *myArray = [[NSMutableArray alloc] init];
// Add your string to the custom array
NSString *myString = #"My string.";
[myArray addObject:myString];
// Put the array back into UserDefaults for later use
[defsData setObject:myArray forKey:#"Key"]; // Key can be anything
[defsData synchronize];
Now, the array (and the string in it) is available anywhere. So, when you navigate to your second view controller, just initialize an NSUserDefaults and access the string:
NSUserDefaults* defsData = [NSUserDefaults standardUserDefaults];
NSArray *myArray = [defsData objectForKey:#"Key"];
NSLog("This is my stored string: %#", [myArray objectAtIndex:0]);
You can modify the init method of your second view controller to take a custom attribute when you subclass it. So, lets say you created a standard UIViewController (.h and .m files). You can modify the init method of this new class to your liking in the .h file:
- (instancetype)initWithString:(NSString *)string;
And then replace the standard init with the new one in the .m:
- (instancetype)initWithString:(NSString *)string {
}
So, when you call your view controller into existence, you just use this new init method and pass the string you wanted like this:
UIViewController *viewController = [[UIViewController alloc] initWithString:myString];
[self presentViewController:viewController animated:NO completion:nil];
This is a programmatical approach of course, but it should be applied to interface builder easily (unfortunately, as I never use interface builder, I don't know how exactly, but as I said, it should be fairly straightforward to anyone who uses it).
I've been racking my brain over this seemingly simple issue. I have a XYZObject class where I declare:
#property BOOL checked;
In my View Controller, I import the object and whenever I use 'checked', the app compiles fine but breaks at runtime wherever 'checked' is used, for example:
XYZObject *tableitem = [myDictionary[currentCategory] objectAtIndex:indexPath.row];
if (tableitem.checked) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
This was working fine until I deleted and re-added the XYZObject class, so I've been debugging under the assumption that something in the file path is what's screwing things up. But I can click on 'checked' in my VC and under Quick Help it shows the proper reference to XYZObject. This is the exact error:
[__NSCFString checked]: unrecognized selector sent to instance
EDIT/UPDATE:
With some help I've realized the issue is that when I changed my datasource from manual declaration in the ViewController, to importing a Plist, I completely scrapped my XYZObject and didn't account for it. Here is the original way I declared my dictionary:
XYZCategory *category1 = [[XYZCategory alloc]init]; category1.categoryArray = #"First Category"; [categoryArray addObject:category1];
XYZObject *object1 = [[XYZObject alloc]init]; object1.objectName = #"My String"; [objectArray addObject:object1];
myDictionary[category1.categoryArray] = objectArray;
When I switched to the Plist, the code changed to:
NSString *path = [[NSBundle mainBundle] pathForResource:#"myDictionaryPlist" ofType:#"plist"];
NSMutableDictionary *plistDictionary = [[NSMutableDictionary alloc] initWithContentsOfFile:path];
objectArray = plistDictionary[#"First Category"];
myDictionary[category1.categoryArray] = objectArray;
And then for reference, XYZObject makes the following declarations:
#property NSString *objectName;
#property BOOL checked;
So the dictionary problem would be that I'm just pulling the direct strings for the objectArray, instead of a set of XYZObjects. I'm going to keep testing but I'm pretty sure I just have to re-define objectArray to be a set of objects based on what's pulled from the Plist.
But I also think that since I'm using the Plist now to create a dictionary (that is popped into a table where the Keys are sections and Values are rows), I can simplify things by removing the XYZCategory and XYZObject all together. Not sure if that's possible but I'm going to work towards it.
As the error message is suggesting, tableitem is actually a NSString, contrary to what you expect.
You are probably populating the dictionary in the wrong way.
I need some help in QuickDialog. I am using this tutorial QuickDialog but i cannot find what i would like to do in my QuickDialog.
First i have a controller A that will transfer to controller B using QuickDialog, values are in controller A. Now, my problem is how can i access the values when I'm already in controller B.
For example: i have declared QEntryElement *amountEntry = [[QEntryElement alloc] initWithTitle:#"Amount" Value:#""]; in controller A and passed this on controller B, how will i access amountEntry in controller B.
I hope i have explained it well. Please help on this.
You can access all values within the QRootElement. One way to do so is setting the key property of every QElement and afterwards fetch all key-value pairs into a NSMutableDicionary like so:
NSMutableDictionary *results = [[NSMutableDictionary alloc] init];
[fooRootElement fetchValueIntoObject:results];
You can use the onSelected completion code to trigger such action with a QButtonElement
QSection *confirmButtonSection = [[QSection alloc] init];
QButtonElement *confirmButton = [[QButtonElement alloc] initWithTitle:#"Accept"];
[fooRootElement addSection:confirmButtonSection];
[confirmButtonSection addElement:confirmButton];
[confirmButton setOnSelected:(^{[self fetchResultsAndCheckThemAndDismissControllerBMethod];})];
the button will then call the method on controller A which will leave you with a filled dictionary full of sweet information.
I am reading some book and I stumbled this thing.
In my ViewController when a user clicks change date button following
code is called:
- (IBAction)changeDate:(id)sender {
DateViewController *vc = [[DateViewController alloc] init];
[vc setItem: item];
[[self navigationController] pushViewController:vc animated:YES];
}
item is a pointer to a custom class object, which has ivar of type NSDate *;
Now, inside DateViewController when user already picked new date and wants
to navigate to previous view, I have following code:
- (void)viewWillDisappear:(BOOL)animated
{
NSLog(#"%#", [datePicker date]);
item.dateCreated = [datePicker date]; // get selected date
}
This code works and when user goes back from above code change is reflected
in item data structure and user can see new date. However, if I change above code, to following code, it doesn't work anymore, any clues why?
(This does NOT work):
- (IBAction)changeDate:(id)sender {
DateViewController *vc = [[DateViewController alloc] init];
vc.userDate = currentItem.dateCreated;
[[self navigationController] pushViewController:vc animated:YES];
}
DateViewController:
- (void)viewWillDisappear:(BOOL)animated
{
NSLog(#"%#", [datePicker date]);
self.userDate = [datePicker date];
}
In the first case, item is a mutable instance, because you can change the date that it contains. In the second case you are supplying the NSDate itself, which is immutable.
So, in the first case, you pass a reference to item which can be edited and these edits are available later.
But, the second case doesn't edit the original date, it just stores the chosen date into a property on the view controller which is in the middle of being dismissed.
Generally it is better to make the communication clear, so the view controller would pass the chosen date back to the caller by delegation or provide a property (like in your second case) that can be queried once the selection is made. Your first option is effectively hiding the data exchange by sharing the instance item while the second view controller is on display.
Immutable means that the object itself (its contents) can not be changed. It does not prevent any reference to the object from being changed. If we use arrays (where there are mutable an immutable versions) to demonstrate:
NSArray *a = [NSArray array];
NSArray *b = a;
[b editSomething]; // illegal (not a true method name but just an example of something you might want to try)
b = nil; // just nils b, no affect on a at all
And
NSMutableArray *a = [NSArray array];
NSMutableArray *b = a;
[b addObject:#"String"]; // edits a, because a and b are the same object
b = nil; // just nils b, no affect on a at all
The NSArray is like the situation where you just pass the NSDate. The NSMutableArray is like the situation where you pass item (because you can change the contents).
This question already has answers here:
how to instantiate an object of class from string in Objective-C?
(2 answers)
Closed 9 years ago.
All is in my title, i want to create some dynamics names, to allocate some differents UIViews but randomly. For example, i want to make :
Level1 * level1view = [[Level1 alloc] init];
So i try to make some NSString like this :
ClasseMap = [NSString stringWithFormat:#"Level%i", Map];
NomMap = [NSString stringWithFormat:#"level%iview", NumeroMap];
id nouveau = NSClassFromString(ClasseMap);
nouveau * ViewTest;
ViewTest = [self valueForKey:NomMap];
ViewTest = [[nouveau alloc] init];
But it gives me : Use of undeclared identifier 'ViewTest'. How could i fix it please ? How could i get access to some variables (for example, level1view.example = YES;) ?
Thanks for your help ! =)
why dont you rather keep an array of views instead?
int Map = 0;
int NumeroMap = 1;
NSMutableArray *array = [[NSMutableArray alloc] init];
//add your views (levels?) to the array
[array addObject:someUIView];
[array addObject:someOtherUIView];
//now you can use your indexes to access the views you want
UIView *yourView = [array objectAtIndex:Map];
UIView *anotherView = [array objectAtIndex:NumeroMap];
i think what you are trying to do is not the way to go about things.