Right to Left Alignment for UITableView - iphone

I am working on an arabic app for iphone 3.0.
i was wondering if there is a way that i can convert the UITableViewCell to be right-to-left.
I want everything to be in the opposite direction.
Any thoughts?

Creating your own UITableViewCell subclass is not that hard to do and is probably the first thing you'll want to do to get a custom look. All you'll need is a custom XIB file and a bit of modified code in your cellForRowAtIndexPath function:
NSString *CellIdentifier = #"IndividualContractWithResult";
UITableViewCell *cell;
...
cell = [thisTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
// TODO: improve code by avoiding the view controller creation
UIViewController *vc = [[UIViewController alloc] initWithNibName:#"IndividualContractWithResult" bundle:nil];
cell = (IndividualContractWithResult_Cell *) vc.view;
[vc release];
}

Hmm.. It's really interesting) I have no solution, but few suggestions. First of all, you can try to use CGAffineTransformInvert to mirror your table. If it wil be useless, you can customize your tableView cells(make an UIImageView at the left side and UILabel with UITextAlignmentRight at the right). This is about your table. If you want to go to another view, you can just change your table view with UIViewAnimationTransitionFlipFromLeft animation instead of using UINavigationController. It's not a pretty solution, but it may do the trick) Good luck)

Related

Use XIB from parent class in UITableViewCell

Currently I have a newsfeed with custom UITableViewCells such as :
NewsCell.m
NewsCell.xib
NewsCell_Friends.m
NewsCell_Friends.xib
NewsCell_CheckinPhoto.m
NewsCell_CheckinPhoto.xib
[...]
NewsCell_Friends and NewsCell_Checkin inherit both from NewsCell (methods and elements such as titleLabel, dateLabel that are shared by all subclasses)
At the moment, I have never used NewsCell class itself and only subclasses as each kind of news has a very distinct layout (Xib).
Let's say now that, I would like to have a light implementation in terms of UI of my newsfeed where all cells have the same appearance, same height, same content : the titleLabel and the dateLabel.
(Such as a notification feed in fact).
What I would like to do is to reuse NewsCell.xib as a standalone for every type of news, e.g. below :
NewsCell_CheckinPhoto *cell = [tableView dequeueReusableCellWithIdentifier:#"CheckinPhoto"];
if (!cell){
UIViewController *c = [[UIViewController alloc] initWithNibName:#"NewsCell" bundle:nil];
cell = (NewsCell_CheckinPhoto *)c.view;
cell.parent = self;
}
[cell configureCell:indexPath withNews:news];
return cell;
in the cellForRowAtIndexPath delegate methods.
Notice that I use the NewsCell xib and not the NewsCell_CheckinPhoto xib in this controller.
But it is not working :the nib file is well loaded and the content of the NewsCell.xib well displayed in the cell, BUT the configuration of the labels (e.g, titleLabel.text = #"Robert took a photo") within the NewsCell_CheckinPhoto class is neither working nor even called.
It works only if I specify class type *NewsCell_CheckinPhoto* in the NewsCell.xib file , but that would not allow me to reuse NewsCell.xib for rendering each subclasses of NewsCell with a sample and unique representation.
When I understand you correct you want to load a cell from a XIB.
You should not do it with
UIViewController *c = [[UIViewController alloc] initWithNibName:#"NewsCell" bundle:nil];
but put only the cell in the XIB and then load it with
UITableViewCell *cell = [[NSBundle mainBundle] loadNibNamed:#"NewsCell"][0];
or similar (please check docs).
Also keep in mind when you load something like a table view cell from a XIB, it is initialised with initWithCoder:, not init, or initWithFrame:. This might be the reason, why your outlets are not intialised.

registerNib:forReuseidentifier with custom UTTableViewCell and Storyboards

I'm migrating from customizing my TableViewCells in tableView:cellForRow:atIndexPath: to using a custom UITableViewCell subclass. Here's how I done it:
First, created empty XIB, dragged UITableViewCell there and put a UILabel on top. Created a class (subclass of UITableViewCell) and in Interface Builder's properties editor set the class to MyCell.
Then, in my TableViewController, put the following:
- (void)viewDidLoad
{
[super viewDidLoad];
// load custom cell
UINib *cellNIB = [UINib nibWithNibName:#"MyCell" bundle:nil];
if (cellNIB)
{
[self.tableView registerNib:cellNIB forCellReuseIdentifier:#"MyCell"];
} else NSLog(#"failed to load nib");
}
After that I wiped out all the custom code from tableView:cellForRow:atIndexPath: and left only default lines:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"MyCell";
MyCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
return cell;
}
When I ran this, I expected to see a bunch of cells with a single label in each cell (the very label that I dropped in the middle while creating XIB). But instead I see just plain white empty cells and adding/removing the components to the XIB layout doesn't help.
I spend A DAY trying different options like setting the reuseIdentifier in Interface Builder for custom cell XIB and loading the view in tableView:cellForRow:atIndexPath:, but none helped.
...but it turned out, that the only thing that I missed, was clearing the reuseIdentifier for prototype cell in my Storyboard for this TableViewController. It seems that Storyboard initializes its views/components later that viewDidLoad called, and instead of taking my nice custom cell, xCode sets the real cell view for reusing to just plain white cell which is the standard for newly created TableViewControllers.
So again: go to your TableView properties and remove the reuseIdentifier you set before ;)
I spend so much time for this, so I thought it might help someone if I share this experience here.

UITableViewCell from a custom .XIB file doesn't create outlets

Update 2:
Long story short, I was being silly (and, in my defense, not properly educated) about this. It works now. My questions have derailed from the original topic a little bit, but that's because I wasn't understanding what was going on in my application. I would like to close the question with one last (and small) query:
I've got two labels in my customCell.xib. I want one of them (cell.label2) to sometimes contain a longer segment of text (2-3 lines). I know one way to make it all fit is to set the autoshrink property, but that shrinks to the text so it can fit on a single line. I want to preserve the original text size and expand the cell's height instead, making the text span multiple lines instead of shrinking it.
Is there a way to do this?
Update 1:
I tried a few things based on the replies below, and they got me nowhere. I am growing convinced that I am doing something fundamentally wrong, and you guys just can't think of it because it's so basic. So let's try again. I am going to changed the names a little, so they are easier to remember.
The problem seems to be in the fact that I can't create any IBOutlets or IBActions for my customCell. Right now I have 3 files that should handle this (DetailedDirectionViewCell.{h,m,xib}, but the Interface Builder doesn't allow me to create a property/outlet/reference out of my UITableViewCell object - anywhere.
Instead of copying the code here, I've provided a PasteBin entry with links to my code. As before, I've removed the less interesting methods. Take a look if you will.
http://pastebin.com/p4eADhKQ
I also have customCell.{h,m}, but those are just new Objective C class files that inherit from UITableViewCell. customCell.xib is just a cell with two labels.
So I have a couple of problems really.
First, generating a UITableView programmatically, using a custom UITableViewCell contained in a .XIB file of its own. My DirectionsViewController class is just a UITableView with programmatic cells. Tapping on one of the cells needs to present a DetailedDirectionsViewController table (in a modal way), the cell design for which sits in a DetailedDirectionsViewCell.xib file. The problem is, I can't create an IBOutlet for the UITableViewCell from the nib file - anywhere. Dragging the File's Owner icon/outlet doesn't offer to create anything. Which, after 5 hours of struggling, means that I can't present my detailed view.
The second problem involves adding a navigation bar to the DirectionsViewController, but let's leave that alone for now.
Here are some methods you might find helpful:
//inside DirectionsViewController
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)
{
DetailedDirectionsViewController *vc = [[DetailedDirectionsViewController alloc] initWithStyle:UITableViewStyleGrouped];
vc.instruction = [turnList objectAtIndexPath:indexPath.row];
[self.tabBarController presentModalViewController:vc animated:YES];
}
//inside DetailedDirectionsViewController
- (UITableViewCell *) tableView:(UITableView *) cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"directionsCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
[[NSBundle mainBundle] initWIthNibNamed:#"DetailedDirectionsViewCell" owner:nil options:nil];
cell = self.tableViewCell;
self.tableViewCell = nil;
}
//here I configure the custom cell
return cell;
}
I don't think the rest of the methods are of interest, because they are either working as expected, or are pretty much the default ones.
To sum up:
DirectionsViewController - essentially a UITableViewController with custom cells. No .xib file
DetailedDirectionsViewController - detailed information about the entries from DirectionsViewController. Cells here should come from a .XIB file, but that's broken.
DetailedDirectionsViewCell - this is the custom cell. I can't set its File's Owner.
Ok.. You do not create IBOutlet connection from File's Owner. Have a look at a screenshot. You create IBOutlet from CustomCell's view(with Red Arrow).
Looking after your code just follow these steps.
1) Goto CustomCell.h file. As you are saying customCell.xib has two UILabels(assume label1 & label2) you gonna have to declare properties and create outlets in CustomCell.h file and in .m file synthesize and release it. Refer this code screen of mine.
2) Now in CustomCell.xib, select view of CustomCell not File's Owner(File's Owner should inherit from NSObjectonly) go to Identity Inspector(Marked with Red Ellipse) and select the corresponding Customcell class (marked with Red rectangle).
3) Right click your customcell's view and make connections to labels. And save it..
4) In your DirectionsViewController.m you have this UITableView's delegate method cellForRowAtIndexPath. Change it like this :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CustomCellIdentifier = #"CustomCell";
EditProjectCustomCell *cell = (EditProjectCustomCell *)[tableView dequeueReusableCellWithIdentifier: CustomCellIdentifier]; // typecast to customcell
[cell setSelectionStyle:UITableViewCellSelectionStyleBlue];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"EditProjectCustomCell" owner:self options:nil];
for (id oneObject in nib)
if ([oneObject isKindOfClass:[EditProjectCustomCell class]])
cell = (EditProjectCustomCell *)oneObject;
[cell setSelectionStyle:UITableViewCellSelectionStyleBlue];
}
cell.label1.text=[someArray1 ObjectAtIndexPath: indexPath.row];
cell.label2.text=[someArray2 ObjectAtIndexPath: indexPath.row];
return cell;
}
this delegate method is gonna be called as many times as you returned value in numberOfRowsInSection DataSource method. Every time cell.label will be blank and you will add data to label by calling this line. so no need to create label each time as you did between line 79-90 here. http://pastebin.com/Vd4PKjTu
cell.label1.text=[someArray ObjectAtIndexPath: indexPath.row];
Creating custom cell means you create UI(i.e. .xib),interface & implementation (.h,.m file) for UITableViewCell by yourself and adopt them in your class's (i.e. DirectionsViewController.m) cellForRowAtIndexPath delegate method.
To load a custom cell, I've used this code (test it and it's working)
static NSString *CustomCellIdentifier = #"CustomCommentIdentifier";
detailedDirectionsViewCell *cell = (DetailedDirectionsViewCell *)[tableView dequeueReusableCellWithIdentifier:CustomCellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"DetailedDirectionsViewCell" owner:self options:nil];
for (id oneObject in nib)
{
if ([oneObject isKindOfClass:[DetailedDirectionsViewCell class]])
{
cell = (DetailedDirectionsViewCell *)oneObject;
}
}
}
and make sure that you changed the cell class nib file as the following:
Click on the files owner, change the type of it to NSObject (this for not to confuse when connect the Outlets.
Remove any view you have in the nib file, then, drag and drop a UITableViewCell component.
Change the super class of the component to the Cell class, in your case, change the cell from UITableViewCell to DetailedDirectionsViewCell.
Connect the outlet.
This should work, let me know if you have any question.
To answer your last question in Update 2, did you consider using a text field instead of a label? You should be able to disable editing so the user can't change what is displayed. If you need it to be a label, in the Attributes Inspector for the label, there is a property called "Lines" under the "Label" drop down that you can adjust. I'm not sure how to access that property programmaticly, but a quick Google search should help you out there.
In my case I had two different views for one cell class. And when I connected outlets to .h file they were connected only to the first view representation, not the second.
So to ensure that your outlets are really connected go Xcode me menu and open View -> Utilities -> Show FileConnection inspector, then make sure that your view's outlets are really connected.

left+right aligned text in UITableView cell, breaks when table is scrolled

My goal is to display 2 strings in the same cell, one of them left aligned and the other right aligned. The code I have attached does just that in a table view, however it breaks when you scroll up/down. I need this to work in a table that can scroll. Someone had mentioned using CustomUITableViewCells instead of my current method, can anyone point me to an example of this?
// 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] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
UILabel *rank = [[UILabel alloc] initWithFrame:CGRectMake(5, 5, 100, 20];
[rank setTag:5];
[cell.contentView addSubview:rank];
[rank release];
UILabel *item = [[UILabel alloc] initWithFrame:CGRectMake(110, 5, 220, 20];
[item setTextAlignment:UITextAlignmentRight];
[item setTag:6];
[cell.contentView addSubview:item];
[item release];
}
UILabel *rank = (UILabel *)[cell viewWithTag:5];
UILabel *item = (UILabel *)[cell viewWithTag:6];
rank.text = #"leftside";
item.text = #"rightside";
}
Any ideas and thoughts greatly appricated, thanks for lookin
This problem is because of dequeueReusableCellWithIdentifier. While the cell is being re-used, and when you scroll up and down it will cause major problems as labels are being added as subviews to the cells and they do not have the properties of the cell. However, if you use the cell.textLabel as your label, it would not cause problems like the one you are facing now, but you cannot add more than one label.
You have two solutions for this.
In your case, you need to stop using the same cellIdentifier for each and use different identifiers for each cells so that they do not get reused. This would be helpful if you have a very small number of rows in the tableView or it would turn out to be inefficient.
A better solution would be to subclass UITableViewCell and add those two labels in it's code, and then use that UITableViewCell with dequeueReusableCellWithIdentifier. This is just a small amount of work, and you get to re-use cells. This would be very helpful if you have a large number of rows in your tableview.
Go through THIS TUTORIAL to learn on how to subclass UITableViewCell with 2 labels.
You will need to work with the method, - (void)layoutSubviews and add those labels to your custom UITableViewCell subclass.
And remember to reference this customUITableViewCell instead of the default uitableviewcell when you are loading up the tableView. Your UILabels will not be messed up anymore.
Another reference.
Well, I have paste the same code that you have posted and I got 2 compiler error mentioning the ) is missing at the allocation of UILable and as I have clear it out, its compiled and started successfully.
The only exception and crash I have faced and that was due to the datasource method is not returning any cell. And that is also missing in given code.
Beside that, the code is working perfectly at my end and not having a single crash even though I scrolled many times.
So, just verify your code again or there should be another problem regarding datasource provided by array and also check the number of rows in section.
I would use a custom UITableViewCell. The easiest way is to just download a sample project, and copy and paste to see how you set up a custom cell. This is a good tutorial with a sample project included. You can use if (indexPath.row == int) in the cellForRowAtIndexPath method to determine which cells should be the standard ones, and which should be your custom cell.

iPhone dev - Having problems adding text to cells of a UITableView

I am trying to make an app that will display a bunch of different people's names and address in different cells of a UITableView. First I'm just trying to get the hand of adding text to the cells, and it's not really working. I have the following code, where myTableViewController is just a subclass of UITableViewController that loads in its view from a nib (without any drastic customizations):
myTableViewController * tvc = [[myTableViewController alloc] initWithStyle:UITableViewStylePlain];
NSIndexPath *path1 =[NSIndexPath indexPathForRow:0 inSection:0];
NSIndexPath *path2 =[NSIndexPath indexPathForRow:1 inSection:0];
[self presentModalViewController:tvc animated:YES];
UITableViewCell * cell1 = [tvc.tableView cellForRowAtIndexPath:path1];
UITableViewCell * cell2 = [tvc.tableView cellForRowAtIndexPath:path2];
cell1.textLabel.text = #"test";
cell2.textLabel.text = #"test2";
I was expecting to see a tableView animate onto the screen, followed by the first and second cells being filled with the text "test" and "test2" respectively. What I get is a blank tableview animating onto the screen. Then if I scroll down so that the top cell is hidden and scroll back up so that the top cell is again visible, the top cell will now have the text "test" in it. But the second cell down never shows any text, just the top one.
Can someone please point me in the right direction? I also would like to have the text in the tableview BEFORE it loads onto the screen, but it looks like the cells don't exist unless they are being displayed. Please help me.
Populating a table view takes the form of a data-source pattern, where the table view calls your data source object for data to put in individual cells.
Try reading through the Table View Programming Guide.
You should use the delegate and the datasource protocol methods.