Set up table view without delegate - iphone

I have a UITableView in view controller. I want to set up the view, properties etc for the table view without setting a UITableViewDelegate or UITableViewDataSource delegate.
Is it possible programmatically? (something like [tableView setNumberOfSections:2])

No it's not possible. But maybe it's an option for you to use a static tableview? There you don't need a delegate, but your number of rows / sections is fixed.

No, but you can set
myTableView.delegate = self;
myTableView.dataSource = self;
and then add the code for the methods in the same class (so you don't need to create new custom classes).

You can't, and why would you want to do that? The system of using delegates is there to give you the most flexible solution possible, you don't have to use all the delegate and datasource methods. It's just the way it works to make it possible to completely customise your table should you choose to, but a basic implementation is almost no work.
You can use any class as the delegate just by adopting the UITableViewDelegate and UITableViewDataSource protocols, so you don't need to create any specialised class. Just use your viewController for example.

Related

Best approach to add Static-TableView-Cells to a UIViewcontroller?

I want to add a tableview-look-a-like-login to my app, but it seems to be not that easy to implement. I tried to accomplish my goal using more then one approach, but i am not sure about which solution is the best.
For example, Dropbox and Facebook have a login page like this.
Here are my 3 approaches :
I added 2 UITextfields to my View (no border) and placed a . png behind, which looks like a tableviewcell. ( Not the best approach cause i want to use real tableviews )
I added a Container View to my ViewController placed a tableview with static Table Views inside. The Problem here is, that i dont know how to access the information inside my viewcontroller?
I added a tableview to my ViewController and used dynamic cells with it. Connected the outlets for delegate and datasource to my viewcontroller and initialized them with the delegate and datasource methods. The Problem here is, that i can not use static table views inside a uiviewcontroller.
Is there any better way of solving this problem ?
I would really like to know how to do this in a more elegant way.
EDIT:
A ContainerViewController basically solved this issue for me some month ago.
After embedding one into the main controller you can access it through the prepareForSegue function and define a protocol-based interface for that specific controller to interact with the embedded controller.
If you want to use static cells inside a regular UIViewController, just add the static cells and design them the way you like in interface builder, then connect the table cells as strong IB outlets (weak won't work, make sure they are strongly referenced). This will work flawlessly if you have a few table cells. Then set the view controller as the data source of the tablet view, implement -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section to return the number of cells and implement -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath to return your strongly referenced cell instance for the specified index path. I've used this method for a simple table view in my view controller that had four cells and it is working perfectly. For a large-dynamic data set, I definitely do not recommend this approach but for small, static tables, this does the job right.
I have an idea how to solve this. I think it's a clean way to do so. You do not need storyboard for this controller.
Make your controller subclass UITableViewController like so:
#interface YourViewController : UITableViewController
Then in your viewDidLoad you create the instances of the cells:
- (void) viewDidLoad {
usernameCell = [YourTextFieldCell new];
passwordCell = [YourTextFieldCell new];
}
The YourTextFieldCell is of course your own subclass of a UITableViewCell, which could be something like this:
#implementation YourTextFieldCell {
UITextField textField;
}
- (id) init {
self = [super init];
if (self) {
// Adjust the text's frame field to your liking
textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 200, 20)];
[self addSubview:textField];
}
}
// A getter method to access the textfield from the outside
- (UITextField *) textField {
return textField;
}
#end
Back in YourViewController:
- (NSInteger) tableView:(UITableView *) tv numberOfRowsInSection:(NSInteger) section {
return 2;
}
- (UITableViewCell *) tableView:(UITableView *) tv cellForRowAtIndexPath:(NSIndexPath *) indexPath {
if (indexPath.row == 0) {
return usernameCell;
} else if (indexPath.row == 1) {
return passwordCell;
}
return nil;
}
Do you get where I am going with this? This is how I think you should do it! Good luck!
I think your approach 2 is the best. If you need to access information in the table view controller, from your UIViewController (which will be the parent view controller), you can get a reference to that table view controller with self.childViewControllers.lastObject. In the viewDidLoad method of the UIViewController subclass, you could set yourself as the delegate of the table view with this line if you want:
[[(UITableViewController *)self.childViewControllers.lastObject tableView] setDelegate:self];
That way, you could implement the tableView:didSelectRowAtIndexPath: method in the view controller, which will get the information I'm guessing you need.
If you go with your option 2) using a storyboard and have a ContainerView containing your own subclass of UITableViewController with static cells then you can implement the prepareForSegue: method in your parent ViewController to take a reference to the UITableViewController (it'll be the destinationController of the segue) and also to pass itself down to the UITableViewController subclass if necessary (which should hold onto it with a weak reference).
Disclaimer - This answer will work for any size of UITableView, but if you're just making a login view, Tom's answer will work quite well.
I'm not sure if this will help, but what I did for this was create my own UITableView-esque subclass with a UITableViewCell-esque subclass as well.
This may not be what you want to hear, but I find what I made to be really helpful, since I've used it a number of times now. Basically, you have a UIView with the stylistic approach for the different types (10.0f - 20.0f cornerRadius and a 1px border (divide by UIScreen's scale property for retina). As for the cell, you'll want to have a full sized UIButton on it that responds to your table view for the touch events either with a delegate or by setting the target and tag inside your table view's class.
Last, you'll have a delegate system just like the UITableView for your information for building the specific tables.
In short, you'll need:
2 UIView subclasses (TableView and TableViewCell)
2 Delegates/Protocols (TableViewDataSource and TableViewDelegate)
Optionally
1 Delegate (TableViewCellResponseDelegate)
1 NSObject Subclass (Contains all of the information needed in each cell - Ease of use)
I found Can's solution to be the best / easiest, but unfortunately it breaks in XCode 5.1 --
I found a workaround which builds off the same basic idea, but unfortunately requires a little more involvement: http://www.codebestowed.com/ios-static-tableview-in-uiviewcontroller/
To summarize, you can add TableViewCells directly to views (and create IBOutlets from them, etc), but in order for them to get "moved" to the TableView properly, you need to remove them from the view in code, and you also need to set Auto-Layout constraints in IB.

What exactly does delegate do in xcode ios project?

I have just been learning iPhone apps development but I have a hard time in understanding what delegate actually means? Can anyone tell me with example what it does and how important it is? Thanks for any helps!
It's a key concept to understand conceptually so getting your head around how to think about it ahead of the technical details is important. Simply put, a delegate is a callback.
Two main scenarios to use delegates:
A class or control wants to abstract out the details on how to do work (like retrieve data).
Allow others to hook code into a pipeline.
Examples:
UITableView - a table view is just a control that knows how to render a list of cells. It handles all the heavy lifting of rendering, scrolling, etc... But, it has no idea how to load your data. So you implement a datasource delegate which has methods to get the cell data for a given row etc... That makes it easy on you. You just use the control and plug in the specifics for your data. The UITableView will do everything for you ... just answer a few specific questions for. A delegate answers those few specific questions.
A text control - you add a text control to your view and voila! you can type in it and alls good. But what if you want to do something when they start typing or when they're done typing? Well, the text control offers a delegate with methods that allow you to hook into the execution pipeline of the text control. It allows the text control to do everything for you and allows you to interject code where you need it. Many times, there's way to interject code to make a decision on whether something is allowed. The control will call back and ask, should I be able to do x? You can interject code and influence the behavior.
If you're creating a control or class, you can create your own protocol, datasource delegates etc... so your control can focus on doing what's advertised. For example, let's say you wanted to create a task control. You could:
First, create a contract. Hey, if you're going to provide data for my control, these are the questions I'm going to ask you. I'll take it from there... In this case, I'm going to ask you the number of tasks and I'm going to have you give me a task given the row number.
#protocol XXTaskBoardDelegate <NSObject>
-(NSInteger*)getTaskCount;
-(XXTask*)getTaskForRow:(NSInteger*)rowNumber;
#end
In the control or class, give the consumer a way to give us the delegate datasource class that will answer the questions the control will ask. At this point, the control is a pure control. It knows nothing about how you get your data. It's asking for an object (id) that implements a contract/protocol. id
#implementation XXTaskBoard
- (void)setDelegate:(id<XXTaskBoardDelegate>)newDelegate
{
// the control stores the delegate so it can callback and ask you questions.
}
Then, for the delegate class, in the header declare you implement that formal protocol
and in the implementation m file you provide the code.
#interface AppController : NSObject<XXTaskBoardDelegate>
{
//...
}
then, implement it in the implementation
#implementation AppController
- (NSInteger*)getTaskCount
{
return [model queryTaskCount];
}
- (XXTask*)getTaskForRow:(NSInteger*)rowNumber
{
return [[model tasks] getItem:(NSInteger*)rowNumber];
}
A delegate is an object that another class can pass messages to. In practice delegate classes have to conform to a delegate protocol.
For instance we will take a subclass of a table view controller. This is a delegate for your table view. First you define that it is a table view delegate by doing this:
MyTableViewController : UITableViewController <UITableViewDelegate>
This says that class MyTableViewController is a subclass of UITableViewController and CONFORMS to the UITableViewDelegate protocol.
Setting [tableView setDelegate:self] (or defining it as such in IB) then passes the self object to the tableview in order for the tableview to send messages to it.
The main message it sends is the didSelectRowAtIndexPath message which tells your class that the user has pressed a table view cell.
So the object that takes the click event (the table view) passes on the message that the cell has been clicked to the delegate object (which in this case is your MyTableViewController object).
Delegate protocols exist so that you can make sure that the delegate object has the necessary methods to deal with your messages. Methods in a delegate protocol can be #optional or enforced. Any methods that are optional don't have to be defined. In your MyTableViewController class the method didSelectRowAtIndexPath is optional - you don't have to have it. If the table view doesn't find the method it just won't call it.
However the cellForRowAtIndexPath is necessary and without it your app won't compile.
I hope this helps and is straightforwards for you. If you need any more info let me know.
Delegates are just way of getting callbacks from something. You pass a delegate (a pointer to an object that conforms to a protocol) to something and when it has new data for you or when an event occurs that something make a method call on the delegate.
For example, when events occur, like your app is put into the background or the app is about to terminate the UIApplication object will call your application delegate to let it know. When a CLLocationManager has a new GPS position is will call your delegate to pass it the new position. UITableViews call their delegates to get UITableViewCells to display in the table. There are many uses of delegates in iOS.

Setting UITableViewController Delegate?

If I have a class of type UITableViewController and I am going to add the required delegate methods to that class am I right in thinking I don't need to specify a delegate as the class defaults to using itself?
I am not quite sure it is a good idea to make a class be its own delegate. Maybe it would work with UITableViewController, but I read that this wouldn't work with UITextField for example, because it intoduces a message loop, see: Problem with TextField set as its own delegate
However, whether you decide on trying or specifying another delegate, you need to adopt the UITableViewControllerDelegate protocol in any case.

understanding methods in objective-c

for example we use this method in the tableview
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 16;
}
i want to learn we don't call this method in anywhere but application reads this value how is it being? there are a lot of methods like this we did not call.
Your object has been set as the data source of the UITableView somewhere. Most likely, by making a connection in InterfaceBuilder, though it is straightforward to do so in code by setting the dataSource property of the UITableView:
- (void) setUpMyJunkMan
{
myTableView.dataSource = self;
}
Once you have set your object as the data source, the table view will invoke the method as needed to determine what it needs to draw or how it needs to respond to events.
Your object is required to implement the UITableViewDataSource protocol (though, if you connected the data source via InterfaceBuilder, there may not be a complaint if you don't -- it is more of a compile time validation than a runtime one).
If you look at the declaration of UITableViewDataSource, you'll see that a number of methods are #optional. The rest are #required; you must implement them to fulfill the contract of the protocol.
This is the key difference between data sources and delegates. Delegates can optionally implement any of the declared methods. Data sources create a much more formal relationship between the two objects wherein some of the methods must be implemented.
An easy way see why a method is being called - set a breakpoint, run in debug mode, and then look at the stack trace.
For this particular case - It's being called automatically by the framework when it renders the table view.
I think you really need to take a look at The Table View Programming Guide so that you have a good understanding of what methods you need to override (and not override) when using Table Views. If you are extending the TableViewController class the framework does a lot of the heavy lifting and you barely have to write any code.
numberOfSectionsInTableView: is being called by the table view.
You implement numberOfSectionsInTableView: as part of the UITableViewDataSource protocol. Each UITableView is given a dataSource. Normally, UITableView will be constructed by a UITableViewController which will set itself as the view's dataSource.
When the view is shown, it calls numberOfSectionsInTableView: on its dataSource.
This is explained in the Table View Programming Guide for iPhone OS.
This is part of a Delegate Interface.
At some point in your application (possibly in your UIBuilder) you have specified that the object that contains the method is actually the delegated object. This means that when you want to adjust the behaviour (in this case of a UITableView) you can without actually extending UITableView but mearly changing the delegate methods.
basically the UITableView class will look somehting like this.
- (void) AMethodinUiTableView
{
int colums =[self.delegate numberOfSectionsInTableView:self];
}
for more info i would check out delgate programing and selectors.

Change uitablelview properties in subclass in viewdownload method in cocoa?

I've been following a tutorial that manipulates a uitableview from a uiviewcontroller to generate nicely styled cells.
I was wondering is it possible to do same to a class that subclasses uitablewcontroller instead of uiviewcontroller. The user uses code like:
tableView.rowHeight = 50;
tableView.backgroundColor = [UIColor clearColor];
In the viewdidload method. I would like to do the same but again in a uitableview sub class. I tried to do
self.rowHeight = 50;
But this didn't work. Does anyone know how I can implement this?
Thanks a million!
This is the actual tutorial site: http://blog.atrexis.com/index.cfm/2009/1/6/iPhone--Customize-the-UITableCellView
The Cocoa design patterns encourage using a controller object to configure views, but there's no reason why you can't subclass like you're describing, especially if you need to add functionality that can't be done any other way. You can use properties and methods just how you're describing, so there's a problem somewhere else. What method are you subclassing to assign the row height? Have you checked in the debugger to make sure your subclass is being allocated instead of a regular table view?
A UITableViewController IS a subclass of UIViewController.
The only diffference is that it conforms to the UITableViewDelegateDataSource and UITableViewDelegate protocols and it has an additional instance variable: tablview.
In viewDidLoad, you can set any table properties you like except for style (style has to be set in the initializer or in IB)
- (void)viewDidLoad{
[[self tableView] setRowHeight:kCellHeight];
[[self tableView] setTableHeaderView:myView];
//etc...
}