I am trying to use Storyboards on this project. I cntrl drag from a static tableview cell to a new viewcontroller select push.
When I run the app and click the tableviewcell, which I dragged from in the previous step, nothing happens?
I am not sure if I have screwed things up by also putting in my tableviewcontroller class the following method.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier1 = #"Cell1";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier1];
}
[cell.textLabel setFont:[UIFont fontWithName:#"GothamRounded-Light" size:18]];
cell.textLabel.backgroundColor = [UIColor clearColor];
cell.detailTextLabel.backgroundColor = [UIColor clearColor];
[cell.detailTextLabel setFont:[UIFont fontWithName:#"GothamRounded-Light" size:12]];
cell.contentView.backgroundColor = [UIColor statOffWhite];
if (indexPath.row == 0) {
cell.textLabel.text = #"Profile";
}
else if (indexPath.row == 1) {
cell.textLabel.text = #"Support";
}
else if (indexPath.row == 2) {
cell.textLabel.text = #"Share";
}
else if (indexPath.row == 3) {
cell.textLabel.text = #"About";
}
else if (indexPath.row == 4){
cell.textLabel.text = #"";
cell.frame = CGRectMake(0, 0, self.view.bounds.size.width, 200);
UIImageView *watermark = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"watermark.png"]];
watermark.frame = CGRectMake((cell.frame.size.width/2) - (watermark.image.size.width/2), 80, watermark.image.size.width, watermark.image.size.height );
[cell addSubview:watermark];
}
return cell;
}
// UPDATE ////////
I took out the cellForRowAt method and the storyboard thing worked. But since I have taken out that method how can I set my font on my cell to be a custom font that isn't in Xcode's selections? I have included the font in my project, which I use everywhere.
What happen with your implementation of cellForRowAtIndexPath: is that your are creating cells from scratch and overwriting the storyboard's cells (hence your segue not being triggered).
If you defined static cells in your storyboard, you should not dequeue and create cells yourself. If your class is a subclass of UITableViewCellController, you could call the implementation of super and use the returned cell.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
// Customize your cell here
}
Note however that doing so makes little sense : all the things you are doing in your cellForRowAtIndexPath: method could and should for simplicity sake be done in the storyboard.
If you really need to customize a static cell programmatically, the way to go is to define an outlet to this cell in your view controller and customize the cell in the appropriate method (viewDidLoad for example).
Related
I have created a few labels on my tableview using custom UITableViewCell and interface builder. Now i am using some third party control called BEMLineGraph and i want to add it to my tableview cell using code. It also has a few delegates and data source methods. I am doing the following but the problem is that i get duplicate graphs and messed up data upon scrolling up and down.
ProductsTableViewCell.m
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.productGraph = [[BEMSimpleLineGraphView alloc] initWithFrame:self.graphContainter.frame];
//_myGraph.enableTouchReport = YES;
self.productGraph.tag = 100;
self.productGraph.animationGraphStyle = BEMLineAnimationNone;
//_myGraph.enablePopUpReport = YES;
self.productGraph.enableXAxisLabel = YES;
self.productGraph.colorTouchInputLine = [UIColor whiteColor];
self.productGraph.colorXaxisLabel = [UIColor darkGrayColor];
self.productGraph.colorTop = [UIColor clearColor];
self.productGraph.colorBottom = [UIColor clearColor];
self.productGraph.colorLine = [UIColor colorWithRed:255.0/255.0 green:255.0/102.0 blue:255.0/102.0 alpha:1];
self.productGraph.colorPoint = [UIColor lightGrayColor];
[self addSubview:self.productGraph];
}
return self;
}
TableViewController.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
ProductsTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell = [cell initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.productGraph.frame = CGRectMake(0, 0, cell.graphContainter.frame.size.width, cell.graphContainter.frame.size.height);
cell.productGraph.dataSource = self;
cell.productGraph.delegate = self;
//All the other stuff is set here and works well.
}
- (NSInteger)numberOfPointsInLineGraph:(BEMSimpleLineGraphView *)graph
{
if (graph.tag == 100)
{
return productDetail.count;
}
else
{
return numbers.count;
}
one thing wrong I can see your code:
if (cell == nil)
{
cell = [cell initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
}
it should be:
if (cell == nil)
{
cell = [[ProductsTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
}
but this won't fix the problem of duplicate graphs
As you have subclassed the cell anyways, why don't you keep the delegate and datasource of the productGraph in the cell itself
If you have registered the ProductsTableViewCell class with the UITableView, then dequeueReusableCellWithIdentifier: will create an object of that class for you, and call its initWithCoder: method (for cells defined in Interface Builder). Therefore, remove the call to your initWithStyle:reuseIdentifier: and do initialisation in the initWithCoder: method of ProductsTableViewCell instead.
Then, in your cellForRowAtIndexPath: do only that what is specific for that cell. What that is depends on the implementation of your Graph class, but it needs to make sure that the old graph is not visible anymore.
How can I set first row of tableview checkmarked when the app started? I mean when I start app now, there are few rows in tableview and when I click on some of them its accessory change to checkmark. When click another one, the another one comes checkmarked and previous checkmark dissapears. So now I want first row of tableview to be checkmarked when app is started and then when I click another row it 'uncheckmark' and 'checkmark' new row etc...
Try the options suggested in these posts how to apply check mark on table view in iphone using objective c? or iPhone :UITableView CellAccessory Checkmark
Basically you need to keep track of the checkmarks using say a dictionary or so. And In viewDidLoad or init method make the first cell as checked in the dictionary. While drawing cells, always check if the corresponding entry in the dictionary is checked or not and display check mark accordingly. When user taps on a cell, modify the value in dictionary to checked/unchecked.
Update:
Here is a sample code.
In .h file declare a property as
#property(nonatomic) NSInteger selectedRow;
Then use the below code,
- (void)viewDidLoad {
//some code...
self.selectedRow = 0; //if nothing should be selected for the first time, then make it as -1
//create table and other things
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// create cell and other things here
if (indexPath.row == self.selectedRow)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// some other code..
if (indexPath.row != self.selectedRow) {
self.selectedRow = indexPath.row;
}
[tableView reloadData];
}
You could set an integer to a variable similar to "checkedCell", have that value default to cell 0, and in the cellForRowAtIndexPath check to see if the cell is already checked, if not change the accessory to make it checked and update your variable.
-(void)viewWillAppear{
currentCheckedCell = 0;
}
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//
// Create cells -- if indexpath.row is equal to current checked cell reload the table with the correct acessories.
//
static NSString *cellIdentifier = #"RootMenuItemCell";
MyCell *cell = (MyCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[MyCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
NSArray *nibContents = [[NSBundle mainBundle] loadNibNamed:#"MyCell" owner:self options:nil];
for (UIView *view in nibContents) {
if ([view isMemberOfClass:[MyCell class]]) {
cell = (MyCell *)view;
break;
}
}
//OTHER CELL CREATION STUFF HERE
// cell accessory
UIImage *accessory = [UIImage imageNamed:#"menu-cell-accessory-default.png"];
UIImage *highlighted = [UIImage imageNamed:#"menu-cell-accessory-selected.png"];
if(indexPath.row == currentCheckedCell){
//DEFAULT ACCESSORY CHECK
// cell.accessoryType = UITableViewCellAccessoryCheckmark;
UIImageView *accessoryView = [[UIImageView alloc] initWithImage:accessory highlightedImage:highlighted];
}else{
//DEFAULT ACCESSORY NONE
// cell.accessoryType = UITableViewCellAccessoryNone;
UIImageView *accessoryView = [[UIImageView alloc] initWithImage:accessory highlightedImage:accessory];
}
[cell setAccessoryView:accessoryView];
}
return cell;
}
- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//UPDATE SELECTED CELL & RELOAD TABLE
currentCheckedCell = indexPath.row;
[self.tableview reloadData];
}
Also worth noting that my examples uses custom images for accessories.
If you check out the link #ACB provided you'll find a very similar concept.
You can use,
if (firstCellSelected)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
Set the firstCellSelected flag in viewDidLoad method.
I have uitaleviewcell with different sections and rows, I want to have checkbox cell that you can see in the picture
my question is how can I create checkbox in uitableviewcells?(I used storyboard)
Use UISwitch and in the property inspector, set an empty box image for normal state and a checked box image for highlighted state. However checkbox behaviour is represented by switches in ios, a checkbox has a very small hit area and might pose a usabilty problem for your users, especially when they are close to each other as in the image you provided.
UISwitch Reference
Each checkbox cell should be a Custom TableViewCell. Then simply drop an ImageView and a Label in the TableViewCell and use didSelectRowAtIndex: to toggle the image between checked/unchecked.
You need two images for imageView of cell
#define SELECTED_ROW #"selectedRowImage.png" // CheckBox with Selected sign png
#define NOT_SELECTED_ROW #"notSelectedRowImage.png" // Empty CheckBox png
// listSelected is array of indexes selected
in ViewDidLoad:
NSMutableArray *listSelected = [[NSMutableArray alloc]init];
// CellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"select";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: cellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
if ([self checkIfIndexPathAlreadySelected:indexPath])
cell.tag = 1;
else cell.tag = 0;
if(cell.tag == 0)
cell.imageView.image = [UIImage imageNamed:NOT_SELECTED_ROW];
else
cell.imageView.image = [UIImage imageNamed:SELECTED_ROW];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if(cell.tag == 0)
{
cell.tag = 1;
[self.listSelected addObject:indexPath]];
cell.imageView.image = [UIImage imageNamed:SELECTED_ROW];
}
else if(cell.tag == 1)
{
cell.tag = 0;
[self.medicineIndexArray removeObject:indexPath];
cell.imageView.image = [UIImage imageNamed:NOT_SELECTED_ROW];
}
}
- (BOOL)checkIfIndexPathAlreadySelected:(NSIndexPath *)indexPath
{
if([self.listSelected containsObject:indexPath])
return YES;
else
return NO;
}
I am looking at making a table view section that extends another section like the image. Although this is purely aesthetic if you know of an easy way of doing this I would like to know.
You different section can have different background image and different frames for the subviews.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"myCell"];
if(cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"LOC_ID"];
[cell autorelease];
}
if(indexPath.section == 0){
if(indexPath.section == 0 && [self tableView:numberOfRowsInSection:0]-1 == indexPath.section){
//put background image for last row in section 0
} else {
//backgroundimaes for all other cells in section0
} else if(indexPath.section == 1) {
//configure section 1 ibackgroundimages
}
}
return cell;
}
setting background of an cell
cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"cell_bg.png" ]autorelease];
cell.selectedBackgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"cell_selected_bg.png"];
Nice diagram. If you are trying to create a UITableView with sections that have different widths, that is not possible. You will have to use two separate UITableViews with different widths, and put one below the other. Or just set up some UITableViewCells manually and don't use a UITableView at all.
when I used layoutSubviews method of UItableViewcell with category, just like the code below
#implementation UITableViewCell (forimage)
- (void)layoutSubviews{
[super layoutSubviews];
self.imageView.frame = CGRectMake(0, 0, 50, 50);
}
#end
when I used the code below to draw the cells , the textLabel was disappeared ,anyone know why it be that~, and does that mean if I use layoutSubviews,I must write all the subviews what I need in the method?
- (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];
}
RadioInfo *radioinfo = [radios objectAtIndex:indexPath.row];
cell.textLabel.text = [NSString stringWithFormat:#"%#",radioinfo._name];
if(!radioinfo._logo){
if(self.tableView.dragging == NO && self.tableView.decelerating == NO){
[self startPicDownload:radioinfo forIndexPath:indexPath];
}
cell.imageView.image = [UIImage imageNamed:#"1.jpg"];
}
else {
cell.imageView.image = radioinfo._logo;
}
return cell;
}
What you want to do is add to the behaviour of UITableViewCell's layoutSubviews method, not replace it.
To properly add to the behaviour, subclass the cell and perform your own layout, as you have above but add a [super layoutSubviews] right at the top of your method to ensure that the cell's own basic layout is performed first.