I am creating a UICollectionViewController programmatically. No, I don't want to use IB and Storyboards like every tutorial out there. I just want to use plain code.
Here is what I have in my viewDidLoad:
// UICollectionView
UICollectionViewFlowLayout *aFlowLayout = [[UICollectionViewFlowLayout alloc] init];
[aFlowLayout setItemSize:CGSizeMake(200, 140)];
[aFlowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:aFlowLayout];
[self.collectionView setDelegate:self];
[self.collectionView setDataSource:self];
self.collectionView.backgroundColor = [UIColor clearColor];
[self.collectionView setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth];
[self.collectionView registerClass:[PUCImageGridCell class] forCellWithReuseIdentifier:CollectionViewCellIdentifier];
I have implemented the required delegate methods and I still get this error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'UICollectionView must be initialized with a non-nil layout parameter'
This is what I use to initialize a UICollectionViewController:
- (id)initWithCollectionViewLayout:(UICollectionViewLayout *)layout
You do not need to instantiate the collectionView the controller will do it for you. Set the frame after calling this or you can override and set the frame inside:
- (id)initWithCollectionViewLayout:(UICollectionViewLayout *)layout{
self = [super initWithCollectionViewLayout:layout];
if (self) {
// additional setup here if required.
}
return self;
}
I prefer to use the autolayout constraints.
Related
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"
I'm trying to add UICollectionView to my app with auto layout, but it keeps crashing. This is my code:
_collection = [[UICollectionView alloc] init];
[_collection registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:kCellId];
_collection.collectionViewLayout = [DXSelectionViewLayout new];
_collection.translatesAutoresizingMaskIntoConstraints = NO;
_collection.dataSource = self;
_collection.hidden = YES;
Error:
2014-05-14 16:16:09.978 Sportlinked[4712:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'UICollectionView must be initialized with a non-nil layout parameter'
For UICollectionViews you need to use
- (id)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout
as initializer - instead of the plain
- (id)init
method.
(The collection view must be initialized with a layout.)
So practically replace your first line of code with something like this in order to create a collection view properly:
CGRect frame = CGRectMake(0, 0, 200, 200); // sample frame
UICollectionViewFlowLayout *layout= [UICollectionViewFlowLayout new]; // standard flow layout
_collection = [[UICollectionView alloc] initWithFrame:frame collectionViewLayout:layout];
I think you can find your answer there :
Creating a UICollectionView programmatically
UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc] init];
_collectionView=[[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];
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];
...
}
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.
I'm trying the following in Xcode 4.3.2. I've created a single view application. My ViewController implements UITableViewDelegate, UITableViewDataSource.
In ViewController.m:
UITableView *tv = [[UITableView alloc] initWithFrame:CGRectMake(0, 10, 120, 100)
style:UITableViewStylePlain];
tv.delegate = self;
tv.dataSource = self;
[self.view addSubview:tv];
I implemented numberOfSectionsInTableView, numberOfRowsInSection, cellForRowAtIndexPath and didSelectRowAtIndexPath. It works fine, and displays "welcome" in two rows. But If i place the UITableView creation in the init, then it is not working.
- (id)init
{
self = [super init];
if (self) {
UITableView *tv = [[UITableView alloc] initWithFrame:
CGRectMake(0, 10, 120, 100) style:UITableViewStylePlain];
tv.delegate = self;
tv.dataSource = self;
[self.view addSubview:tv];
}
return self;
}
Two things:
if you're loading from a xib file or storyboard, the initializer used is initWithCoder:.
the view controller's views are not loaded until they're needed, which means viewDidLoad: rather than any init... method. (Though, viewDidLoad: is triggered by a reference to the view property.)