UICollectionView created programmatically doesn't scroll - ios

I'm making a horizontal picker by using a UICollectionView. It's simple enough: A UIView with a UICollectionView created programmatically, using UICollectionViewFlowLayout with one section, scrolling set to horizontal. It appears onscreen, complete with the correct data in the correct cells. But it doesn't scroll---in fact it doesn't respond to user interaction at all.
Here's the initializer for the view:
- (id)initWithFrame:(CGRect)frame andItemData:(NSArray *)itemData
{
self = [super initWithFrame:frame];
if (self) {
_itemData = itemData;
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
[flowLayout setItemSize:CGSizeMake(kCellWidth, kCellHeight)];
[flowLayout setMinimumInteritemSpacing:0.f];
[flowLayout setMinimumLineSpacing:0.f];
_collectionView = [[UICollectionView alloc] initWithFrame:[self frame] collectionViewLayout:flowLayout];
[_collectionView setDataSource:self];
[_collectionView setDelegate:self];
[_collectionView setBounces:NO];
[_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"HorizontalPickerCell"];
[self addSubview:_collectionView];
}
return self;
}
I tried programmatically setting UserInteractionEnabled to YES, but that didn't make any difference (nor should it have, since UserInteractionEnabled is set to YES by default). FWIW, the collection view uses standard UICollectionViewCells with UILabels added to their contentViews as subviews.
Any thought as to why this isn't scrolling? Any and all help much appreciated.

Ok, this turned out to be both dumb on my part and easy to fix. I set the frame of the collection view to its parent view's frame rather than its bounds. This caused all sorts of autolayout issues and resulted in touch events simply not registering. All fixed now.

Related

Use CollectionViewLayout of a CollectionView created in XIB?

I've got a XIB named 'ImageViewController.xib" which contains a collection view. I've set up my desired collection view layout on this collection view inside the xib.
When trying to run my app I get the error message:
'UICollectionView must be initialized with a non-nil layout parameter'
I'm using this inside ImageViewController:
-(id) initWithImages:(NSArray *)imagesUrls
{
if (self = [super initWithCollectionViewLayout:self.collectionViewLayout]) {
self.imageUrls = [[NSArray alloc] initWithArray:imagesUrls];
}
[self.collectionView registerNib:[UINib nibWithNibName:#"ImageCell" bundle:nil] forCellWithReuseIdentifier:#"Cell"];
return self;
}
I just want to use the layout I have set up in the XIB and not make one programatically.
You can add the collectionViewLayout to the collectionView in the viewDidLoad.
Create your collectionViewLayout eg:
UICollectionViewFlowLayout * flowLayout = [[UICollectionViewFlowLayout alloc] init];
flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
flowLayout.minimumLineSpacing = 5;
flowLayout.minimumInteritemSpacing = 5;
flowLayout.sectionInset = UIEdgeInsetsMake(5, 5, 5, 5);
Then we set it as the flow layout of the collectionView
_collectionView.collectionViewLayout = flowLayout;
I found this answer on a good tutorial which can be found here
Hopefully this helps
Try adding this in your view did Load method act its what I did to get rid of it
UICollectionViewFlowLayout* flowLayout = [[UICollectionViewFlowLayout alloc]init];
flowLayout.itemSize = CGSizeMake(100, 100);
[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"MyCell"];
this worked for me…you see what the error is telling you that the layout should not be nil, the Layout's frame is set relative to its superview, the layout is passed to the parent class during initialization, check if your CollectionViewLayout is "Null"

Horizontal UICollectionView with UIRefreshControl issue

I have horizontal UICollectionView with UIRefreshControl:
self.refreshControlMain = [[UIRefreshControl alloc] init];
//self.refreshControlMain.tintColor = [UIColor grayColor];
[self.refreshControlMain addTarget:self action:#selector(refershControlAction) forControlEvents:UIControlEventValueChanged];
[self.collectionViewMain addSubview:self.refreshControlMain];
self.collectionViewMain.alwaysBounceVertical = YES;
self.collectionViewMain.pagingEnabled = YES;
self.collectionViewMain.showsHorizontalScrollIndicator = NO;
self.collectionViewMain.scrollEnabled = NO;
//Because user can't scroll horizontally (he needs to press next button)
But this code doesn't work, because I can't drag it vertically.
The only option I found is to set self.collectionViewMain.scrollEnabled = YES; (and in this case I can drag it vertically, so that refresh control appears), but in this case user is able to scroll horizontally (but user shouldn't be able to do that).
Is there any option to use refresh control in my situation?
update:
I don't need horisontal refresh control. I have horisontal collectionview, but I need vertical refresh control. if I put "self.collectionViewMain.scrollEnabled = YES" in my code, it works. but I need user not be able to scroll himself.
UIRefreshControl does not support horizontal use natively.
There are various solutions whereby it has been extended for horizontal use.
Check out this link.
Or as per this answer you could use a UITableViewController that is rotated 90 degrees.
Add [self.view setTransform:CGAffineTransformMakeRotation(-M_PI / 2)]; in the UITableViewController class during setup.
Example using UITableView (and not UITableViewController):
table_ = [[UITableView alloc] initWithFrame:self.bounds];
[table_ setDelegate:self];
[table_ setDataSource:self];
[table_ registerClass:[UITableViewCell class] forCellReuseIdentifier:#"Cell"];
[table_ setTransform:CGAffineTransformMakeRotation(-M_PI / 2)];
UIRefreshControl *ctrl = [[UIRefreshControl alloc] init];
[ctrl setBackgroundColor:[UIColor yellowColor]];
[table_ addSubview:ctrl];
[self addSubview:table_];
Make sure to remember to rotate the content back again in the opposite direction!

UITableView subclass with default style grouped

I have no clue how can I set grouped style as default to UITableView subclass. My goal is to get grouped TableView (ofc) but by something like that.
TableSubclass *myView = (TableSubclass*)some.other.view
Is this possible? I will be greatful for any advice.
UPDATE
I have ios 6 app with custom UITabBar and custom more section.
My "custom" code
- (void)viewDidLoad
{
[super viewDidLoad];
firstUse=true;
UINavigationController *moreController = self.moreNavigationController;
moreController.navigationBar.barStyle = UIBarStyleBlackOpaque;
self.moreNavigationController.delegate = self;
if ([moreController.topViewController.view isKindOfClass:[UITableView class]])
{
UITableView *view = (UITableView *)moreController.topViewController.view;
view = [view initWithFrame:view.frame style:UITableViewStyleGrouped];
UIView* bview = [[UIView alloc] init];
bview.backgroundColor = [UIColor blackColor];
[view setBackgroundView:bview];
moreTableViewDataSource = [[NXMoreTableViewDataSource alloc] initWithDataSource:view.dataSource];
view.dataSource = moreTableViewDataSource;
}
}
It's working great under 6 but under 7 UITableView don't respond but when I remove
[view initWithFrame:view.frame style:UITableViewStyleGrouped];
It respond again but I lose grouped style.
Are you sure that the table view is not yet configured?
from UITableView Class Reference
When you create a UITableView instance you must specify a table style,
and this style cannot be changed
Have a look how to create and configure UITableView.
Generally you use UITableViewController and then in:
- (void)loadView
{
UITableView *tableView =
[[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]
style:UITableViewStylePlain];
...
}

UICollectionview isn't loading cells when layout is horizontal until view frame is large enough

All of my delegate are hooked up and called for a vertical layout object. In horizontal mode, for some reason the only delegate called is numberofcellsincollectionview (which returns correct number) - cellforitematindexpath isn't called unless I increase the size of the collectionview frame. when it is large enough cellforitematindexpath is called. This strange behavior only happens when the collectionview layout is in horizontal mode. In vertical mode not getting this behavior. (also this strange behavior only started in iOS7 - don't know if there is a connection)
horizontal layout code
-(UICollectionViewFlowLayout *)getFilmStripLayout
{
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
[flowLayout setSectionInset:UIEdgeInsetsMake(0, 0, 0, 0)];
CGSize s = CGSizeMake(self.frame.size.height,self.frame.size.height);
[flowLayout setItemSize:s];
return flowLayout;
}
View controller containing view
-(UIThumbnailGalleryView *)gallery
{
if (_gallery == nil)
{
CGRect r = CGRectInset(self.filmStripRect, 0, -20); // started with inset 0,0 , increased the size and then the delegates are called.
_gallery = [[UIThumbnailGalleryView alloc] init2WithFrame:r]; // custom initializer testing layouts
[_gallery setBackgroundColor:[UIColor clearColor]];
[_gallery setBackgroundColor:[UIColor purpleColor]]; // setting colors in order to see the placement
_gallery.layer.borderColor = [UIColor orangeColor].CGColor;
_gallery.layer.borderWidth = 3;
_gallery.dataSource = self;
_gallery.delegate = self;
[_gallery setInToggleMode:YES];
}
return _gallery;
}

How do I get a UITableView to autoresize?

I have a couple of side-by-side UITableViews in a UIView, and I would like to get the whole thing to autoresize. I have a UIView In my init() method am doing:
// I don't know how big frontBack should be, so I'd like it to autosize
UIView *frontBack = [[UIView alloc] initWithFrame:CGRectZero];
frontBack.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
UITableView *table = [[UITableView alloc]
initWithFrame:CGRectMake(0, 0, r.size.width / 2, height) style:UITableViewStyleGrouped];
table.autoresizingMask = UIViewAutoresizingFlexibleHeight;
table.dataSource = model1;
[table reloadData];
[frontBack addSubview:table];
... (add second table similarly, except with model2)
...
controller.view = frontBack;
This does not work. The tables are 'height' pixels tall (which is smaller than what they need; the text is cut off).
I've tried several ways of getting the UITableViews to resize, with no luck
// contentSize is correct, but frame size does not change
[table reloadData];
table.frame.size.height = table.contentSize.height;
// contentSize is correct, but bounds does not change
[table reloadData];
table.bounds.size.height = table.contentSize.height;
// Nothing appears to change
[table setNeedsLayout];
[table layoutIfNeeded];
// Again, no change
[table sizeToFit];
I assume I am missing something basic here, but I'd be grateful if someone could point out what it is.
table.bounds.size.height = table.contentSize.height;
This is a read-only property, you need to set the frame again.
Also, Are you sure your containing UIView isn't cutting off the table content? You should resize it as well.

Resources