NSObject as delegate for UITableView - objective-c

I have a UITableView which is dragged into a UIViewController and a NSObject class. This NSObject class should serve as delegate and datasource to the tableview.
I tried creating an instance of NSObject and conformed delegate and datasource to the tableview. Datasource is working fine. But the cellForRowAtIndexPath: is never getting called and all i get is a EXC_BAD ACCESS and app just stops right there. But when I drag a object to UIViewController bottom pane and giving the class name to it and setting delegate and datasource, everything is working good and UITableView is displaying.
I don't know why this strange behaviour.
I have done this in the viewdidload of viewcontroller class.
customnsobject *custom=[customnsobject alloc]init];
tableview.delegate=custom;
tableview.datasource=custom;

create a parent id in your class h file like this
#property(nonatomic,retain) id parent;
and in your view controller just below the instance of nsobject you created do this
custom.parent=self;
I hope this will work

Related

View not updating when a message is sent to its view controller

I am having problems updating a view when a message from another class is sent to a ViewController.
Basically I have an application with a single window where different custom views will be swapped out for another. I have an AppController Class that manages this and works fine:
#interface AppController : NSObject
#property (weak) IBOutlet NSView *ourView;
#property (strong) NSViewController *ourViewController;
- (IBAction)changeView:(id)sender;
- (IBAction)start:(id)sender;
- (void)changeViewContoller:(NSInteger)tag;
#end
When a new view is swapped out for another, the ourViewController property will be updated to point to that view's controller class. Every view controller class will have a method all named the same thing, for example "action". This method is supposed to change something on a view.
So the "start" method in AppController class will then call the "action" method on the ourViewController property. To do this I used the objc_msgSend() method:
objc_msgSend(self.ourViewController, action);
Here's the View Controller class definition:
#interface CountdownViewController : NSViewController
#property (weak) IBOutlet NSTextField *label;
- (IBAction)changeLabel:(id)sender;
- (void)start;
#end
I placed an NSLog() in the "action" method for each ViewController, to see if it was working, and it does, however the "action" method is also supposed to change a label's string value, but it does not. If anyone knows why the view is not being updated, that would be extremely helpful. Thanks!
the view is held weak?
TRY making it strong if you need to retain that pointer in this class
btw: ..also why do you objc_msgsend.... use performSelector

Using a protocol and a delegate

I am trying to get some code in a view working. I have declared a delegate and it does not get instantiated, any Idea what I am missing?
I have tried to summarise how I have done this below. I think that the issue is that somewhere, my dataSource delegate needs to be instantiated.
I have a View called graph view and a delegate that is in the viewcontroller GraphViewController.
I know that the method in GraphView is doing something as it calls the AxisDrawing helper class and draws in Axes.
Here is the relevant code
In GraphView.h I set up the protocol and the dataSourceDelegate
#class GraphView;
#protocol GraphViewDataSourceDelegate
- (float)functionOfX:(float)xValue inGraphView:(GraphView *)sender;
#end
#interface GraphView : UIView
#property(nonatomic, weak) IBOutlet id <GraphViewDataSourceDelegate> dataSourceDelegate;
#end
Which I synthesize in GraphView.m
#import "GraphView.h"
#import "AxesDrawer.h"
#implementation GraphView
#synthesize dataSourceDelegate = _dataSourceDelegate;
Also in Graph View I try to use the delegate as follows (pixel is a CGPoint). This routine does run and I can draw to GraphView from here provided I do not try to use my protocol method. i.e. Some of my DrawRect stuff does get drawn which checks out the linking of the UIView to my custom View
pixel.y = [self.dataSourceDelegate functionOfX:pixel.x inGraphView:self];
++++Breakpoint put in here+++++
In GraphViewController I state that I implement the protocol and implement it as follows. The compiler warns me and spots when the implementation is done, turning of the warning. (I am only returning 3.0 at the moment as a test).
#interface
GraphViewController () <GraphViewDataSourceDelegate>
#property (nonatomic, weak) IBOutlet GraphView *graphView;
#end
...
-(float) functionOfX:(float)xValue inGraphView:(GraphView *)sender{
NSLog(#"fofx accessed");
return 3.0;
}
If I look at the GraphView* object just after a breakpoint, it seems to have no instance. What am I missing out.
This is from the trace at the breakpoint
_dataSourceDelegate struct objc_object * 0x0
EDIT: (In addition to #Clays answer below)
It turned out that my connection to the custom view was broke. This meant that the fault lay with the View not talking to the Custom ViewController. The link is made by ctrl dragging from the View Controller button in the Interface builder to the View within the ViewController.
This caused the ViewController to be instantiated and everything then worked fine.
To put it another way.
The link in question was the Outlet. This has to be declared in the ViewController as a property and then linked in IB using ctrl Drag from the ViewController Name-Bar to the View in the Controller.
Provided that you have added the Outlet property correctly, when you do the ctrl drag, your view will appear an option.
The context button popup information on the ViewController button in IB does give a clue.
If you have neglected to put the outlet property into the view controller, the link does appear in the context button popup but it is greyed out, and when you do the link your View is not named.
Once you put the outlet in, the name appears in the menu but not greyed out.
Make sure you've hooked everything up correctly: setting your GraphView's dataSourceDelegate, and your GraphViewController's graphView.
From the trace it looks like you haven't done that; or you lose the reference somewhere along the way because at some point nothing's holding on to it.

Reloading a TableView's data?

I'm trying to build a hello world application with Xcode 4.3.
So far, I have a TableView (dragged and dropped from the objects list) and a TableViewCell (also dragged and dropped from the objects list).
I have an array too, and my TableView works and gets the data from array, but how can I reload the TableView's data? I tried [self.tableView reloadData]; but it doesn't work. When I type [self., tableView is not in my options...
To have the NSTableView as a property of your class, you have to declare it as one.
In the interface of your class add:
#property (weak) IBOutlet NSTableView *tableView;
In the implementation add:
#synthesize tableView;
Then in Interface Builder connect the table view to the tableView outlet of your class, by right clicking on "File's Owner" and dragging a line from "tableView" to your table view.

Access a TableViewController from another class

I'm a beginner in objective-c and want to realize a simple GUI: A MyMainWindowController with a corresponding xib wich contains a table and a simple Add button.
#interface MyMainWindowController : NSWindowController
{
}
#end
The implementation code of the controller is nearly empty (pre-defined initWithWindow and windowDidLoad). The AddressTvc is defined like this:
#interface AddressTvc : NSObject <NSTableViewDataSource>
{
#private
IBOutlet NSTableView *myTableView;
NSMutableArray *list;
}
- (IBAction)add:(id)sender;
#end
This works fine. I can click on the Add button and a new row is inserted in the table.
It seems that the AddressTvc is created automatically (by the IB?) when the MyMainWindowController is visible. I want a reference in the code of MyMainWindowController to AddressTvc so I'm able to fill the table with some data retrieved by a background thread. This should be done by calling the - (IBAction)add:(id)sender; method.
I tried to create a AddressTvc inside the MyMainWindowController but then the object is initialized twice. I'm sure I have to wire it somewhere in the IB, but have no clue where to do this ...
Create an outlet in you MyMainWindowController class that can point to your table view controller class.
E.G.
#interface MyMainWindowController : NSWindowController
{
IBOutlet AddressTvc *myTVC
}
#end
Then simply control+drag from your file owner to the instance of the table view controller in interface builder and you can now access it in your window controllers code.

Can't access #Property from other class

I'm having trouble accessing some variables in my program.
I have one class called MainMenu.
In the .h file I have declared 2 properties as follows:
MainMenu.h:
#property (nonatomic, retain) IBOutlet NSView *mainView;
#property (nonatomic, retain) IBOutlet NSWindow *theMainWindow;
In another class file, I want to be able to access these 2 variables, current I am using the following code in the other .h class file which does not work, I don't understand what I'm doing wrong:
AppDelegate.m:
MainMenu *theMainMenu = [[MainMenu alloc] init];
[theMainMenu switchViews:theMainMenu.theMainWindow:theMainMenu.mainView];
Here I create an object of the MainMenu class, and invoke a method called 'switchViews' in its definition, I then want to pass it the 2 variables which I'm having trouble accessing.
Any help greatly appreciated.
Thanks in advance everyone.
EDIT: 'switchViews' method shown below:
- (void)switchViews:(NSWindow*)mainWindow:(NSView*)newView {
NSView *dummyView;
[mainWindow setContentView:dummyView];
[mainWindow setContentSize:newView.frame.size];
[mainWindow setContentView:newView];
}
I think the problem is one of 2 different instances of your MainMenu class. If you hooked up your IBOutlets, you must have a blue cube in IB set to your MainMenu class, correct? However, when you alloc init one in your app delegate, that creates another instance of MainMenu that doesn't have those properties connected to anything. Instead, you should also have a blue cube in IB set to your app delegate, and have an IBOutlet in that class that you connect to the MainMenu blue cube in IB.
This might be silly, but did you remember to link your NSWindow and NSView in Interface Builder? Or are you at least manually instantiating them?
My best guess is (assuming there is a MainMenu.xib somewhere), that when you call init, it object is inited but not necessarily loaded. You should try to call your switchViews method in your controllers viewDidLoad or viewWillAppear method to be sure it is all loaded.