UICollectionViewCell Subclass issue - objective-c

I have subclassed a UICollectionViewCell-
#interface ListCell : UICollectionViewCell
#property(nonatomic,strong) IBOutlet UILabel *lblAppName;
#end
I have made an xib for the same ,made all the IBOutlet collection as well as set the class of the XIB , while using this Cell in the Collection view delegate method i get a nill value while trying to access the label instance.
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
ListCell *cell = (ListCell *)[cv dequeueReusableCellWithReuseIdentifier:#"ListCell" forIndexPath:indexPath];
AppDetails *temp=[arrApplist objectAtIndex:indexPath.item];
cell.lblAppName.text=temp.strName;
return cell;
}
i have registered the cell to my collection view by:
[collectionView registerClass:[ListCell class] forCellWithReuseIdentifier:#"ListCell"];
is there something else i might be missing??
Thanks in advance.

Instead of registering the class, I think you need to register the xib, using registerNib:forCellWithReuseIdentifier:. Try that, and see if that helps.

if you use ListCell.xib,please use registerNib:forCellWithReuseIdentifier:.
Implement your ListCell initial in awakeFromNib instead of initWithFrame.
And change type like that:
- (ListCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
ListCell *cell = [cv dequeueReusableCellWithReuseIdentifier:#"ListCell" forIndexPath:indexPath];
cell.lblAppName.text=(NSString *);
return cell;
}

Related

How Passing indexPath.row between views?

I have table view, and I want to send the indexPath.row(index of selected row) to another view.
ProfesorViewController.m
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
SCProfesoresCellTableViewCell *cell = (SCProfesoresCellTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
rowselected = indexPath.row;
}
ProfesorViewController.h
#interface ProfesorViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
#property long rowselected;
#end
I want to receive value of rowselected variable:
ProfesorDetailViewController.m
#synthesize rowselected;
- (void)viewDidLoad {
NSLog(#"BANDERA DE LA FILA %ld", rowselected);
}
ProfesorDetailViewController.h
#interface ProfesorDetailViewController : UIViewController
#property long rowselected;
#end
But the value of rowselected is always 0.
I don't know how to send the value of variable.
You have two classes with properties with the same name, but you never assign the value of one to the value of the other. At some point you need to take your instance of ProfesorDetailViewController and set rowselected on it, likely when initializing it.
ProfesorDetailViewController *detailViewController = [[ProfesorDetailViewController alloc] init];
detailViewController.rowselected = self.rowselected;
I can not understand where to pass data between ProfesorViewController and ProfesorDetailViewController so pass data between to view controller
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
ProfesorDetailViewController *profesor=[[ProfesorDetailViewController alloc]initWithNibName:#"ProfesorDetailViewController" bundle:nil];
rowselected=indexPath.row;
search.Selected=_selected;
[self.navigationController pushViewController:profesor animated:YES];
}
Now you get the value of selected row index in ProfesorDetailViewController viewController properly..

Creating a Custom Table Cell, Cannot Access Property

IMPORTANT EDIT: I posted the wrong error code, like an idiot. I was posting the error for an attempt I had previously made to fix the issue, instead of the first error. Disregard my dumbness, please.
I'm creating a Facebook Feed app in Xcode, and I'm running into trouble in the creation of custom cells for a table. I'm trying to assign values to two UILabels on the custom cell, and it's giving me the error "No visible #interface for 'JSONFeedItemCell' declares the selector 'nameLabel'". My code is as follows:
Master View Controller
- (void)viewDidLoad
{
UINib *nib = [UINib nibWithNibName:#"JSONFeedItemCell" bundle:nil];
[[self tableView] registerNib:nib forCellReuseIdentifier:#"JSONFeedItemCell"];
... // other stuff, not relevant
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
JSONFeedItemCell *cell = [tableView dequeueReusableCellWithIdentifier:
#"JSONFeedItemCell"];
NSDictionary *p = [[[JSONFeedItemStore sharedStore] allItems]
objectAtIndex:[indexPath row]];
[[cell nameLabel] setText:#"The Name"];
return cell;
}
Cell Class
#import <Foundation/Foundation.h>
#interface JSONFeedItemCell : UITableViewCell
{
}
#property (weak, nonatomic) IBOutlet UIImageView *imageView;
#property (weak, nonatomic) IBOutlet UILabel *detailLabel;
#property (weak, nonatomic) IBOutlet UILabel *nameLabel;
#end
Let me know if you need any additional information or code, I'd be happy to provide it.
Two things: you have to make sure.
#import "JSONFeedItemCell.h" //in your mainViewController.h
And, as Wolfgang Schreurs suggested, typecast the cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
JSONFeedItemCell *cell = (JSONFeedItemCell *)[tableView dequeueReusableCellWithIdentifier:
#"JSONFeedItemCell"];
NSDictionary *p = [[[JSONFeedItemStore sharedStore] allItems]
objectAtIndex:[indexPath row]];
[[cell nameLabel] setText:#"The Name"];
return cell;
}
EDIT: since you don't use custom setters/getters you have to synthesize the properties
in JSONFeedItemCell.m
#synthesize imageView;
#synthesize detailLabel;
#synthesize nameLabel;
Compiler should warn you if you forgot to do that but with all the possible compiler settings you never know.
Do you maybe have something like a , I call it, circle import? Xcode gets messed up when you have 2 classes which imports each other. Xcode displays sometimes 'random' errors like this. And sometimes helps to clean and organize project, and restart pc. I have actually no idea why, but it helps sometimes.

Is it possible to create a static tableview in a storyboard and add it programmatically later? (iOS5, XCode 4)

I'm trying to create a couple of small, static tableviews and add them to a panel that I have which slides in and out. The panel is created programmatically so I can't lay the tableviews out inside it via storyboard, and anyway I'm not sure if this is possible anyhow: It seems the only way you can lay out static tableviews that work is in a tableviewcontroller, which takes up the whole screen.
If you can't tell I'm pretty new to iOS dev so if I'm not understanding some fundamental concepts here please feel free to explain.
Of course is possible. Here is how it can be done:
Drag a TableViewController to your storyboard.
Set its Size to Freeform, add an identifier and uncheck Resize View From NIB
Select the tableview and set its content to Static Cells. Design your cells.
Set its size
Now, wherever you need to instantiate it do it like this:
// I am using a UITableViewController as an example here
// you probably would like to set your actual controller subclass instead
UITableViewController *tableViewController = [[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:#"staticTv"];
UITableView *tableView = tableViewController.tableView;
[self.view addSubview:tableView]; // Or add it to whatever view
Enjoy :)
A UITableViewController isn't necessary to provide the functionality you need to manage a UITableView. I think what you're looking for is the "Delegate" pattern. Any UIViewController can be assigned to be the delegate of the UITableView. For example, I have a "static" table that shows some options in an app I am working on:
#interface LBOptionsViewController : UIViewController <UITableViewDataSource,
UITableViewDelegate>
If you're creating your table views programmatically, you'll probably either be creating them in viewDidLoad or loadView (if you're creating the actual view yourself). After you've created your tableView, assign the delegates:
self.tableView.delegate = self;
self.tableView.dataSource = self;
Then your UIViewController subclass will receive the data delegate messages like:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
Not sure if this helps you. I have not played with Storyboards much yet.
EDIT: #Alladinian has the right answer! If you're using an property for the view controller make sure you allocate it if you need it to be called by other methods.
I've yet to find a usefully reason to use static table view cells over dynamic. Table views were pretty scary when I started iOS programming. I used sqlite in my first app YIKES.
So yeah, you should just import the UITableView Data Source and Delegate and follow up by adding the table view to your panel (assuming it's a uiview and you can add the table view as a subview).
Anyways in your ViewController.h include UITableViewDataSource and UITableViewDelegate.
#interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>
Next, add properties for a UITableView and an NSMutableArray:
#property (strong, nonatomic) UITableView* tableView;
#property (strong, nonatomic) NSMutableArray* tableViewContents;
In your ViewController's .m:
#synthesize tableView;
#synthesize tableViewContents;
inside ViewDidLoad:
self.tableViewContents = [NSMutableArray arrayWithObjects:#"Cell 1",#"Cell 2",#"Cell 3",nil];
[self.tableView setDelegate:self]
[self.tableView setDatasource:self]
In the .m file:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.tableViewContents.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSUInteger row = [indexPath row];
index = row;
static NSString *cellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
}
cell.textLabel.text = [tableViewContents objectAtIndex:row];
return cell;
}

Failing to properly declare/implement UITableViewDataSource methods

I have a UIViewController that I want to use to implement the methods of UITableViewDataSource on. I have this header, FriendsController.h:
#import <UIKit/UIKit.h>
#interface FriendsController : UIViewController <UITableViewDataSource>
#end
Edit: now updated the #interface declaration to:
#interface FriendsController : UIViewController <UITableViewDataSource, UITableViewDelegate>
and this implementation, FriendsController.m:
#import "FriendsController.h"
#implementation FriendsController
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
NSLog(#"CALLED .numberOfRowsInSection()");
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"CALLED cellForRowAtIndexPath()");
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:#"FriendCell"];
cell.textLabel.text = #"Testing label";
return cell;
}
#end
When run this gives me a '-[UIView tableView:numberOfRowsInSection:]: unrecognized selector sent to instance 0x81734d0'. Can anyone see if there is something wrong with my implementation/declaration of .numberOfRowsInSection()?
Edit: I've added a technique for method listing from here and run the view 'unconnected', it outputs the following list:
[<timestamp etc>] Method no #0: tableView:numberOfRowsInSection:
[<timestamp etc>] Method no #1: tableView:cellForRowAtIndexPath:
[<timestamp etc>] Method no #2: numberOfSectionsInTableView:
[<timestamp etc>] Method no #3: tableView:didSelectRowAtIndexPath:
[<timestamp etc>] Method no #4: viewDidLoad
Post scriptum: Both #ThisDarkTao and #Pei got it right, as can be seen in my previous question documenting the visual parts, here.
You need to add UITableViewDelegate to the list of protocols in the interface file, like this: <UITableViewDataSource, UITableViewDelegate>
You also need all of the following delegate methods:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1; // Number of rows
}
- (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 = #"Test Cell";
return cell;
}
In your xib/storyboard view, you also need to connect the tableview's delegate and datasource connections to the viewcontroller.
If you want your cells to 'do something' when you tap them, you also need to implement the following delegate method:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"Tapped cell %d",indexPath.row);
}
If you use the Storyboard in your project, you have to set the UIViewController's Class field to be your "FriendsController" on Identity Inspector of your storyboard.
So you can present your UIVIewController to be using your correct class (In this case, FriendController for you).
Pei.

UITableView not populating from UIView

I have this problem I've been sitting with. My tableView that I put inside my UIView is not populating or sometimes I get an exception.
// .h
#interface List : UIViewController <UITableViewDelegate, UITableViewDataSource>
{
UITableView *mTableView;
}
#property (nonatomic, readonly) IBOutlet UITableView *tableView;
//------------------------------
// .m
#synthesize tableView=mTableView;
//Further I do the normal viewDidUnload stuff = nill
//And the numberOfSectionsInTableView, numberOfRowsInSection and
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"cellForRowAtIndexPath:");
NSLog(#"Table View: %#",[tableView description]);
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = #"Hi";
// Configure the cell...
return cell;
}
I get as output:
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<List 0x6a78000> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key tableView.'
or just a list of empty cells, not even "Hi" as a title.
I'm almost sure that this error occurs because you have improperly connected your UITableView . You should delete an ivar mTableView, an IB outlet property tableView and #synthesize . Then DELETE AN OUTLET IN IB. Then, connect it again by dragging it from the interface builder and DO NOT TYPE ANY CODE in your class. Xcode will do all stuff for you (create a property, synthesize it and do MM things)
Make sure that you have set the delegate and the datasource of the table within Interface Builder
If you do not do anything with your IBOutlet why do you have it? The method
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
is Called by the nib-File for the tableView instance created in the nib.Your Class as a delegate of this instance receives this call. Being the delegate of the tableView in the nib is all you need.