UITableView changes its style by itself - objective-c

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

Related

UITableView with Tab Bar Controller

I have a tab bar control and I want to show table view in first tab.
In my story board I have Tab Bar view controller with Items and I put the tableview and tableview cell in it. ( I am not sure about it. Should I put them to show data in tableview or should I do it programmatically?) I am getting the data from database (there is not any problem in this side) but can not bind the data in tableview.
What is wrong in my code?
My code:
.h file
#interface CategoryTabController : UIViewController<UITableViewDataSource, UITableViewDelegate>
{
DatabaseProcess *databaseProcess;
UITableView *categoryTableView;
NSMutableArray *categoryTableArray;
}
.m file
#implementation CategoryTabController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
databaseProcess = [[DatabaseProcess alloc]init];
//Get Category data to array
categoryTableArray = [[NSMutableArray alloc]initWithArray:[databaseProcess getAllActiveCategory]];
categoryTableView = [[UITableView alloc]init];
categoryTableView.delegate = self;
categoryTableView.dataSource = self;
[self.view addSubview: categoryTableView];
}
- (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 categoryTableArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CategoryCell" forIndexPath:indexPath];
cell.textLabel.text = [categoryTableArray objectAtIndex: indexPath.row];
return cell;
}
You must make categoryTableView as IBOutlet property and connect it to your table in IB. Also you must set "CategoryCell" as cell identifier in IB to 'dequeueReusableCellWithIdentifier' to work.

Populate UITableView from button pressed

I am trying to populate UITableView from NSMutableArray. I have UITextField and a button on a ViewController. When I type any text in the UITextField and click button, I can see the text being added to the array with NSLog. I set breakpoints on the data source method of UITableView but it does not even hit those breakpoints when I click the button.
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UITableViewDataSource, UITableViewDelegate>
{
NSMutableArray *arrBarcode;
IBOutlet UITextField *txtInsert;
}
#property IBOutlet UITableView *myTableView;
-(IBAction)btnPressed:(id)sender;
#end
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.myTableView.delegate = self;
self.myTableView.dataSource = self;
arrBarcode = [[NSMutableArray alloc]init];
}
-(IBAction)btnPressed:(id)sender{
[arrBarcode addObject:txtInsert.text];
NSLog(#"array count is : %i", [arrBarcode count]);
[self.myTableView reloadData];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[txtInsert resignFirstResponder];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(NSInteger)numberOfSectionsInTableView: (UITableView *)tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
if ([arrBarcode count] == 0){
return 0;
}
else{
NSLog(#"Number of Rows : %i", [arrBarcode count]);
return [arrBarcode count];
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"Cell Identifier";
[tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:CellIdentifier];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSString *barcode = [arrBarcode objectAtIndex:[indexPath row]];
[cell.textLabel setText:barcode];
return cell;
}
#end
When I initialize a NSMutable Array with some data in the viewDidLoad method, the UITableView is populating fine but not with dynamic array. I am newbie in Objective C, Can someone point me to right direction?
Code looks OK (even if not very efficient). You have to check if the button is indeed connected to the action. In storyboard or Interface Builder, select the button and check the rightmost inspector on the right. See if the action is correctly connected.
Maybe you want to get rid of the touchesBegan call and call resignFirstResponder when the button is pressed.
For numberOfRowsInSection I think this is enough:
return arrBarcode.count;
I'm not sure but the following line looks strange to me:
#synthesize myTableView = myTableView_;
This is telling the compiler to make a getter and setter for the property myTableView and backing it with an iVar named myTableView_. But in your case you have already defined an iVar named myTableView_.
Try connecting the UITableView as a property instead. A property will be backed by an instance variable with the form _yourProperty and have getter and setter generated automatically so #synthesize isn't really needed in this case.

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];
}

Made Custom UITableViewCell -- Now UITableView Is Not Scrolling

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.

Table view as an object in a view - how to initialize with an array of data?

My goal is to have something like a "select" option in a HTML form, but now in my app. After doing research it's probably best to do this with a table view. I though of the picker view, but the fixed height is too big.
With the interface builder I simply placed a table view on my subclass of UIViewController.
How do I fill the Table view with options? I've seen many tutorials, but those are all for having a UITableView as their own class and filling up the entire screen. In my application this is just a small piece of the entire form.
What a nightmare to create a relatively simple thing like a table view. It either crashes or I get a table view that covers my entire view and that is not filled with anything.
The variable countryTable is connected to the object in the interface builder.
Frustrated after a hard day of work. Anyone got the complete working code? That would be great. I already had a great look at apple's explenation AND various tutorials, but I can't figure it out.
I've tried multiple things, but this is my current code:
#interface myView: UIViewController
{
NSArray *countryArray;
IBOutlet UITableView * countryTable;
}
#property (nonatomic, retain) UITableView *countryTabel;
#end
and in my .m file
#implementation myView
#synthesize countryTable;
- (void)loadView
{
self.countryTable.dataSource = self;
}
- (void)viewDidLoad
{
NSArray *array = [[NSArray alloc] initWithObjects:#"test1", #"test2",
#"test3",nil];
self.countryTable = array;
[array release];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void) dealloc
{
[countryTable release];
[super dealloc];
}
#pragma mark -
#pragma mark Table View Data Source Methods
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
return [self.countryTable count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:SimpleTableIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:SimpleTableIdentifier] autorelease];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [countryTable objectAtIndex:row];
return cell;
}
#end
You are on the right track. If you were to use a UITableViewController subclass, you would obviously have a full screen table view by default. Going the route of using a UIViewController subclass with a UITableView as a subview in the UIViewController's view is the right way to go. A few things that you will need to address are:
1) In the UIViewControllers header file you will need to add <UITableViewDatasource, UITableViewDelegate> as your view controller is responsible for fill implementing this functionally.
2) In viewDidLoad:, set self.contryTable.delegate = self; and self.countryTable.datasource = self;
The following protocol methods need to be implemented like so:
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
return countryArray.count;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
-(UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SimpleTableIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:SimpleTableIdentifier] autorelease];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [countryArray objectAtIndex:row];
return cell;
}
Hope this helps.