Horizontal UICollectionView in UITableView not scrolling - ios

In my project, I have a UITableView with different types of cells.
One of these cells contains a horizontally scrolling UICollectionView.
When I run my project, the UICollectionView is correctly populated, but I cannot scroll horizontally, clicking and dragging inside this UICollectionView only allows for me to scroll the tableview vertically.
The desired behaviour would be that a click inside the cell with the UICollectionView would allow the user to scroll horizontally, clicking in any other cell allows for vertical scrolling.
I'm assuming that I need to overwrite/pass on or disable some OnClick event in this cell however I cannot find the correct solution.
Any help pointing me in the good direction would be greatly appreciated :)
The code for creating the concerning TableViewCell looks like this.
#property(nonatomic) HorizontalCollectionViewDelegate *horizontalCollectionViewDelegate;
- (UITableViewCell *) createHorizontalScrollCell:(NSIndexPath *)indexPath tableView:(UITableView *)tableView{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:myCellIdentifier];
MyHorizontalScrollingTableCell *myHorizontalScrollingTableCell = (MyHorizontalScrollingTableCell *)cell;
UICollectionView *horizontalCollectionView = myHorizontalScrollingTableCell.myHorizontalCollectionView;
//Link collectionView to its delegate
self.horizontalCollectionViewDelegate = [[HorizontalCollectionViewDelegate alloc] init];
horizontalCollectionView.delegate = _horizontalCollectionViewDelegate;
horizontalCollectionView.dataSource = _horizontalCollectionViewDelegate;
_horizontalCollectionViewDelegate.data = myData;
//Define the cells in HorizontalCollectionView
UINib *cellNib = [UINib nibWithNibName:#"CollectionViewCell" bundle:nil];
[horizontalCollectionView registerNib:cellNib forCellWithReuseIdentifier:#"horizCell"];
//Define flow of AttachmentsCollectionView
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setItemSize:CGSizeMake(90, 90)];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
[horizontalCollectionView setCollectionViewLayout:flowLayout];
return cell;
}
EDIT: I'm using the same HorizontalCollectionViewDelegate elsewhere in my project (just not in a tableview) and over there it is working, so I assume the problem is not there.
EDIT 2: Problem solved, turns out there wasn't a problem (see answer below), will be accepting my answer in two days when I can.

Solved...
Turned out I only needed to add more content to the UICollectionView.
With 2 or 3 elements the Cells did not fill the complete view. Because the swipe animation was not showing I assumed there was an error somewhere.
However just adding more content solved this issue.

Related

IOS : UICollectionView inside UIScrollView index not incremented

Hello people of stackoverflow,
Currently working on an App where I have a user profile that looks like this
http://i.imgur.com/H1N0ouX.jpg (sorry I dont have enough reputation to post the image)
Header View is a picture of the user.
Tab View is 2 tabs, one with a collectionview, the other with a tableview.
All those views are nested inside a scrollView
My problem is that when I scroll that view (collection view height set programmaticaly depending on number of elements), the collection view's index does not increment. Only the 6 first items are loaded in in the visible cells index of the collection view.
I need to segue from the collectionview's items to the item's detail view.
How can I use the scrollView delegate to know where my collection view is at.
I've looked at those threads :
iOS 7 Collection View inside Scroll View
How to implement non-scrollable UICollectionView inside UIScrollView?
But none gave me the answer I was looking for.
I also tried looking at scrollViewDidEndDecelerating and setting my collection view scroll offset according to the scroll view offset, but I could not make it work.
Any advices?
Thanks
EDIT :
Hello and thanks for your answer,
To answer your question, I can scroll my collectionview, since it is inside a scroll view, I set my collectionview height during viewdidload (based on number of elements)
my problem is, I can click on the first 6 items , and display details (via a segue) but after that, selection is not recognized as the index is not refreshed for my collection view. I can scroll all the way to the bottom of my collection view (I scroll via the scrollView).
My collectionView has user interaction enabled checked, as I said, I can select the first 6 items, and then selection is not recognized.
I understand the UICollectionViewFlowLayout issue, but where do I write this line ? in the viewDidLoad? or in delegate funcs of CollectionView ?
If you need more information, I can copy some code or show you the layout of the view in storyboard
Thanks in advance.
EDIT 2 :
images , storyboard : layout of my view
http://i.gyazo.com/c491786507db2effc702d910020515a2.png
code, here are the datasource funcs of the collectionView
http://gyazo.com/3730caeb2b2a40fef9efec559171744f
delegate func of the collection view
http://i.gyazo.com/81fc9443b4367ecbd304e608ab0cc864.png
EDIT3:
Okay so basically this is what I want to reproduce,
tab view in the middle with multiples tabs with collection view, all this scrollable.
What I cant understand, is if I set my topView as the header of the CollectionView, I can't switch tabs like I want since its inside the header.
ViewController with TalbeView and CollectionView tabs like Google+ in IOS
Hi First of all I need more detail about your question but I am assuming that you want your UICollectionView scrollable and actually its not scrolling.
So could you check following points :-
UserEnableInteraction for collection view should be enabled.
And also check what is the value you gave for UICollectionViewFlowLayout because just consider if You have total 5 elements to show and your UICollectionViewFlowLayout size is like it can show all five items in visible cell index then it doesn't scroll so you need to increase the size of UICollectionViewFlowLayout to make it scroll.
e.g
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setItemSize:CGSizeMake(148, 148)];
And if you want then you can get the help from UIScrollViewDelegate method like
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if (!decelerate)
{
// do your job
}
}
set delegates and Datasource in .h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UITableViewDataSource , UITableViewDelegate ,
UIScrollViewDelegate , UICollectionViewDataSource , UICollectionViewDelegateFlowLayout>
You can do that .m
in ViewDidLoad:-
UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc] init];
UICollectionView *collectionView =[[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout ];
collectionView.frame = CGRectMake(5, 61, 365, 678);
collectionView.delegate = self;
collectionView.dataSource = self;
[collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"cellIdentifier"];
[self.view addSubview:collectionView];
And then Call her delegates method :-
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return [arrImages count];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
[self createCell:cell forTableview:collectionView];
[self fillCell:cell cellForRowAtIndex:indexPath];
return cell;
}
//- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
//{
// return CGSizeMake(50, 50);
//}

Prevent UITableViewCells from creating as you scroll down

I'm creating a mail screen using which visually resembles the iOS native email app. It looks like this (Both images are of the same screen. First one is the top half and the second one is the rest of it).
The difference is my mail screen has more custom fields in addition to normal To, Cc, Subjet fields.
I'm using a UITableViewController to create this. Below is a code snippet which creates a cell (For each cell it's pretty much the same).
- (UITableViewCell *)tokenTableView:(TITokenTableViewController *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil;
self.tableView.frame = CGRectMake(0,0,320,320);
UIView *contentSubview = nil;
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifierSubject];
if(!self.txtSubject) {
self.txtSubject = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
self.txtSubject.frame = CGRectMake(10, cell.frame.size.height / 2 - self.txtSubject.font.lineHeight / 2, tableView.tableView.bounds.size.width, 30);
self.txtSubject.placeholder = #"Subject";
[self setupMailData:indexPath.row];
}
contentSubview = self.txtSubject;
}
Say, I open up a draft. All the details in the input fields are filled and without changing anything, I hit send and it crashes the app. I know what's causing this. The problem is that normally the cells that are under the viewable portion of the screen gets created as you scroll down, right? But in this scenario, if I send it without scrolling down but those cells below the viewport don't exist thus it throws the error.
If I open the draft, scroll down and hit send, it works fine.
I need to know if there's a way to create all these cells at once. Even the cells that are below the viewport at first. Not depending on the user to scroll down.
I hope you have an idea about my situation. Can anyone suggest a solution?
Thank you.
follow steps:
Take uiscrollview and set scrollview frame as which you want to display.
Take uitableview as a subview of uiscrollview
set property Scrolling Enabled = NO (uncheck checkbox in .xib) of uitableview
call reloaddata method of uitableview
set tableview frame and contentsize of scrollview
tblEmail.frame = CGRectMake(yourXPos, yourYPos, yourWidth, tblEmail.contentSize.height);
scrollObj.contentSize = CGSizeMake(yourScrollWidth,tblEmail.contentSize.height+10);
so, the height of tableview is equal its contentsize. so, its create all cells at a time. and set contentsize of scrollview is equal tableview contentsize. so, the scrolling feature is worked like uitableview scrolling...
Use a Storyboard, add a UITableViewController and set the 'Content' to StaticCells.
Then you can define all the cells and their content in the Storyboard. You can even wire stuff up to IBOutlets in your UITableViewController subclass and they will all be there for you when viewDidLoad is fired ...
When using a Storyboard your code for getting the ViewController looks like:
[[UIStoryboard storyboardWithName:#"MyStoryboard" bundle:nil] instantiateInitialViewController];

UITableView - Sliding content inside each cell horizontally

This is my first native iOS app...
Exactly like the iTunes app on iOS does, by having a tableview that you can scroll vertically, and then each row, you can scroll independently horizontally. At least this is ow I imagine it to work.
how would I implement this? I imagine a view inside each tableCell that can scroll horizontally?
Can any one please shed some light on this and what I might read or try to do
You can add the scroll view into the cells content view and then just the content size property of the scroll view to whatever length you want. Here I have set the width of scroll view to 1000 and the height to 44 (which is the default size of the UITableViewCell).
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
UIScrollView *vwScroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
vwScroll.backgroundColor = [UIColor scrollViewTexturedBackgroundColor];
vwScroll.contentSize = CGSizeMake(1000, 44);
[cell.contentView addSubview:vwScroll];
return cell;
}
The only option I can think of is if you place a UIScrollView inside the UITableViewCell's view.
Note though, that this may cause problems in regard to the vertical scrolling behavior of the UITableView itself.
To achieve independently scrolling rows similar to the App Store app on iOS, one approach is to nest a Collection View inside a Table View Cell.
I wrote a Swift tutorial with step-by-step instructions on the setup, including how to wire the Collection View dataSource to the Table View Cell.
The tutorial includes a working sample project on GitHub and a link to an Objective-C tutorial.
I believe the free Sensible TableView framework provides these cells out of the box. Should give you a good head start since you're still starting out. Hope this helps.

On iOS, what is the difference between adding a subview to a UITableViewCell object "cell" vs to "cell.contentView"?

In the following code, if we do [cell addSubview: someLabel] vs [cell.contentView addSubview: someLabel], they seem to work the same. Is there any difference doing one or the other? (the custom cell in the real code is adding UIImageView and UILabel) (UIView, on the other hand, doesn't have contentView, so we don't need to add subview to its contentView. UITableViewCell is a subclass of UIView by the way)
-(UITableViewCell *) tableView:(UITableView *) tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil;
if ([tableView isEqual:self.songsTableView]){
static NSString *TableViewCellIdentifier = #"MyCells";
cell = [tableView dequeueReusableCellWithIdentifier:TableViewCellIdentifier];
if (cell == nil){
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:TableViewCellIdentifier];
}
// ... some code to create a UILabel (not shown here)
[cell addSubview: someLabel]; // vs using [cell.contentView addSubView: ...]
I believe If I am not wrong, the contentView is a subview of UITableViewCell.
If you look at this page here, you can see there are actually 3 subviews in a UITableViewCell
I think by default, the Editing Control is hidden until you enter edit mode for a table in which case, the Editing Control appears (the minus button left of each row) and your contentView gets resized and pushed to the right. This is probably what gives the "proper animation" effect mentioned by the other answer.
To test the difference, try adding a subview such as UILabel with text, to the cell rather than the cell.contentView. When you add it to cell rather than cell.contentView and you enter edit mode for your table, I believe your UILabel will not resize, you will see the edit button ontop/below the minus sign button.
Placing your views in the contentView affects proper animation in and out of edit mode. Place all of your subviews in contentView when you're not subclassing, which should be all of the time unless you know what you're doing.

UITableView separator lines disappear between cells on scroll

Problem: The separator between cells in a table view appear only for those cells shown when the view loads, and only at load time. When the tableview is scrolled down, the cells scrolled into view show no separator between them, then when the tableview is scrolled back up, the initial cells show no separator.
Details: I've got a UITableView to which I'm adding standard UITableViewCells. These cells are created with initWithFrame, frame height = 90px. I'm adding a custom view created from a nib to this cell's view, height = 90px. The cell height is specified at 90px in tableView:heightForRowAtIndexPath:.
Has anyone experienced this behavior?
I had a feeling the solution to this would be simple...
I made the height of my cells 91px and the separator lines appear as they should on scroll.
I couldn't use Douglas's solution because my tables have a huge amount of cells and would become pretty much unusable on older phone. Reusing cells is key for performance.
BUT, I managed to workaround the problem using a transparent separator and adding my own in the contentView of the cell, as follows:
yourTable.separatorColor = [UIColor clearColor];
separatorView.frame = FactRectMake(0, rowHeight-1, appFrame.size.width, 0.2);
I had the same problem, but I used a different solution.
My separators were disappearing because I was clearing my cell using:
for (UIView *eachView in self.subviews) {
[eachView removeFromSuperview];
}
This removed the separator view as well!
Instead, I assigned a tag for each of my customs views (three labels) right before adding them to the sub view:
tempFirstNameLabel.tag = 100;
self.firstNameLabel = tempFirstNameLabel;
[self addSubview:self.firstNameLabel];
Then when I cleared the cell, I just removed those views:
for (int i = 100; i<103; i++) {
UIView *eachView = [self viewWithTag:i];
[eachView removeFromSuperview];
}
Hope this helps!
This also avoids the memory management issues that #Douglas Smith's solution posed.
You should set separator none and then single line again
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// it is a bug in iOS 7
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;

Resources