Collectionview cell to open new view - objective-c

I have a collection view with 6 cells in it how do I have each cell open a new viewcontroller when clicked?

In order to achieve your goal you need to edit 2 files:
In the Storyboard you need to add a cell view for each static cell in your Collection View. Just drag as many UICollectionViewCells onto the Collection View. For each cell you need to define a unique reusable identifier (meaning a name like CellType1) in the Attributes Inspector when a cell is selected in the Storyboard's Document Outline. And then control-drag from each cell to the desired target view controller to create a Push segue (provided that your collection view is associated with a UINavigationController).
Create a subclass of UICollectionViewController and assign it in the Storyboard's as the Collection View Controller's class (see the Identity Inspector).
In your UICollectionViewController subclass implement the following methods:
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
// Enter the number of static cells that are present in the Storyboard's collection view:
return 3;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
// Enter the reusable identifiers that are defined for each cell in the Storyboard's collection view:
NSArray *cellIdentifiers = #[#"CellType1", #"CellType2", #"CellType3"];
NSInteger cellIdentifierIndex = indexPath.item;
// Make one identifier the default cell for edge cases (we use CellType1 here):
if (cellIdentifierIndex >= cellIdentifiers.count) cellIdentifierIndex = 0;
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifiers[cellIdentifierIndex] forIndexPath:indexPath];
// Configure the cell …
return cell;
}
I've created a demo app to show a full implementation: https://github.com/widescape/StaticCollectionViewCells

Related

NSCollectionViewItem does not display custom view

I have a subclass of NSCollectionViewItem, called ZMSDKThumbnailCollectionViewItem. Using this, I want to display a custom view represented by ZMSDKThumbnailVideoItemView.
ZMSDKThumbnailCollectionViewItem is represented by a XIB file. This contains exactly one NSView which's class is set (using Identity Inspector) to ZMSDKThumbnailVideoItemView.
#interface ZMSDKThumbnailCollectionViewItem : NSCollectionViewItem
#property (assign) IBOutlet ZMSDKThumbnailVideoItemView *videoItemView;
#end
In my NSCollectionViewDataSource I create items like this:
- (NSCollectionViewItem *)collectionView:(NSCollectionView *)collectionView itemForRepresentedObjectAtIndexPath:(NSIndexPath *)indexPath
{
ZMSDKThumbnailCollectionViewItem* item = [collectionView makeItemWithIdentifier:#"ZMSDKThumbnailCollectionViewItem" forIndexPath:indexPath];
ZMSDKThumbnailVideoItemView* thumbnailView = [_thumbnailVideoArray objectAtIndex:indexPath.item];
// IBOutlet videoItemView
item.videoItemView = thumbnailView;
return item;
}
Problem: although _thumbnailVideoArray contains elements, nothing is displayed in the collection view.
When I modify ZMSDKThumbnailCollectionViewItem so that it contains a NSLabel instead of a ZMSDKThumbnailVideoItemView, the items are being displayed properly.
Question: in which manner do I have to create a NSCollectionViewItem to display a custom view? Is it correct to set the class of the containing view in the XIB file to ZMSDKThumbnailVideoItemView like I did?
After all I found the solution.
Instead of changing the class of the item's view, one has to add a sub view to the item's view:
- (NSCollectionViewItem *)collectionView:(NSCollectionView *)collectionView itemForRepresentedObjectAtIndexPath:(NSIndexPath *)indexPath
{
ZMSDKThumbnailCollectionViewItem* item = [collectionView makeItemWithIdentifier:#"ZMSDKThumbnailCollectionViewItem" forIndexPath:indexPath];
ZoomSDKVideoElement* thumbnailView = [_videoArray objectAtIndex:indexPath.item];
[item.view addSubview:[thumbnailView getVideoView]];
return item;
}

UITableviewCell height according to In side another UITableviewCell height

{
MainTitle 1
{
Subtitle 1
( item 1
item 2
item 3 )
},
{
MainTitle 2
{
Subtitle 2
( item 1
item 2
item 3)
}
}
There is JSON data format that I have to display in UITableview. The data is restaurant's menu. I create Table 1 for MainTitle display and Table 1 cell inside another UITableview Table 2 for Subtitle and item Subtitle set as header and item as row.
Tableview cell height is dynamic so I set it UITableViewAutomaticDimension for both tableview. Table 1 cell height is set according to inside it Table 2 height. Table 2 is not scrollable, it's height is according to content height.
So, I want to set Table 1 cell height after loading Table 2 all data.
You could use proper UITableView sections and rows. Add "MainTitle" as Table Section and MainTitle's "Items" as Section Rows.
I'd recommend using one single tableview as mentioned by #trungduc and #Raj D
You should be able to use a custom tableview cell to layout the items the way you want, and you can always use buttons for items that need to be clickable (i.e. if you need to click on the menu items and show another view controller).
Here's a basic mockup of what I mean:
You'll want to use a stack view within the cell and then dynamically generate the menu items based off your backing data model (this should allow it to obtain the correct intrinsic content size for UITableViewAutomaticDimension to size the cells correctly).
Here's an example of what I mean by dynamically adding the menu items when setting the submenu item of the custom cell:
- (void)setupMenuItemsStack:(NSArray <RPMenuItem *> *)menuItems {
for (UIView *subview in self.menuItemsStack.arrangedSubviews) {
[NSLayoutConstraint deactivateConstraints:subview.constraints];
[subview removeFromSuperview];
}
for (RPMenuItem *menuItem in menuItems) {
UIButton *menuItemButton = [UIButton buttonWithType:UIButtonTypeSystem];
[menuItemButton addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[menuItemButton setTitle:menuItem.title forState:UIControlStateNormal];
[self.menuItemsStack addArrangedSubview:menuItemButton];
}
}
Depending on how you're structuring your model, the tableview methods would look something along these lines:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return self.menuList.menus.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [[self.menuList.menus objectAtIndex:section] subMenus].count;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [[self.menuList.menus objectAtIndex:section] title];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
RPMenuTableViewCell *cell = (RPMenuTableViewCell *)[tableView dequeueReusableCellWithIdentifier:#"RPMenuCell" forIndexPath:indexPath];
RPSubMenu *subMenu = [[[self.menuList.menus objectAtIndex:indexPath.section] subMenus] objectAtIndex:indexPath.row];
[cell setSubMenu:subMenu];
return cell;
}
Where the menu list is a top level list of menus and it cascades down from there (i.e. menu list holds an array of menus, menus hold an array of submenus, submenus hold an array of menu items).
#property (strong, nullable) RPMenuList *menuList;
Adding the ability to expand and contract (accordion style) to show the menu items would probably be a nice touch as well:

custom cell for UICollectionView

I need to create an app which has a list of items, each item has an image a title, a subtitle a price and a description and I need 2 items per line (so I can't use a UITableView)
Is it possible to use a UICollectionView with custom cell in order to have the result I want or should I search another solution?
The custom cell layout should be like this:
You totally can !
Just create your custom UICollectionViewCell, then go in the "cellForItemAtIndexPath" method in order to use it.
Hope this help :)
1, create a xib file in the subclass of UIcollectionViewCell
2, register your xib in controller's viewdidload fun
[mCollectionView registerNib:[UINib nibWithNibName:#"CollectionViewCell" bundle:nil] forCellWithReuseIdentifier:#"Cell"];
3,
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;
{
CollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
return cell;
}
You can definitely customise your UICollectionView's Cell. But you will have to do following steps as well:
Register your Custom Cell to your collection view :
[self.collectionView registerClass:[YourCustomClass class]
forCellWithReuseIdentifier:#"CustomCell"];
Secondly, inside your method : cellForItemAtIndexPath, you will have to call custom cell like this (as you do in tableView's custom cell too):
YourCustomClass *cell = (YourCustomClass *)[collectionView
dequeueReusableCellWithReuseIdentifier:#"CustomCell" forIndexPath:indexPath];
Here is a tutorial to make custom UICollectionView Cell

UICollectionViewCell reflection - appropriate time for taking the cells' snapshot image

I'd like to add reflection to my collection view's cells. I have the method that creates a reflection, but I don't know the correct time to create the snapshot.
I have tried doing it in the collection view's -viewWillAppear:, but the cell's contentView has zero-sized frames for its subviews. I have also tried taking the snapshot during the cell's -layoutSubviews, but the subview frames are still 0.
At what point is the cell's layout set so I can take the snapshot?
The snapshot should be taken after the cell has been added to the collection view, and after the cell has been dequeued by the collection view data source. This ensures the snapshot will be up to date, containing the cell's content view at the correct moment (when it's about to be added to the collection view, and after it has just been dequeued):
CollectionViewCell.m
- (void)didMoveToSuperview {
[self updateSnapshotImage];
}
CollectionViewController.m
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;
{
CollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cellID" forIndexPath:indexPath];
[cell updateSnapshotImage];
return cell;
}

How to save state of UICollectionViewCell

Please help me, how can I save state of UICollectionViewCell. For example: I have cells with UIWebView and when I dequeueReusableCellWithReuseIdentifier:forIndexPath: returned wrong cell, not for this indexPath and after it UIWebView content will reloaded for correct indexPath with twitches. Thanks!
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
NewsCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"NEWS_CELL" forIndexPath:indexPath];
if (!cell.isShowed) { // I just added boolean property
cell.isShowed = YES;
/*** some init actions ***/
}
return cell;
}
If I use this method, cells with cell.isShowed == YES return on wrong indexPath. But if I not use cell.isShowed content of UIWebView will reloaded in every showing cell
Sorry for my english :)
See what Apple's UIWebView Class Reference say:
Important: You should not embed UIWebView or UITableView objects in
UIScrollView objects. If you do so, unexpected behavior can result
because touch events for the two objects can be mixed up and wrongly
handled.
But UICollectionView inherits from UIScrollView. So you need to redesign your architecture.