I coding app from iPad and I have to put two separate UITableView in the same screen. For this app I can´t put the UITableView and divid in two sections for requisits reason. It must be two separated. Well, in this case how I can fill the rows of UITableView. Can I have create a DataSource and Delegate in separate classes, one for a first UITableView and other DataSource and Delegate class for the second UITableView or have other approach more elegant?
tks a lot.
You can do this a few different ways. The most straightforward is to use separate classes to handle the datasource and delegate protocols for each table view.
Alternatively, you could use a single class as the datasource and delegate for both, and check the identity of the tableview that's passed into the protocol methods.
It would looks something like this: (I'm assuming this code is on your view controller.)
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
CGFloat height = 44.0; // default height
if (tableView == self.myLeftTableView) {
height = // Compute the cell height for the left table view.
} else {
height = // Compute the cell height for the right table view.
}
return height;
}
This could get ugly quickly, which is why I'd recommend the first approach.
Yes, you can make different classes for datasource and delegate methods for different UITableView and in-fact this is the best approach for using multiple tables on same view as this approach implements MVC architecture.
For this try these 2 solutions in which first approach is for implementing 2 tables datasource and delegate method in same class and second is to implement different datasource and delegate method in different classes either by using UITableViewController or NSObject class
For more detail try these links where you can find sample code too:
Handle more than one table in a View Part-1
Handle more than one table in a View Part-2
Related
How would you implement a 7x7 grid using UICollectionView? This grid would have no spaces in between each cell and also when it rotates the cells would simply resize to fit the screen, so it will always be 7x7 no matter what.
I have the following classes already done, a ViewController, a Cell class, a CollectionViewLayout class.
My original thinking was that I would have to do this in the CollectionViewLayout class, but which methods should I target to do this?
Apart from adjusting the datasource methods to return 7 sections and 7 rows per section, you have to have your view controller comply to the UICollectionViewDelegateFlowLayout protocol.
Assuming you want no spaces (having set the minimum spacing to 0) you can then use this method to size the cell:
-(CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return CGSizeMake(self.collectionView.bounds.size.width/7.0,
self.collectionView.bounds.size.height/7.0);
}
Actually, to make this work, you need another 2 tweaks. First, you should react to interface orientations, like this:
-(void)didRotateFromInterfaceOrientation:
(UIInterfaceOrientation)fromInterfaceOrientation {
[self.collectionView.collectionViewLayout invalidateLayout];
}
Second, to ensure one section does not get broken into 2 lines, you might have to use 7.01 for the division rather than 7.0.
Is it safe to deque UITableViewCell prototype from one table and use them in another?
When I want to display the UITableViewCell in the other UITableView I am simply dequeueReusableCellWithIdentifier a reusable cell from the table where the prototype type cells are specified. That is, not the UITableView they will be displayed in.
It seems to work fine and I haven't noticed any errors in the logs but I am concerned it might cause weird issues as I have not seen it done before.
Should I simply implement this using a separate nib for each cell? Or is this approach fine, bad practice or dangerous?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (self.prototypesTableView == tableView) {
cell = [self.prototypesTableView dequeueReusableCellWithIdentifier:cellType];
}
else if (self.otherTableView == tableView) {
cell = [self.otherTableView dequeueReusableCellWithIdentifier:cellType] ?: [self.prototypesTableView dequeueReusableCellWithIdentifier:cellType];
}
}
I'm pretty certain that each table view in memory has it's own queue of table view cells.
And when the table view (and view that hosts it) disappears, all the objects associated with it are released (assuming ARC here). Having one view with two tables shouldn't matter: each table has their own collection of cells to dequeue.
And in my own code, I frequently reuse the same custom "UITableViewCell" from one table to the next. To register a custom UITableView cell (which would be the only object in a XIB file), I do:
UINib * nib = [UINib nibWithNibName: #"SomeVeryCustomCell" bundle: nil];
if(nib)
{
[myTableView registerNib: nib forCellReuseIdentifier:#"SomeVeryCustomCell"];
}
This code is now running in production and I have seen no ill affects caused by dequeueing reusable cells from one table and using them in another. To ensure correct reuse I always dequeue from the "otherTableView" and if no UITableCell is available dequeue from the "prototypesTableView".
Although I implemented it like this for the sake expediency I would suggest it is better practice to implement it in the manner suggested by Michael, as it provides greater ability to share cells between view controllers.
I need a free Area at the Top (above) of my grouped-style TableView in an UITableViewController. What's the Top? The Area between NavigationBar and SectionTitle of the TableView.
First, i used
UIEdgeInsets inset = UIEdgeInsetsMake(60, 0, 0, 0);
self.tableView.contentInset = inset;
That works fine in the first Moment, exactly what I need. But, if I scroll down the TableView, the view will move into the new free Area.
To work with
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
seems doesn't work :(
Any suggestion?
The root view of a table view controller is the table view, so you can't put things above or below it, as there isn't a superview for you to add them to.
The solution is to use a UIViewController subclass instead, to this you can add a table view of any size, with views above and below it. There isn't much additional work involved - you have to declare that your view controller implements the delegate and datasource protocols, and connect those outlets up in IB, aside from that it's the same as a table view controller.
Basic message - you can have a table view without a UITableViewController.
If your table is read only, jrturton suffices. Otherwise, you also need to propagate the editing call from the UIViewController to the enclosed UITableView as follows:
//In UIViewControler propagate call to tableView property
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
[self.tableView setEditing:editing animated:animated];
}
You can use the headerView property of table create one view with required size and put it in the header view of table it will give you what you exactly need.
You can use -(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section delegate method of tableView to put the header view for first section.
Happy Coding :)
So you need a space above the Table view, which doesn't get covered by the table view when it is scrolled?
Instead of playing around with the table view, just try to add a UILabel on top of the table view or in place where the header of table view would have been there. Then make the table view's co-ordinates start right below that of the label. This way when you scroll, the space, i.e; the label here, is always visible.
The reason to do this is because everything defined for a UITableView, such as the header or footer, is always associated with the table, and cannot be manipulated separately.
What is the difference between dragging a Table View Controller into the storyboard vs dragging a UI View Controller and dragging a Table View inside that in xCode?
I know how to populate a table view controller in code.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath;
How do I populate a table view within a UI View Controller? What custom class do I delegate to the UI View? I cannot seem to put a tableViewController on it as it is only a ViewController with a table view...
I'd like to know this because I'd like to have objects other than the table in that view (i.e. a section of the view is for the table and the other section contains a label, an image, and a button.)
Populating a UITableView inside of a UIViewController is no different than populating a UITableView inside of a UITableViewController. You just have to make sure you implement the required datasource and delegate methods. You also need to be sure to assign the UIViewController as the delegate and the datasource for that UITableView.
If you want objects other than the table, then you should us a UIViewController. In fact, I rarely use the UITableViewController any more just in case I need to add other objects.
I found another difference too .
While using a UITableViewController , which has UIScrollView in it , the view scrolls up when keyboard moves up .
This doesn't happen with UIViewController as you need separate methods for View scrolling up and down .
You can also take a look at this
https://stackoverflow.com/a/14465669/5553647
Only UITableViewController can have static content. https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/TableView_iPhone/TableViewCells/TableViewCells.html#//apple_ref/doc/uid/TP40007451-CH7-SW20
I'm trying to set up very basic drag and drop for my NSTableView. The table view has a single column (with a custom cell). The column is bound to an NSArrayController, and the array controller's content array is bound to an NSArray on my controller object. The data displays fine in the table. I connected the dataSource and delegate outlets of the table view to my controller object, and then implemented these methods:
- (BOOL)tableView:(NSTableView *)aTableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard
{
NSLog(#"dragging");
return YES;
}
- (NSDragOperation)tableView:(NSTableView*)tv validateDrop:(id <NSDraggingInfo>)info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)op
{
return NSDragOperationEvery;
}
- (BOOL)tableView:(NSTableView *)aTableView acceptDrop:(id <NSDraggingInfo>)info
row:(NSInteger)row dropOperation:(NSTableViewDropOperation)operation
{
return YES;
}
I also registered the drag types in -awakeFromNib:
#define MyDragType #"MyDragType"
- (void)awakeFromNib
{
[super awakeFromNib];
[_myTable registerForDraggedTypes:[NSArray arrayWithObjects:MyDragType, nil]];
}
The problem is that the -tableView:writeRowsWithIndexes:toPasteboard: method is never called. I've looked at a bunch of examples and I can't figure out anything I'm doing wrong. Could the problem be that I'm using a custom cell? Is there something I'm supposed to override in the cell subclass to enable this functionality?
EDIT: Confirmed. Switching the custom cell for a regular NSTextFieldCell made dragging work. Now, how do I make drag and drop work with my custom cell?
I was banging my head against the wall in search of a more elegant solution to the same problem, and then I came across this:
http://www.wooji-juice.com/blog/cocoa-10-bindings.html
For instance, if you want to support drag-and-drop from a table, you need to set up a data source for it — even if you’re using bindings to supply the actual data, you can set a data source on it, and Cocoa needs one to handle the tableView:writeRowsWithIndexes:toPasteboard and related messages.
Yep. If you've got everything bound to your array controller, what you can do is to have the array controller implement the necessary drag/drop functions and then set the table view's data source to the array controller with setDataSource:.
I fixed the issue. There seems to be an issue with using bindings with custom NSCells in a table view. Switching to the traditional NSTableViewDataSource methods rather than bindings and an array controller solved it.
What works for me is to call initTextCell rather than init or initImageCell within the initializer of my custom cell (in my case, init). It doesn't seem to matter whether the superclass is NSCell or NSActionCell. Also, I have binding, and dragging still works.
That should be sufficient to allow the drag to start. Are you sure you've connected the delegate methods?
I ran into this problem, your custom cell needs to extend NSActionCell not NSCell if you want drag and drop to work properly. There is probably something you could implement in NSCell that would make it all work too, but I didn't dig any further after switching to NSActionCell. At least, that fixed the issue for me.
I ran into the problem. I have a NSCell subclass, and I did implement the tableView:writeRowsWithIndexes:toPasteboard and the dataSource was set for the NSTableView. Dragging would not work.
If I set the cell type in my init for the custom subclass
self.type = NSTextCellType;
Then I get dragging. If I don't, it defaults to NSNullCellType and dragging doesn't work. I'm guessing the people who got it working by using another subclass NSTextFieldCell works because the cell type is different.
I also observe the similar issue, NStableView drag & drop is not working. I have 4 column in my tableview and two of them are custom cells. Dragging for non-custom cell is working fine even though its working on cell separator as well however its not working with custom cells.
My custom cell was subclassed from NSButtonCell which was causing the
issue. So as suggested, I changed my parent class from NSButtonCell to
NSActionCell. Now, dragging is working perfectly.
It works with both NSCell as well as NSActionCell however I required action on my cell so used NSActionCell.