Populate a UITableView with variables - objective-c

I have a table and so far, I can populate it by adding values to an array in the code. But I want to use a textfield values and enter it there, the only problem is, if I do that I can only have one value, I want to pass a textfield value without overwriting the current cell.
Here is what I have:
-(void)viewDidLoad
{
[super viewDidLoad];
//[self fetchRecords];
titlestring = [[NSUserDefaults standardUserDefaults] objectForKey:#"titletext"];
detailsstring = [[NSUserDefaults standardUserDefaults] objectForKey:#"details"];
tabledata = [[NSArray alloc] initWithObjects:#"titlestring", nil];
tablesubtitles = [[NSArray alloc] initWithObjects:detailsstring, nil];
}
Is there a way to use MyArray[i] = marry initWithObjectcs...
Thanks.

I don't understand what you is your problem.
But if you want to add objects to an existing array, you should use a NSMutableArray not a NSArray.

Related

MASPreferences choose view

I am using MASPreferences in my app, I was able to set up everything correctly, with 3 different views (preferences, login and about).What I would like to do is to choose which panel gets shown when the window is opened. This is so that when the user clicks on about, the about panel is shown, etc. instead of the last panel shown being the one displayed. As of now I have tried modifying the entry in the plist file, but it does not seem to work. Is there any other way?
So after a bit of trying, and by using #Jasper's answer, I came up with the following:
-(void)openPreferencesWindowWithIdentifier:(NSString *)identifier {
[NSApp activateIgnoringOtherApps:YES];
[[NSUserDefaults standardUserDefaults] setValue:identifier forKey:#"MASPreferences Selected Identifier View"];
// Create the preferences window
NSViewController *generalViewController = [[GeneralPreferencesViewController alloc]initWithNibName:#"GeneralPreferencesViewController" bundle:nil];
NSViewController *loginViewController = [[PushoverLoginViewController alloc]initWithNibName:#"PushoverLoginViewController" bundle:nil];
NSViewController *aboutViewController = [[AboutPreferencesViewController alloc]initWithNibName:#"AboutPreferencesViewController" bundle:nil];
NSArray *controllers = [[NSArray alloc]initWithObjects:generalViewController,loginViewController,[NSNull null],aboutViewController, nil];
NSString *windowTitle = NSLocalizedString(#"Preferences", #"Comon title for preferences window");
_preferencesWindowController = [[MASPreferencesWindowController alloc]initWithViewControllers:controllers title:windowTitle];
[self.preferencesWindowController showWindow:nil];
}
Essentially this method writes the required "tab" on the plist file, and then initalizes a new instance everytime. By doing so, the correct view is loaded. The identifier parameter is the one you set up for each of the views. Thanks again to Jasper for his answer, really helped me understand how to figure this one out!
MASPreferences remembers the last opened 'tab'
Change in the order in your array when passing it to your MASPreferencesWindowController should work to change the order of your tabs.
-(NSWindowController *)preferencesWindowController
{
if (_preferencesWindowController == nil)
{
NSViewController *generalViewController = [[GeneralPreferencesViewController alloc] init];
NSViewController *accountViewController = [[AccountPreferencesViewController alloc] init];
NSViewController *troubleshootingViewController = [[TroubleShootingPreferencesViewController alloc] init];
//Change the order here
NSArray *controllers = [[NSArray alloc] initWithObjects:accountViewController, generalViewController, troubleshootingViewController, nil];
NSString *title = NSLocalizedString(#"Preferences", #"Common title for Preferences window");
_preferencesWindowController = [[MASPreferencesWindowController alloc] initWithViewControllers:controllers title:title];
}
return _preferencesWindowController;
}
Have a look inside MASPReferencesWindowController.m line 6. There is a static NSString key which handles the logic to show the last selected tab
static NSString *const kMASPreferencesSelectedViewKey = #"MASPreferences Selected Identifier View";
The key is used in:
- (void)windowDidLoad
{
if ([self.title length] > 0)
[[self window] setTitle:self.title];
if ([self.viewControllers count])
self.selectedViewController = [self viewControllerForIdentifier:[[NSUserDefaults standardUserDefaults] stringForKey:kMASPreferencesSelectedViewKey]] ?: [self firstViewController];
NSString *origin = [[NSUserDefaults standardUserDefaults] stringForKey:kMASPreferencesFrameTopLeftKey];
if (origin)
[self.window setFrameTopLeftPoint:NSPointFromString(origin)];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(windowDidMove:) name:NSWindowDidMoveNotification object:self.window];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(windowDidResize:) name:NSWindowDidResizeNotification object:self.window];
}
TL;DR
Look for the method - (void)setSelectedViewController:(NSViewController <MASPreferencesViewController> *)controller inside MASPreferencesWindowController.m
Comment this line:
// Record new selected controller in user defaults
[[NSUserDefaults standardUserDefaults] setObject:controller.identifier forKey:kMASPreferencesSelectedViewKey];
Now change the way you initialise your NSWindowController so you create a new instance every time, otherwise it will still remember the last selected tab:
-(NSWindowController *)preferencesWindowController
{
NSViewController *generalViewController = [[GeneralPreferencesViewController alloc] init];
NSViewController *accountViewController = [[AccountPreferencesViewController alloc] init];
NSViewController *troubleshootingViewController = [[TroubleShootingPreferencesViewController alloc] init];
//NSArray *controllers = [[NSArray alloc] initWithObjects:generalViewController, accountViewController, troubleshootingViewController, nil];
NSArray *controllers = [[NSArray alloc] initWithObjects:accountViewController, generalViewController, troubleshootingViewController, nil];
// To add a flexible space between General and Advanced preference panes insert [NSNull null]:
// NSArray *controllers = [[NSArray alloc] initWithObjects:generalViewController, [NSNull null], advancedViewController, nil];
NSString *title = NSLocalizedString(#"Preferences", #"Common title for Preferences window");
_preferencesWindowController = [[MASPreferencesWindowController alloc] initWithViewControllers:controllers title:title];
return _preferencesWindowController;
}

Changes made in old array also reflecting in new copied array

Copied the contents of an array to another array using mutableCopy, but if the changes made in original array it also show changes in new array. Below is code m using.
NSArray *newArr = [mainArray mutableCopy];
[[newArr objectAtIndex:indexpath.section] replaceObjectAtIndex:indexpath.row withObject:#""];
[[mainArray objectAtIndex:indexpath.section] removeObjectAtIndex:indexpath.row];
objAppDelegate.arrayProfile = [newArr objectAtIndex:2];
I have to remove the value from original array mainArray, but not want to reflect the changes in new array. Please guide.
For NSArray you have to use copy not mutablecopy
NSArray *newArr = [mainArray copy];
You need to copy all items of main array
NSMutableArray *newArr = [[NSMutableArray alloc] initWithCapacity:mainArray.count];
for (NSObject* item in mainArray) {
[newArr addObject:[item copy]];
}

Xcode NSMutableArray not populating data from NSUserDefaults

I have a problem with adding data to an NSMutableArray. I have a tableView and I store the cell text in an NSMutableArray. The tableView is user-populated, meaning that the user enters in what they would like to put on the tableView (to make lists, etc.). The problem I have is with storing the data they have entered. Here is my saving code:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:self.tasks forKey:#"tasksArray"];
[defaults synchronize];
The variable "tasks" is the NSMutableArray. The above code happens right after the user presses the done button on the keyboard and the keyboard text is added to the "tasks" NSMutableArray. There does not seem to be any problem here because I have debugged and found that everything saves properly.
In my viewDidLoad:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSArray *array = [[NSArray alloc] initWithArray:[defaults objectForKey:#"tasksArray"]];
if ([self.tasks count] == 0) {
NSLog(#"Array is 0");
self.tasks = [[NSMutableArray alloc] init];
}
else {
NSLog(#"Array is > 0");
self.tasks = [[NSMutable array] alloc] initWithArray:[defaults objectForKey:#"tasksArray"]];
}
Now the above code is where I want the data to be loaded onto the array which populates the tableView. The error I get is a NSRangeException, index 0 beyond bounds of empty array. The problem seems to be with the NSMutableArray "tasks" and trying to fill it with the saved data. My goal is to have the "tasks" array populated with the data stored on NSUserDefaults under the key "tasksArray" if the user has previously entered any data. If not, and the tableView should be empty, then I want the "tasks" array to be created.
If any help could be given as to what is wrong with my code or provide a different method of getting a result that would help a lot. Thank you!
Why you are using these If else condition. Just use
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if(!self.tasks)
self.tasks = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:#"tasksArray"]];
else
[self.tasks addObjectsFromArray:[defaults objectForKey:#"tasksArray"]];
Now you can place the check, where you want
if([self.tasks count]){
}
else{
}
objectForKey returns a generic object. You know it's an array, but NSMutableArray does not recognize it as such. Use either:
self.tasks = [[NSMutableArray alloc] initWithArray:[defaults arrayForKey:#"tasksArray"]];
or
self.tasks = [[NSMutableArray alloc] initWithArray:(NSArray *)[defaults objectForKey:#"tasksArray"]];

Change from a NSMutableArray to a .plist

I have been working through several tutorials on uitableviews.
I have put, as instructed, all the info into a 'listofitems' as below
listOfItems = [[NSMutableArray alloc] init];
NSArray *countriesToLiveInArray = [NSArray arrayWithObjects:#"Iceland", #"Greenland", #"Switzerland", #"Norway", #"New Zealand", #"Greece", #"Rome", #"Ireland", nil];
NSDictionary *countriesToLiveInDict = [NSDictionary dictionaryWithObject:countriesToLiveInArray forKey:#"Countries"];
NSArray *countriesLivedInArray = [NSArray arrayWithObjects:#"India", #"U.S.A", nil];
NSDictionary *countriesLivedInDict = [NSDictionary dictionaryWithObject:countriesLivedInArray forKey:#"Countries"];
[listOfItems addObject:countriesToLiveInDict];
[listOfItems addObject:countriesLivedInDict];
This creates a sectioned table view. I would like to know how to change it into a .plist instead of typing it all out into the RootViewController.m. I would still like it to be in a sectioned tableview.
Is there a simple method for changing from this NSMutableArray,NSArray and NSDictionary to a plist?
There's a simple method for this writeToFile:atomically::
[listOfItems writeToFile:destinationPath atomically:YES];
This will automatically create a file with plist inside it.
that sorta depends on what you want in a plist, and what you put into it. if the entries and contents are all CFPropertyList types (CFString,CFDate,CFData,CFDictionary,CFArray,CFNumber...) then just create it with something like CFPropertyListCreateDeepCopy.
if you have non-convertible custom objects (e.g., your own NSObject subclasses), then see the cocoa archiving topics.
This is the simple function end hear relization
This is function is updating NSArray
- (void) WriteRecordToFile:(NSMutableDictionary*)countDict {
// Here to write to file
databasePathCallCount = #"plist path";
NSMutableArray *countArray = [NSMutableArray arrayWithContentsOfFile:databasePathCallCount];
if(countArray)
[countArray addObject:countDict];
[countArray writeToFile:databasePathCallCount atomically:NO];
}

Populate an NSTokenField with tokens from a container of objects

I have an NSTableView and an NSTokenField in a window. I have implemented the following delegate methods:
tokenField:completionsForSubstring:indexOfToken:indexOfSelectedItem:
tokenField:representedObjectForEditingString:
tokenField:displayStringForRepresentedObject:
I want to make it so that when a row is selected in it, the NSTokenField gets populated with the tags that are contained in an NSMutableSet of the row object. How do I populate an NSTokenField with tokens if I have a container of the objects that they represent (and therefore the strings that need to be made into tokens)?
I figured it out. In the code below ms is an NSMutableSet that contains my objects.
//set the token field
NSMutableArray *ma = [[NSMutableArray alloc] init];
for (MyClass *anObject in ms){
[ma addObject:anObject];
}
//sort the array
NSSortDescriptor *sorter = [[NSSortDescriptor alloc] initWithKey: #"title" ascending: YES];
NSArray *sortDescriptorArray = [[NSArray alloc] initWithObjects:sorter, nil];
[ma sortUsingDescriptors:sortDescriptorArray];
[tokenField setObjectValue:ma];
The key is the last line: [tokenField setObjectValue:ma];