Can not get UICollectionView to show up - interface-builder

I have added a UICollectionView to a UIViewController, but it does not show up, why? I can see only the black background. Labels textcolor is white.
UPDATE
I had to implement the following UICollectionViewDataSource methods. The lesson that UICollectionView can not design via static cells, like UITableView, only via Dynamic Prototypes.
func collectionView(collectionView: UICollectionView!,
numberOfItemsInSection section: Int) -> Int
{
return 5
}
func collectionView(collectionView: UICollectionView!,
cellForItemAtIndexPath indexPath: NSIndexPath!) -> UICollectionViewCell!
{
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath)
return cell as UICollectionViewCell
}

Looks like you not implemented CollectionView delegate methods.
I would like to suggest, you have to implement UICollectionView delegate methods.
Those are -
#pragma mark - UICollectionViewDataSource
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return "number of items";
}
// This method return the object of collectionViewCell.Your collectionviewcell has label object.
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cell" forIndexPath:indexPath];
return cell;
}
// Perform operation on selection of cell
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1; // returns number of section
}
#pragma mark - UICollectionViewFlowDelegate
// Returns size of Cell
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return CGSizeMake(80, 60);
}
// Space between cells
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(2, 5, 2, 5);
}
Don't forget to link delegate to xib file.
After implementing those methods you can able to see those Cell's on device or simulator.

Related

Animating a UICollectionViewCell: Scroll To And Resize At The Same Time

I'm trying to get a UICollectionViewCell to do an animated resize and at the same time have the collection view scroll the cell to the top of the collection view's viewport.
When I do
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
[self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionTop animated:YES];
[collectionView performBatchUpdates:nil completion:nil];
}
with
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:indexPath];
if (cell.isSelected) {
return self.collectionView.frame.size;
}
else {
return CGSizeMake(300, 100);
}
}
the scroll happens before the resize animation.
And if I call scrollToItemAtIndexPath inside of performBatchUpdates like
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
[collectionView performBatchUpdates:^{
[self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionTop animated:YES];
} completion:nil];
}
it doesn't work most of the time.
Thanks!
-Eric
The best way to achieve an effect like this is to simply subclass UICollectionViewFlowLayout and tweak cell layout attributes based on the selected cell.

View-Based NSTableView in Swift - How to

I have a NSTableView whose cells are view-based.
DataSource & Delegate are connected, but I'm not able to display the cell's textField string value.
This is the code in Objective-C, working:
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
return 10;
}
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
NSTableCellView *cell = [tableView makeViewWithIdentifier:#"List" owner:self];
[cella.textField setStringValue:"Hey, this is a cell"];
return cell;
}
And here is my code in Swift, not working :
func numberOfRowsInTableView(aTableView: NSTableView!) -> Int
{
return 10 //Casual number
}
func tableView(tableView: NSTableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> NSTableCellView! {
var cell = tableView.makeViewWithIdentifier("List", owner: self) as NSTableCellView!
// setup cell without force unwrapping it
cell.textField.stringValue = "Hey, this is a cell"
println("Method called") //Never printed
return cell
}
This is the result: (table on right side of image)
Note that the comment //setup cell without force unwrapping it makes no sense, I forgot to delete it.
What I am missing ?
Edit: I tried even the following with no success:
func numberOfRowsInTableView(aTableView: NSTableView!) -> Int
{
return 10
}
func tableView(tableView: NSTableView!, objectValueForTableColumn tableColumn: NSTableColumn!, row: Int) -> AnyObject
{
var cell = tableView.makeViewWithIdentifier("List", owner: self) as NSTableCellView
cell.textField.stringValue = "Hey this is a cell"
return cell;
}
Thank you all.
Alberto
After hours of search, I discovered this method that works !
func tableView(tableView: NSTableView, viewForTableColumn: NSTableColumn, row: Int) -> NSView
{
var cell = tableView.makeViewWithIdentifier("List", owner: self) as NSTableCellView
cell.textField.stringValue = "Hey, this is a cell"
return cell;
}
I see that you found your answer your self but from what I can see your clue was in the Return Value of Objective -C delegate.
- (NSView *)tableView:...
The return value is a NSView.
But you should look at the Swift/Objective -c documentaion.
From the Docs:
Providing Views for Rows and Columns
tableView:viewForTableColumn:row:
Asks the delegate for a view to display the specified row and column.
Declaration
SWIFT
#optional func tableView(_ tableView: NSTableView!,
viewForTableColumn tableColumn: NSTableColumn!,
row row: Int) -> NSView!
OBJECTIVE-C
- (NSView *)tableView:(NSTableView *)tableView
viewForTableColumn:(NSTableColumn *)tableColumn
row:(NSInteger)row
Note the -> NSView! in the swift code also.
The new docs allow you to see the code for Swift and Objective -c side by side or one or the other. You can use a selection tab at the top of the documentation to choose.
It also looks like your code should include the "!" for optionals
If you change the content mode of the table view from view based to cell based the method is called.
This beat me up for an hour. Works with Swift 2.2, probably won't work for earlier or later versions:
let cell = tableView.makeViewWithIdentifier(myid!, owner: nil) // You can't cast this with as! like they want you to
if let mycell = cell as? NSTableCellView {
mycell.textField?.stringValue = text
return mycell
}

UICollectionView inside UIView

I am trying to implement a UICollectionView inside a UIView, but I cant find out how to do it. There is a lot of tutorials on how to use UICollectionView with a UICollectionViewController, but not how to implement one in a regular View.
How do you do that?
1) Drag a UICollectionView into your UIView and size it appropriately.
2) Create a property which is also an IBOutlet in your .h file for the collection view:
#property (nonatomic, retain) IBOutlet UICollectionView *myCollectionView;
3) Again in your .h file declare your delegates, so now your .h should look somethng like this:
#interface UtaQuickView : UIViewController <UICollectionViewDataSource, UICollectionViewDelegate> {
}
#property (nonatomic, retain) IBOutlet UICollectionView *myCollectionView;
4) Connect your myCollectionView IBOutlet in your storyboard.
5) (optional) If you're targeting anything older than iOS6 synthesize your myCollectionView property. If you're targeting iOS6, it will auto-synthesize it for you. This goes for all properties, not just UICollectionViews. So in iOS6, you don't need to #synthesize myCollectionView = _myCollectionView at all. You can just use _mycollectionview wherever you need to access the property.
6) In your .m file viewDidLoad, set your delegate and dataSource.
_myCollectionView.delegate = self;
_myCollectionView.dataSource = self;
7) Implement the required dataSource methods:
#pragma mark - UICollectionView DataSource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
From there you can implement as many or as little of the UICollectionViewDelegate methods as you need. However, 2 are required according to the documentation:
#pragma mark - UICollectionViewDelegate
- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath
- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingSupplementaryView:(UICollectionReusableView *)view forElementOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath
It's important to note that you can substitute <UICollectionViewDelegateFlowLayout> for <UICollectionViewDelegate> and still have access to all of the methods in <UICollectionViewDelegate> because <UICollectionViewDelegateFlowLayout> is a subclass of <UICollectionViewDelegate>.
UICollectionViewDataSource Protocol Documentation
UICollectionViewDelegate Protocol Documentation
And the Swift version
Drag a UICollectionView into your UIView and size it appropriately.
Modify your UIViewController to extend UICollectionViewDataSource and UICollectionViewDelegate
Implement the required functions
Control-Drag from your storyboard to the class to create an outlet 'collectionView'
In the viewDidLoad() wire up the delegate and datasource to self
collectionView.delegate = self and collectionView.dataSource = self
It should end up looking like this:
class CustomerViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate
{
#IBOutlet weak var collectionView: UICollectionView!
override func viewDidLoad() {
collectionView.delegate = self
collectionView.dataSource = self
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
}
func collectionView(collectionView: UICollectionView, didEndDisplayingCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
}
func collectionView(collectionView: UICollectionView, didEndDisplayingSupplementaryView view: UICollectionReusableView, forElementOfKind elementKind: String, atIndexPath indexPath: NSIndexPath) {
}
}
Drag a UICollectionView into your UIView and size it appropriately.
Create a property which is also an IBOutlet in your .h file for the collection view:
#property (nonatomic, retain) IBOutlet UICollectionView *myCollectionView;
in UIView first you need to declare your UICollectionView cell in -(void)awakeFromNib
[myCollectionView registerNib:[UINib nibWithNibName:#"nib file of collectionView cell" bundle:nil] forCellWithReuseIdentifier:#"identifier"];
then
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
custom class *cell1=[collectionView dequeueReusableCellWithReuseIdentifier:#"identifier" forIndexPath:indexPath];
return cell1;
}
Drag uiviewcontroller to the stroryboard.
Create the new class file for the new uiviewcontoller
Set the newly created class to our viewcontroller. And add protocol methods to the .h file. -UICollectionViewDelegate,UICollectionViewDataSource
Drag uicollectionview to the viewcontroller, by default there will be a uicollectionviewcell with the collectionview.
Create new class for the cell customisation as the subclass of the uicollectionviewcell and set the class to the cell in the identity inspector. Also set reuse identifier in the attributes inspector, the name we should specify to identify the uicollectionviewcell. Say cell here.
Drag and drop an imageview(can be anything as your wish) inside the uicollectionviewcell, size it to fit within.
Set an image with the imageview(this image will be shown repeatedly with the collectionview).
Set the delegate and datasource with the uicollectionview to the corresponding viewcontroller.
Set datasource methods - numberOfItemsInSection and cellForItemAtIndexPath.
Return the required cell count with the numberOfItemsInSection method. Say 10 here.
Return the cell to display with the cellForItemAtIndexPath.
NSString * identifier = #"cell";
CollectionViewCellForDay * cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
return cell;
By now, you should be able to have a visual of a 10 cell collection view :)

cellForRowAtIndexPath text not displaying in cell

Have a table view with three rows, but the text in the cellForRowAtIndexPath is not displaying in the screen.
Any idea what's wrong?
Here is the code
AllListsViewController.m
#import "AllListsViewController.h"
#interface AllListsViewController ()
#end
#implementation AllListsViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 3;
}
- (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];
}
cell.textLabel.text = [NSString stringWithFormat:#"List %d", indexPath.row];
return cell;
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"ShowChecklist" sender:nil];
}
#end
There are a lot of things that you should do. The first one being conforming to the UITableViewDelegate and UITableViewDataSource protocols (using the <Protocol_Name_One, Protocol_Name_Two> syntax). Then you have to call (in your viewDidLoad method):
[theTableView setDelegate:self];
[theTableView setDataSource:self];

Adding cells to table view (UITableView) in XCode

I'm new to X-Code and have just started working on my first app. I'm using Storyboards. To the Navigation Controller scene I've added a MasterViewController with two cells, which leads to two DetailViewControllers (Detail1 & Detail 2).
Number of Columns = 1
Number of rows in columns = 2
I've added a Reuse Indicator for the cells in the attributes inspector, and made the connection in the storyboard.
But when I run the app, I can only see the first cell x2.
When I look in the MasterViewController.m I can see the code for the first cell, but I don't understand how to insert the second cell etc!
I know the solution is easy and I've been looking for the answer for 3 days now, I feel stupid but I really need some help now,,
Can someone help me understand how to add more cells in the code, and maybe understand the Table View Code a bit more?
This is the code for the table view so far:
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return 2;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Formal";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
return cell;
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath][withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
*/
}
#end
Lets say you have an array called arr.
Then you have to return the number of objects in the array when numberOfRowsInSection gets called.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [arr count];
}
Your cellForRowAtIndexPath delegate method should look like this to print out the strings in the array.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Formal";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
cell.textLabel.text = [arr objectAtIndex:indexPath.row];
return cell;
}
Hope this helps!
My code now looks like this:
- (void)viewDidLoad
{
[super viewDidLoad];
omMeny = [[NSMutableArray alloc] init];
//Add items
[omMeny addObject:#"Formålet med guiden"];
[omMeny addObject:#"Aromahjulet"];
[omMeny addObject:#"Fagterm"];
//Set the title
self.navigationItem.title = #"Om Rødvin";
}
//dealloc method declared in RootViewController.m
- (void)dealloc {
[omMeny release];
[super dealloc];
}
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
// return 2;
return [omMeny count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Om";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Set up the cell...
NSString *cellValue = [omMeny objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
// Configure the cell...
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
*/
}
#end
with this in the .h
#interface OmMasterViewController : UITableViewController {
NSMutableArray *omMeny;
}

Resources