Add delegate to custom UITableView - iphone

I have a custom UITableView integrated in my ViewController, with more elements, and I tried to add to the UITableView a control to refresh its content, like twitter app. The problem is that I can't capture the scrolls of the tableview in the ViewController. If I set the delegate of the custom UITableView, then I can capture the scrolls but I get troubles with the custom table behavior.
So, I don't know what it's better, either find the way to add the delegate for scrolls without override anything or find a way to add the control to refresh the table from the ViewController, not from the UITableView class.
The case with more details is:
A library for the custom UITableView. It's used to draw a conversation like the message app. So I just pass the information to the table and the table draw it. I don't do anything more, not delegate, nothing, just add the table to my ViewController.
I put the methods of the scroll's delegate in my ViewController, and, when I do scroll in the table, I don't get anything(the app doesn't enter in the scroll's delegate methods). If I set the table's delegate to self, the scroll works but I get some random problems from the table( I don't know how it's made the table), so I have to discard this option(set the delegate).
Thanks in advance

Try using the UIRefreshControl object. You define this object in the viewController in the viewDidLoad method and add the target to your tableView when it's value changes, here is an example:
self.refreshControl = [[UIRefreshControl alloc] init];
[self.refreshControl addTarget:self.tableView action:#selector(reloadData) forControlEvents:UIControlEventValueChanged];
Your viewController needs to be a UITableViewController however. To initiate and end the refresh use the methods:
[self.refreshControl beginRefreshing];
[self.refreshControl endRefreshing];

Related

Where is the proper place to reload TableView data?

My project has a few view controllers, let's say A and B.
In A I have a UITableView. When a row is selected, I pass the row number and cell text to view B, then pushViewController B.
In view B, when hitting the 'done' button I make changes to the underlying data (right now a Singleton array) and then pop back to view A. In view A viewDidAppear, I reload the UITableView to see the new data.
Is this the best way to do it?
Or should I be reloading the UITableView when the 'done' button is hit?
If so, how do I reload a Table in view A from within view B?
Thanks.
It is better to reload the data directly when you hit the "Done" button. You can do that by a Notification Center. Please check this link for more details about Notification Center.
ViewController "A" should certainly be responsible for deciding to reload the table data. I would consider putting that into the "viewWillAppear" method of ViewController A. That way the table is reloaded before being displayed to prevent and "flickering".
There is nothing very wrong about this, except that your table will be reloaded every time it's viewDidAppear is called, which may not be very good depending upon the size of the table. The best way would be to use #protocol and make a quick delegate design pattern, though this might seem unnecessary headache if you are not used to it. You can also use NSNotifications, although I would not insist using it in this case, as there are not many observers listening to the event.
Instead of using NSNotification. You can assign view A to be view B's delegate which is a much cleaner design pattern.
So in view A it would look like
ViewB *b = [[ViewB alloc] init];
b.delegate = self;
and the in viewB when you are done making modification u call
[delegate updateTable];
where in updateTable is a #required method in the delegate declaration and since its required viewA will need to implement it if it says it conforms to that delegation.
Also this method will be called before you pop the viewB out.

Scrollable all the way UITableView

I have this code linked to a button on a ViewController with a UITableView as subview:
-(IBAction)Action:(id)sender{
[tableView setContentSize:CGSizeMake(320, 1000)];
}
This makes tha tableView scrollable to the bottom so that I can use a couple of buttons I programatically added to the bottom. So far so good.
However, I want the tableView to be ok from the beginning, so I added the code inside viewDidLoad. Surprisingly, it doesn't work at all.
Could somebody give me a hand?
thanks!
If your datasource methods are being fired after viewDidLoad, the tableView content size will be reset when it's loaded. You'll need to make sure you've called reloadData for the table before the code above. If you're using a UITableViewController, the order the methods are called is:
viewDidLoad
ViewWillAppear:
<your datasource methods>
ViewDidAppear:
However, if you want buttons at the end of table, you should put them in the tableFooterView. You can do this in interface builder easily by dragging a view to the bottom of the tableView. Or you can do it in code (in your viewDidLoad method, for example)
Per #Justin's answer... your question isn't very clear
I'm not sure what your trying to accomplish. If your trying to access button on the bottom of a tableView why not use a Tableview Footer.
And if your trying to just scroll to the bottom of the tableview there is a method for that as well.
Need more info

UITableViewController without subclassing

Is it possible to create and display a UITableView controller which allows the user to select an item and fire back a message to the delegate without subclassing it?
The reason is I just want to display a list of items in a popovercontroller and it seems a waste to have to create a subclass just for this
In the view controller that presents the popover you could implement UITableViewDataSource and UITableViewDelegate - then set the popover's tableview to use the parent controller as its source and delegate before presenting it.
If you are using iOS 5 SDK then you can make static cells.
Otherwise the only option is to create a subclass and provide a DataSource array.
Either ways you might want to have a View Controller that prepares the view controller loaded on the touch action?

What's the best way to refresh a UITableView within a UINavigationController hierarchy

I'm pretty new to iPhone development and have struggled to find what I consider to be a neat way around this problem.
I have a user interface where a summary of record data is displayed in a table inside a navigation controller. When the user clicks the accessory button for a row, a new view is pushed onto the navigation controller revealing a view where the user can edit the data in the corresponding record. Once done, the editing view is popped from the navigation controller's stack and the user is returned to the table view.
My problem is that when the user returns to the table view, the table still shows the state of the data before the record was edited. I must therefore reload the table data to show the changes.
It doesn't seem possible to reload the table data before it is displayed as the call only updates displayed records. Reloading it after the table has been displayed results in the old data changing before the user's eyes, which I'm not too happy with.
This seems to me like a pretty normal thing to want to do in an iPhone app.
Can anyone please suggest the best practice approach to doing this? I feel like I'm missing something.
Cheers - Steve.
The standard approach may sound like a lot of hassle at first, but is a useful pattern for a lot of situations.
In your tableview class create a method like:
-(void)editDone {
[self.tableView reloadData];
}
Add a property to your edit controller like:
#property (assign) id delegate;
Set the delegate when your accessory is clicked:
editController.delegate = self;
And when editing is complete, call your method like so:
[delegate performSelector:#selector(editDone) withObject:nil];
You can create similar methods to handle cancel of your edit component, or to carry out dismissing of modal edit controllers, etc. It's considered more classy to put all this in a protocol, if you like.
I'd implement this in the following way:
Save indexPath of a clicked cell.
Implement -[UIViewController viewWillAppear:] method of the view controller, which contains the UITableView. If saved indexPath is not nil, reload specified cells with:
-[UITableView reloadRowsAtIndexPaths:withRowAnimation:]

Problem with UItableview reload data using alert view with prompt on a custom cell

I have a UItableViewController with a custom cell designed using interface builder. The custom cell has a button and a label on it. The button when click will trigger an alert view with prompt. Once the text is entered and press OK the label on the cell will display the updated info on the table. The problem is the label will not get updated until I click on one of the cells. I cannot use [tableview reloaddata] because I am using IB and it creates a separate .h and .m UItableViewCell files and this is where I put the alert view with prompt code in it. How can I call reload data to update the table when the alert view is dismissed. I have put [tableview reloaddata] in the UItableViewController under viewWillAppear, but it does not work.
You could keep reference to UITableViewController and call reloaddata on it from cell.
I am fairly new to iPhone development, however, one of the design patterns I have seen again and again is delegation. This allows you to extend functionality while maintaining reusability of your components.
I believe you can set a delegate for a UIAlertView and then implement the protocol on your main UITableViewController via in the #interface definition. This means that your controller will be notified of events as they pertain to that particular alert as long as you set the delegate property in your AlertView object after instantiation.
Take a look at the function...
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
If you set up the above delegation, then overload this function, you should be able to call [tableview reloadData] when the alert view is specifically pressed.
Also -- is there a reason you can't define the IBAction method that the button calls in the UITableViewController? This would allow you to avoid passing around the parent of the cell, seems like a better adherence to MVC.
I have figured it out. See code below:
UItableView *tableView = (UItableView *)self.superview;
[tableView reloadData];
The self.superview is the trick!