Table view using CollectionView - ios

I have to represent data in a table.
I'm trying to build a layout suited to do this.
I was thinking something like:
I have already started with the implementation.
I have built a programmatically Collecionview and this is the result:
![MyWork][2]
On the internet there are infinite solutions. To me this seemed the most suitable but now I have two main problems:
I have implemented the CollectionView horizontally. So if I put
more than 15 ithem structure comes out badly because it adds the
ithem in a new column. So I wish it adds below and create a vertical
scroll view
second problem is to block the first column from the first line and
horizontal scroll view

Use rotated table view
-(void) didLoad{
....
[self.tableView.layer setAnchorPoint:CGPointMake(0.0, 0.0)];
self.tableView.transform = CGAffineTransformMakeRotation(M_PI/-2);
self.tableView.showsVerticalScrollIndicator = NO;
....
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
SEScrollMenuCell * cell = [tableView dequeueReusableCellWithIdentifier:#"menuCell" forIndexPath:indexPath];
//use custom UI objects inside cell
cell.label_text.text = [self.items objectAtIndex:indexPath.row];
cell.label_text.textAlignment = NSTextAlignmentCenter;
cell.selectionStyle = UITableViewCellSelectionStyleGray;
cell.label_text.textAlignment = NSTextAlignmentCenter;
cell.label_text.transform = CGAffineTransformMakeRotation(M_PI/2);
cell.label_text.frame = CGRectMake(0.0, 0.0, 32.0, [[self.items_width objectAtIndex:indexPath.row] doubleValue]);
.......
return cell;
}

Related

Scroll to the last two rows of table

when the table has more records than the screen let you see, and the user scroll to the bottom for the last records in the table, the last two rows are not accessible (just in iOS7, in iOS8 everything is fine). Once the user take the finger from screen, the table goes up, and the last two rows are hidden.
This is one of the method used for tableView but i dont know if this come from here:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * cellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
// Configure the cell...
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
if (selectionCategMsg == 0)
{
if ([self.tableauMsgReceived count] < 1) {
cell.textLabel.text = NSLocalizedString(#"noMessagesYet", nil); //#"No messages yet !";
}
else
{
cell.textLabel.text = [NSString stringWithFormat:#"%#", [self.tableauMsgReceived objectAtIndex:indexPath.row]];
cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
}
}
else
{
if ([self.tableauMsgSent count] < 1) {
cell.textLabel.text = NSLocalizedString(#"noReplyYet", nil);
}
else
{
cell.textLabel.text = [NSString stringWithUTF8String:[NSString stringWithFormat:#"%#", [self.tableauMsgSent objectAtIndex:indexPath.row]].UTF8String];
cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
}
}
[cell setAccessoryType:UITableViewCellAccessoryNone];
return cell;
}
Can someone give an advice ? Thank you.
THIS IS THE SOLUTION THAT I FOUND:
// -> SET TABLE FRAME
CGFloat sideMargin = 0;
CGFloat originX = sideMargin;
CGFloat topBottomMargin = 100;
CGFloat originY = topBottomMargin;
// Width based on view size
CGFloat sizeWidth = self.view.bounds.size.width);
// Height based on view size
CGFloat sizeHeight = (self.view.bounds.size.height - topBottomMargin);
self.myTableView.frame = CGRectMake(originX, originY, sizeWidth, sizeHeight);
// <- END SET tableView frame
UITableView has the method scrollToRowAtIndexPath:atScrollPosition:animated:. That method lets you scroll the table view so a given indexPath is visible. Is that what you're looking for?
EDIT:
#Daij-Djan's post is a good theory on what's wrong. If your table view goes off the screen then it will position the last couple of cells inside it's view, but that view won't be visible. You're going to need to do some debugging to figure out what's wrong. You might try setting the table view's layer's borderWidth to a non-zero value so you can see the bounds of the table view.
In your viewDidLoad, add code like this:
myTableView.layer.borderWidth = 1;
myTableView.layer.borderColor= [UIColor redColor].CGColor;
(Where you'd replace "myTableView" with the name of your table view instance variable or property.)
You'll have to import QuartzCore.h in order for the code above to compile:
#import <QuartzCore/QuartzCore.h>

TableView rows get mixed up when scrolling

I am using a tableview in a UIViewController and I have subclass of UITableViewCell.
I register the cell in viewDidLoad;
- In cellForRowAtIndexPath, I use dequeueReusableCellWithIdentifier to get the cell and I reset all the labels to the right values; However, when the table scrolls, the top rows and the bottom rows get mixed up and the labels get interchanged. I don't know why this would happen when I am resetting the cells to the right values for each row. Do you have any idea why the mix up happens.
[self.myFoldersTableView registerClass:[QConnectFoldersTVCell class] forCellReuseIdentifier:QMY_FOLDERS_CELL_ID];
and
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:NSIndexPath *)indexPath
{
QConnectFoldersTVCell *cell = (QConnectFoldersTVCell *)[tableView dequeueReusableCellWithIdentifier:cellId forIndexPath:indexPath];
NSMutableDictionary *cellDataDict = [self findCellDataAtIndexPath:indexPath];
// Configure the cell...
cell.mainLabel.text = cellDataDict[FOLDER_CELL_DICT_KEY_MAIN_TEXT];
cell.detailLabel.text = cellDataDict[FOLDER_CELL_DICT_KEY_DETAIL_TEXT];
cell.folderCellType = [cellDataDict[FOLDER_CELL_DICT_KEY_TYPE] intValue];
return cell;
}
I want to add that I have printed out the label values being set for the row and the data is right for each row. The cells are being reset to the correct data in the above function. So I don't know why something else is displayed on screen.
I found the reason for the mixup. In my tableViewCell subclass, I was using layoutSubviews to do initialization for the labels because the actual size of the cell isn't available in init but is available in layoutSubviews. Removing layoutSubviews override seems to have stopped the row mixup of data/values.
- (void)layoutSubviews
{
[super layoutSubviews];
CGSize size = self.contentView.frame.size;
CGFloat mainHeight = ((size.height * 6)/10) - 6.0;
CGFloat detailHeight = ((size.height*4)/10) - 6.0;
self.mainLabel = [[UILabel alloc] initWithFrame:CGRectMake(8.0, 4.0, size.width - 16.0, mainHeight)];
self.detailLabel = [[UILabel alloc] initWithFrame:CGRectMake(8.0, 4.0+(self.mainLabel.frame.size.height)+4.0, size.width - 16.0, detailHeight)];
}

How to create a group of text fields like in the Facebook login screen?

I have a screen with a picture and a label in the top part and somewhere in the middle i want to add two textfields. I really like the way Facebook login screen looks and i would like to do something similar but that is not too easy for me, being an absolute beginner.
I am using Storyboards and the view controller for the current screen implements UIViewController.
I would like to understand how to manage it, so, any tips are apreaciated.
Thanks.
LE:This is what i have tried, but with no result:
I added a table view on the screen and i created properties for the two text fields so i can dynamically add the two text field in the 2 cells.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 2;
}
- (UITableViewCell *)tableView:(UITableView *)table cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [table dequeueReusableCellWithIdentifier:#"Cell"];
if( cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
if (indexPath.row == 0) {
self.txtUsername = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 280, 20)];
self.txtUsername .placeholder = #"Username";
self.txtUsername .autocorrectionType = UITextAutocorrectionTypeNo;
[self.txtUsername setClearButtonMode:UITextFieldViewModeWhileEditing];
cell.accessoryView = self.txtUsername ;
}
if (indexPath.row == 1) {
self.txtPassword = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 280, 20)];
self.txtPassword.placeholder = #"Password";
self.txtPassword.secureTextEntry = YES;
self.txtPassword.autocorrectionType = UITextAutocorrectionTypeNo;
[self.txtPassword setClearButtonMode:UITextFieldViewModeWhileEditing];
cell.accessoryView = self.txtPassword;
}
[cell addSubview:self.txtUsername];
[cell addSubview:self.txtPassword];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
I am not using Static cells so i figured it out the only way is to programatically add those text fields.
Should i user Static cells?
What are you are looking to do can be easy achieved with a tableView and just insert your text fields inside of your cells. Give this documentation on table views a read for a better understanding on how they work : Apple's Documentation on Table View Programming
If you are working on storyboards like stated in your description, then you will want to delete the delegate methods you have in your view controller (the code that you posted) for the table view, the app will not work this way.
Sounds like what you are trying to achieve can be done with Static cells, therefore You shouldn't use the data source methods.

UITableView GridLayout Problems with Reusable UITableViewCells

I am creating a Grid (spreadsheet) like layout for iPad app using UITableView. I got the grid part working but since I am dynamically adding UILabels to the cells the reusable portion is not working fine. Here is the code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"FundCell"];
Fund *fund = [funds objectAtIndex:[indexPath row]];
float labelWidth = 1024 / ([columnNames count] -1 );
for(NSString *columnName in columnNames)
{
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(x, 0, labelWidth, 44)];
label.backgroundColor = [UIColor clearColor];
label.text = [fund valueForKey:columnName];
x += label.bounds.size.width;
[cell addSubview:label];
}
x = 0;
return cell;
}
Result:
You're adding new labels in every reuse. You should only add the labels once, store references to them (usually as properties of a custom cell subclass) and just set the text value thereafter.
You may find it easier to define a custom cell in a xib and position your labels there, creating outlets. You can register this for reuse with the table, it will create or dequeue a cell as needed.

How do I stop a UICollectionView within A UITableViewCell go beyond bounds when more that one is initiated?

I have a UITableView that expands the height of each Cell and displays a UICollectionView when a cell is selected. It does all of the above with no errors, however, when I select one tableCell after the other and they are both expanded.
When the UICollectionView's are populated with Cells and each has a different amount of items (so James has 3 insights and Tim has 4), when I expand the TableViewCell with less items in and then try and scroll Tim's UICollectionView, it exceeds beyond the bounds. This is because when I initiate a new collection view they both take on the numberOfItemsInSection: of the most recently created UICollectionView. I want the view created to maintain the numberOfItemsInSection: it had when it was originally created rather than all the UICollectionView's adopting the most recent numberOfItemsInSection:. I hope this makes sense but I'll paste in my code for a better idea of what I mean, below is the code from the UITableViewController:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
leaderboardCell *leaderCell = (leaderboardCell *) [self.tableView cellForRowAtIndexPath:indexPath];
isSelected = ![self cellIsSelected:indexPath];
if ([self cellIsSelected:indexPath]) {
[leaderCell.collectionView removeFromSuperview];
leaderCell.collectionView = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"PostCellInformation" object:nil];
} else {
if (isSelected) {
leaderCell.collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(320, 65, 322, 200) collectionViewLayout:leaderCell.flowLayout];
[leaderCell.collectionView registerClass:[userCell class] forCellWithReuseIdentifier:#"userCellID"];
leaderCell.flowLayout = [[UICollectionViewFlowLayout alloc] init];
[leaderCell.flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
UIColor *collectionViewColour = [UIColor colorWithRed:0.17 green:0.28 blue:0.40 alpha:1.0];
UIColor *borderColour = [UIColor colorWithRed:0.37 green:0.48 blue:0.60 alpha:1.0];
[leaderCell.collectionView setBackgroundColor:collectionViewColour];
[leaderCell.collectionView.layer setBorderColor:[borderColour CGColor]];
[leaderCell.collectionView.layer setBorderWidth:1.0];
[leaderCell.collectionView setDataSource:leaderCell];
[leaderCell.collectionView setDelegate:leaderCell];
}
}
// Store cell 'selected' state keyed on indexPath
NSNumber *selectedIndex = [NSNumber numberWithBool:isSelected];
[selectedIndexes setObject:selectedIndex forKey:indexPath];
[self.tableView beginUpdates];
[self.tableView endUpdates];
leaderCell is the UITableViewCell which contains the UICollectionView. I want each UICollectionView's numberOfItemsInSection: to be applied to each one not all of them. Has anyone come across a similar problem? Thanks in Advance!
EDIT I have come to the conclusion that what I need to address to successfully achieve what I want here is to assign the dataSource to the right object,however, Im not sure what I need to assign it to... I basically need the dataSource to address each cell individually. At the moment my datasource is set to the TableViewCell which should be correct as it's assigned to each individual cell...

Resources