NSString editing by many View Controllers? - xcode

I want to print a NSString in my TextView in the mainViewController. But this command should come from a second ViewController. I declared a string in my mainViewController.h but I need this string in secondViewController.m! (The text should be printed in mainViewController). When I want to access to this string, it says Xcode does not know this variable. How can i create a string/variable, which I can edit and print from all of my ViewControllers(xib!)?

It sounds like you want to share a model between two view controllers. This is the correct MVC approach so that all that is required is for one of the view controller to change the value in the model and all the other view controllers will be notified and can update their respective views:
Please look at this excellent article on how this should be implemented.

just declare that NSString variable in AppDelegate & access in any ViewController through the sharedApplication method .in your case assign value to it in secondViewController & access that value in mainViewController
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSLOg(#"Nsstring value=%#",appDelegate.stringVariable);
assigning value:appDelegate.stringVariable=#"fromSecondViewController");

Related

Cocoa binding NSTableView within NSTableView

I'm trying to display a NSTableView inside a NSTableView. This is for an iTunes-like albums/tracks view. So there's a list of 10 albums, each album has some tracks. I want to display the albums in the outer table view and the tracks for each album in the inner.
The first NSTableView is bound to an NSArrayController. Each object in the array has its own "tracks" NSArrayController, but I can't figure out how to tell the 'tracks' NSTableView that its content comes from a property of the 'album' NSTableView.
If I understand you right, the source content of the nested array controller comes from objectValue of the owner table cell. So you can't put the array controller content source to be the objectValue of the table cell. I'm doing similar in that I want to filter the array content based on the object value
What I'm doing, which seems to be working, is to make a seperate nib file for your nested table cell view, with it's own nstablecellview subclass. Include the array controller in the nib and create an outlet to it in your cell view subclass.
Register it with the table view in the viewDidLoad method of the tables view controller:
NSNib *cellView = [[NSNib alloc] initWithNibNamed:#"MyTableCellView" bundle:nil];
[myTableView registerNib:cellView forIdentifier:#"myTableCellView"];
Then, in the awakeFromNib method of your cell view subclass, manually make your bindings that require the object value:
[self.arrayController bind:#"contentSet"
toObject:self
withKeyPath:#"objectValue.tracks"
options:nil];
Voila.
Note that when using this technique, the files Owner of the nib file is not your nstablecellview subclass, it is the view controller of the table view.
The problem lies in not understanding the MVC-pattern (Model-View-Controller). Content for a view never comes from another view, it comes from model objects via a controller. The content of each of your tableviews always comes from an NSObjectController, or a subclass like NSArrayController. Basically, there are two solution:
bind the 'tracks' tableview to the selection of the 'album' array controller
create a 'tracks' array controller and bind it to the selection of the 'album' array controller. Bind the 'tracks' tableview to the 'tracks' array controller
A third solution is to use an NSTreeController with an NSOutlineView but outline views and tree controllers are notoriously hard to work with.

NSFetchedResultsController running after performing push on UINavigationController

I am using an NSFetchedResultsController with my tableview inside of a UINavigationControler. When an item is tapped on the tableview I perform a 'push' and pass a specific entity in the prepareForSegue in order to show more detailed data about that record.
In the detail view controller the model can be edited. There appears to be a lot of lag when I change the model. And I noticed that the tableView:cellforRowAtIndexPath: on the previous view controller is being called.
I've tried using performSelectorInBackground: but doesn't seem to help much.
Once push a view controller, isn't the view controller below not supposed to run? Has anyone been able to overcome this lag issue?
Thank you
I actually ran into this tonight and solved it by adding a new bool property on my view controller to store when my VC is visible.
#property (nonatomic, assign, getter = isVisble) BOOL visible;
Then I check at the top of FRC delegate methods if the view is visible or not.
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
if (! self.isVisble) {
return;
}
[tableView beginUpdates];
}
This seems to help stuttering and performance when the VC with the FRC has been pushed behind other VCs.

Can I set a property when created with bindings?

I'm trying to build a To-do list application. I have 2 tablesviews and one textfield. In the first tableview are the different projects, and when you click on one of them the associated todos appear in the second tableview. It's a pretty basic Master-detail I guess.
I set it all up with bindings.
Right now the way you add a task, is you click on an add button and it adds a row with a placeholder text that's editable.
But what I want, is the user to enter the task in the textfield, press add, and then it adds the todo with the name already set.
So basically I have TodoItem Class with a name property, and my question would be, how do I get the content of the nstextfield and assign it to the name property ?
I tried creating an outlet from the Todoitem class to the textfield, but xcode won't let me connect it....
Tell me if you need to see any code, but since I used bindings, there's almost nothing to show. Thanks!
… how do I get the content of the nstextfield and assign it to the name property ?
Translate that directly into Objective-C:
NSString *contentOfTheNSTextField = [myTextField stringValue];
myNewTask.name = contentOfTheNSTextField;
You'd do that in the action method that you've set both the button and the field to call.
I tried creating an outlet from the Todoitem class to the textfield, but xcode won't let me connect it....
To do this, the Todoitem would need to reside in the nib.
But, even if you could do that, why should the model object know about the text field? Carrying values between model and view is a controller's job.

Xcode - Access one view controller from multiple view controllers

I have created an app which in total has 4 view controllers. 2 of these are pages that contain content with an (i) button in the top corner which links to an "about" section of the app. Currently I have 2 separate view controllers displaying the same thing (the about page) as I can't get the two view controllers to link to a single one when I click the button on each respectively.
Is there a way for two view controllers to access one view controller without me having to create a different about page for each one?
Thanks heaps
First you should set the button's target:
exampleButton addTarget:self action:#selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside;
Then, in the button's method:
-(void)buttonAction:(id)sender
{
AboutViewController *aboutViewController = [[AboutViewController alloc] init];
[self.navigationController pushViewController:aboutViewController animated:YES];
}
Don't forget to add the about view controller's header file
#import "AboutViewController.h"
If you use storyboard, you should change the button's action method with
-(void)buttonAction:(id)sender
{
[self.navigationController performSegueWithIdentifier:#"aboutSegueIdentifier" sender:sender];
}

NSTable CoreData and selection

I have a very simple App. It is a non-document based CoreData app. The nib contains one NSArrayController and a window with a NSTable with one column. Below the table are three buttons, Add, Delete, and Fetch. Below the buttons I have one NSTextField and a fourth button labeled Save.
My model has two Entities, Department an Employee. The Department has one attribute, name. I'm not currently using Employee.
In the AppDelegate.h I have added this code:
#interface HMGAppDelegate : NSObject <NSApplicationDelegate>
{
NSArrayController *_departments;
}
#property (retain) IBOutlet NSArrayController *departments;
and in the AppDelegate.m
- (void) awakeFromNib
{
[[self departments] fetch:nil];
}
The buttons are bound to add: remove: and fetch: on the NSArrayController.
The save button is bound to save: on the AppDelegate
The NSTextField is bound to the instance of the NSArrayController in the nib, ControllerKey is selection, Model Key Path is: name
When I run the app, I can create new entities and change the value of the entities. That all works fine.
What doesn't work is selection in the table. Changing the selected row in the table does not cause the value from that row to be selected in the NSArrayController. I understand I could put a delegate on the table catch SelectionDidChange and explicitly set the selection on the ArrayController, but I wonder if there is an easier way to do this.
I have seen other examples where there are two table views, representing a one to many relationship. Selection in the first table causes the second table to display the dependent entities. (for example choosing a department shows the employees of that department). In the example I'm looking at there doesn't seem to be a NSTableDelegate.
What am I missing? How does the NSTableView communicate its selection back to the NSArrayController?
How did you setup the Binding? If you bind NSTableView's content to NSArrayController, you have to bind the selection & sortDescriptions as well.
As an alternative, you can bind the table column's Value Binding to Array Controller.arrangedObjects and the selection should work.

Resources