Made Custom UITableViewCell -- Now UITableView Is Not Scrolling - objective-c

Created an empty xib.
Created a class that overrides UITableViewCell (UserCell).
Put in a custom pieces of logic that simply format some strings for display and connected the two labels in IB.
My view controller owns an UITableView. I've set the view controller as the data source.
Here's how I go about populating it with my custom cells.
(did: http://www.highoncoding.com/Videos/823_Creating_a_Custom_UITableViewCell.aspx)
-(UserCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UserCell* cell = [tableView dequeueReusableCellWithIdentifier:#"Users Table"];
if (!cell) {
NSArray* topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"UserCell" owner:nil options:nil];
for (id currentObject in topLevelObjects) {
if ([currentObject isKindOfClass:[UserCell class]]) {
cell = (UserCell*) currentObject;
break;
}
}
}
[cell setUserNameText:[[[_userDataManager getUsers] objectAtIndex:indexPath.row] name ]];
[cell setNumberLabelText:indexPath.row];
return cell;
}
For some reason, I am not able to scroll. In viewDidLoad: I'm printing scrollEnabled on my table view. It's "1".
Haven't had this trouble until I tried putting in a custom UITableViewCell. :(
Thanks SO for any advice! :D
EDIT: Custom cell code.
#import "UserCell.h"
#implementation UserCell
#synthesize textLabel, numberLabel;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
-(void) setNumberLabelText:(NSInteger)text {
self.numberLabel.text = [[NSString alloc] initWithFormat:#"# %d", text];
}
-(void) setUserNameText:(NSString*)text {
self.userNameLabel.text = text;
}
#end

Closing this question as answered (I'm a derp sometimes)
I haven't done much iOS stuff using a trackpad. Seems like I was expecting two finger scrolling to "scroll" on the simulator. It does not!
A heads up for anyone else having this issue.

Related

UITableView is null after first data load, reloadData does not work

I have a custom UIView with a UITableView in it. I connect the delegate and dataSource via interface builder, it looks like this: http://postimg.org/image/nj9elaj4h/ (may not upload images yet :( )
When I load the view, the data is displayed as it should be. But when I try to call reloadData, nothing happens. I checked if the uitableview is set, but it is NULL. But as soon as I drag the tableView and it reloads it views, the new data is presented. Anyone got an idea why reloadData does not work?
.h looks like this:
#interface NextTitleView : UIView<UITableViewDataSource,UITableViewDelegate,SociusClientDelegate,UIActionSheetDelegate,Ne xtTitleCustomCellDelegate>
{
NexTitleCustomCell* _cellInFocus;
}
#property(nonatomic,retain)IBOutlet UITableView* _tableViewNextTitle;
#end
thanks for your help :D
EDIT: Added .m file
#implementation NextTitleView
#synthesize _tableViewNextTitle;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
-(id)init
{
if(self)
{
[SharedSingeltons sharedInstance]._client.delegateCustomClient = self;
_tableViewNextTitle = [[UITableView alloc]init];
}
return self;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if(section == 0)
return #"Now playing";
if(section == 1)
return #"Comming Next";
else
return #"";
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(section == 0)
return 1;
if (section == 1)
return [[SharedSingeltons sharedInstance]._client._musicList count];
else
return 0;
}
-(NexTitleCustomCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NexTitleCustomCell* cell = [[NexTitleCustomCell alloc]init];
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"NextTitleCustomCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
MusicItem* item = [[SharedSingeltons sharedInstance]._client._musicList
objectAtIndex:indexPath.row];
cell.delegate = self;
cell._labelSongTitle.text = item._songTitle;
cell._labelSongTitle.textColor = [UIColor blackColor];
cell._labelSubtitle.text = item._artist;
cell._identifier = item._songIdentifier;
cell._labelRating.text = item._rating.stringValue;
return cell;
}
-(void)clientDidReceiveMusicList:(SociusClient *)sender list:(NSMutableArray *)array
{
for(MusicItem* item in [SharedSingeltons sharedInstance]._client._musicList)
{
NSLog(#"rating:%#",item._rating);
}
NSLog(#"TAbleVIEW:%#",_tableViewNextTitle);
[self._tableViewNextTitle reloadData];
}
-(void)didPressActionButton:(NexTitleCustomCell *)sender
{
NSLog(#"Show alert view");
_cellInFocus = sender;
UIActionSheet *popupQuery = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Vote Up", #"Like",#"Remember", nil];
[popupQuery showInView:self];
}
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(buttonIndex == 0)
{
NSLog(#"Vote up");
[self sendUpdateVoteForSong];
}
}
-(void)sendUpdateVoteForSong
{
NSMutableDictionary* dict = [[NSMutableDictionary alloc]init];
[dict setObject:_cellInFocus._identifier forKey:#"Vote"];
NSLog(#"Identifier:%#",_cellInFocus._identifier);
[[SharedSingeltons sharedInstance]._client sendObject:dict error:nil];
}
#end
I would say you are calling reload data too soon, probably in initWithNibName, you should be calling it in viewDidLoad.
I just set up a uiviewcontroller to handle the view. Now it works fine.
I think that UIActionSheet led to the problem,you can try to reloadData twice.
I noticed you are New-ing your Table view, but it's an Outlet... You don't need to alloc init your table view, if it's an IBOutlet. So either get rid of the IBOutlet, and just declare it as a property (but then you need to make sure you lay out your Table view programmatically), or keep the IBOutlet, and get rid of the code to alloc init it. Currently also your datasource and delegate are set from IB, so if you alloc init your table view, those won't be set anymore...
The tableview outlet should NOT be nil.
Can you put a breakpoint in awakeFromNib, and see if the TableView outlet is NIL there?
Are you loading the View Class that contains the table view by using its NIB file properly?
If you just embed the View class in the storyboard, it will not load the NIB automatically. I usually use a View container in that case, then load the NIB programmatically, and embed the loaded view in the view container programmatically.
NSArray *arrayXibObjects = [[NSBundle bundleWithIdentifier:#"net.mycompany.myappid"] loadNibNamed:#"myNibName" owner:nil options:nil];
for (id object in arrayXibObjects) {
if ([object isKindOfClass:myNibsClass]) {
return object; // this is your class loaded from NIB
}
}
This code can be placed in a utility method, to make it accessible with 1 line of code.
The returned Class is going to have the IBOutlets connected from the NIB to it's respective Class.
Now check in the debugger:
po [loadedClassFromNib tableView] // should not be NIL
Then embed the loaded NIB in the container like this: (or use constraints)
[self.viewContainer addSubview: classLoadedFromNib];
classLoadedFromNib.frame = self.viewContainer.frame;

cellForRowAtIndexPath does not fire. What am i missing?

I am trying to achieve this:
but i get this:
I have a view cotroller with a view table on it
This is the interface:
#interface LoginViewController : UIViewController<UITableViewDataSource, UITableViewDelegate>
#property (weak, nonatomic) IBOutlet UITableView *tblCredentials;
#end
This is the implementation:
#interface LoginViewController ()
#end
#implementation LoginViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
-(void)viewWillAppear:(BOOL)animated
{
self.tblCredentials.delegate=self;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 2;
}
// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
UITextField *textField = [[UITextField alloc] init];
textField.enablesReturnKeyAutomatically = YES;
textField.autocorrectionType = UITextAutocorrectionTypeNo;
textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
CGRect cellBounds = cell.bounds;
CGFloat textFieldBorder = 10.f;
CGRect aRect = CGRectMake(textFieldBorder, 9.f, CGRectGetWidth(cellBounds)-(2*textFieldBorder), 31.f );
textField.frame = aRect;
if(indexPath.row==0)
{
textField.placeholder = #"Username";
textField.returnKeyType = UIReturnKeyNext;
textField.autocapitalizationType = UITextAutocapitalizationTypeWords;
}
else
{
textField.placeholder = #"Password";
textField.returnKeyType = UIReturnKeyDone;
textField.secureTextEntry = YES;
}
[cell.contentView addSubview:textField];
return cell;
}
#end
I put a breakpoint on the in the cellForRowAtIndexPath and it doesn't stop there, so those text fields don't get rendered.
What am I missing?
PS: Is this a bad approach to achieve the goal? (those two grouped text fields)
LE: I am using stroyboard with no xib files
In viewDidLoad, you must set the delegate and call [self.tblCredentials reloadData] in order for the table view to actually "load its data"
You need to create a Custom Table View cell. have a look at this github link.
You're setting the delegate of the table view, but not the datasource, which is where the number of rows etc. comes from.
You're also setting the delegate a bit late in the cycle. Since this is in a xib, why not set the delegate and datasource in the xib instead of in code? If you declare that your view controller conforms to the delegate and data source properties in the header, you will be able to make the connection in IB. If you insist on setting it in code, it should be in viewDidLoad.
Set delegate and dataSource in -viewDidLoad and put [self.tblCredentials reloadData] in -viewWillAppear:.
- (void)viewDidLoad
{
[super viewDidLoad];
self.tblCredentials.delegate=self;
self.tblCredentials.dataSource=self;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated]; // BTW, it's better to call super's -viewWillAppear: here, according to apple's documentation.
[self.tblCredentials reloadData];
}

UITableView changes its style by itself

I face this kind of problem for the first time.
I have UITableView on my ViewController and I choosed Grouped style in the IB.
So when I run my app on iPad, it is grouped style and everything is OK, but sometimes UITableView's style becomes Plain. I dont change it anywhere in code or something, it just changes it by itself.
.h
#property (nonatomic, retain) IBOutlet UITableView *myTableView;
.m
myTableView.backgroundColor = [UIColor clearColor];
myTableView.opaque = NO;
myTableView.backgroundView = nil;
I tried to delete the XIB and create a new one, but its still the same problem.
Any ideas?
UPD:
OK, I dont know how, but I got 2 same xibs in my projects with same name. And in one xib I had Plain Style and in the 2nd one I had Grouped style; so its explains why sometimes I had Grouped and somteimes Plain Style. I just deleted one of them and it fixed the problem.
UITableView style doesn't change automatically, unless you change the style either in xib or in code. Please check your code once carefully weather u are changing the style or not and also make sure that u are properly connected datasource and delegate.
Hear is the another way you can create one in the code instead in the xib.
Create the tableview in code following code gives u some idea.
#interface ViewController ()<UITableViewDataSource,UITableViewDelegate>
{
UITableView *aTableVIew;
}
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//Do any additional setup after loading the view, typically from a nib.
aTableVIew = [[UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
aTableVIew.dataSource = self;
aTableVIew.delegate = self;
[self.view addSubview:aTableVIew];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
//Dispose of any resources that can be recreated.
}
-(void)dealloc
{
[aTableVIew release];
[super dealloc];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 2;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [aTableVIew dequeueReusableCellWithIdentifier:#"cell"];
if(cell == nil)
{
cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"]autorelease];
}
if(indexPath.section == 0)
{
cell.textLabel.text = #"Hello";
}
else if (indexPath.section == 1)
{
cell.textLabel.text = #"World";
}
else
{
cell.textLabel.text = #"Happy coding";
}
return cell;
}
#end

How to load array into a UITableView, not TableViewController

I am trying to take an array that I loaded from another viewer and put it into a UITableView, not a TableViewController. I don't know how I would do this. Right now I have this code:
CRHCommentSection.m
#import "CRHCommentSection.h"
#import "CRHViewControllerScript.h"
#interface CRHCommentSection ()
#end
#implementation CRHCommentSection
#synthesize observationTable;
NSArray *myArray;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
myArray = [CRHViewControllerScript theArray];
NSLog(#"%#", myArray);
//NSArray* paths = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:1]];
//[observationTable insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationTop];
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
NSLog(#" in method 1");
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#" in method 2");
// Return the number of rows in the section.
return [myArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#" in method 3");
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [myArray objectAtIndex:indexPath.row];
return cell;
}
CRHCommentSection.h
#import <UIKit/UIKit.h>
#interface CRHCommentSection : UIViewController
#property (weak, nonatomic) IBOutlet UITableView *observationTable;
#end
Since you have posted this same example code more than once, Ill give you the way to do this without using statics. And Yes you do need to set the collection (array) on the view controller not the UITableView as the tableView uses the controller as a datasource.
Lets say you had a UITableView that displayed search results... And you launch this view controller from either some other view or from the application delegate like so..
In your viewController (yours is CRHCommentSection) define a property for the array you are going to populate the table with.
#property (nonatomic,retain, setter=setSearchResults:) NSArray *searchResults; //use your array name here
//BTW please dont call it ARRAY..its confusing.
Also in your commentsController (which would be a better name that what you have) add the setter for
the array
-(void) setSearchResults:(NSArray *)searchResults
{
//in case we loaded this view with results previously release the previous results
if ( _searchResults )
{
[_searchResults release];
}
_searchResults = [searchResults retain];
[_tableView reloadData];
}
When you instantiate the new view controller with the UITableView in it - set the "array",
in your case comments in my case searchResults
_searchResultsViewController = [[SearchResultsViewController alloc] initWithNibName:#"SearchResultsViewController" bundle:nil];
//now set the array on the controller
_searchResultsViewController.searchResults = mySearchResults; //(your array)
Thats a simple way to communicate the array for the table view when you instantiate a view controller.
Also the naming conventions will help you clear things up
If you have a view controller for comments it should be
CommentsViewController
And the array if it contains comments should be called comments - for readability.
Cheers.
As for the rest of the boilerplate setting the datasource and delegate and cellForRow etc,
you got that advice on the last go around so I wont repeat it here.
#bigkm had a good point
#interface SearchResultsViewController : UIViewController<UITableViewDataSource, UITableViewDelegate>
Your view controller has to be defined properly as above with the protocols.
You need to set the data source
[self setDataSource:self];
And also add the protocol to your interface.
<UITableViewDataSource>

TableView is delegated, populates but wont group

I am having a weird problem and i couldn`t find a solution (or something similar).
The thing is, my UITableView Populates with initial info (for testing), but no matter what i do i can't seem to put it to grouped style (i can select it on the UI but it wont show)
I initially started a TabBar project and added a third navigationController view in the tabs.
#import <UIKit/UIKit.h>
#interface RootViewController : UITableViewController <UITableViewDelegate, UITableViewDataSource> {
NSMutableArray *tableData;
}
#property (nonatomic, retain) NSMutableArray *tableData;
-(void)initTableData;
#end
This is the header, and as you can see it has nothing out of the ordinary. The following code is inside the .m file of the header i just posted(ill only be posting uncommented code:
#synthesize tableData;
-(void)initTableData
{
tableData = [[NSMutableArray alloc] init];
[tableData addObject:#"Cidade"];
[tableData addObject:#"Veículo"];
[tableData addObject:#"Ano"];
[tableData addObject:#"Valor"];
[tableData addObject:#"Cor"];
[tableData addObject:#"Combustível"];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.title = #"Busca";
UIBarButtonItem *_backButton = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStyleDone target:nil action:nil];
self.navigationItem.backBarButtonItem = _backButton;
[self initTableData];
}
- (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 6;
}
// Customize the appearance of table view cells.
- (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] autorelease];
}
// Configure the cell...
cell.textLabel.text = [tableData objectAtIndex:[indexPath row]];
return cell;
}
- (void)dealloc {
[tableData release];
[super dealloc];
}
Nothing out of the ordinary again as you can see...
Any idea of what may be causing this? I tried
- (id)initWithStyle:(UITableViewStyle)style {
// Override initWithStyle: if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
self = [super initWithStyle:UITableViewStyleGrouped];
if (self) {
// Custom initialization.
}
return self;
}
because i don't know what else to do. (also didn't worked)
Again, i got the delegate and datasource set to File`s Owner.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// Set the tab bar controller as the window's root view controller and display.
self.window.rootViewController = self.tabBarController;
RootViewController *rvc = [[RootViewController alloc] initWithStyle: UITableViewStyleGrouped];
[self.window makeKeyAndVisible];
return YES;
}
As you have modified the - (id)initWithStyle:(UITableViewStyle)style initializer to return a UITableView with a grouped style, do you call this initializer when you initialize the RootViewController?
RootViewController *rvc = [[RootViewController] alloc] initWithStyle: UITableViewStyleGrouped];
Grouped tables respond to the sections. You only have 1 section listed so you will only see the 1 group. Try and add a 2nd tableData for the 2nd group and return 2 sections. You will also have to split the data in your -cellForRowAtIndexPath by section as well to make sure the data goes to the right section.
if (indexpath.section == 0) {
// first section and first tableData
}
if (indexpath.section == 1) {
// second section and second tableData
}