I want to wrap the word in section index displaying on the right side of the UItableView.
The problem is that, if the word length increases the section index width also increases and table view cell content view size reduces.And I do not want to display substring of section index array object.Since I want to display whole word in the section i have to wrap it.
-(NSArray*) sectionIndexTitlesForTableView:(UITableView *)tableView
{
NSMutableArray *array = [[NSMutableArray alloc] init];
for (int i = 0; i <[keys count]; i++) {
NSString *str = [self.keys objectAtIndex:i];
[array addObject:str];
}
NSArray *a =[NSArray arrayWithArray:array];
[array release];
return a;
}
object in the array return by sectionIndextitle method is lengthy and I want to wrap the word.
Any one knows how it can be done?
you can only create your own "section index view" as a custom UIView
and it's eazy to do that
just calc the height of your tableview , calc the count of your sections
then draw your section title on it in
- (void)drawRect:(CGRect)rect
then detect the touch event
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
calc which section you touched , then call the tableview method
- (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated;
then put it on your tableview, eazy done!
It seems that your answer is no but the following should solve the problem behind your question.
I would use this function instead tableView:viewForHeaderInSection: on the UITableViewDelegate protocol. More information can be found in the documentation here UITableViewDelegate Docs. Note – tableView:heightForHeaderInSection: must also be implemented. This combination of functions will allow you to return a view with a UILabel subview that has numberOfLines set to 0, i.e. as many as necessary, and the text set to whatever value you need.
It is not possible to wrap section indexes to multiple lines. This wouldn't make sense in the default UI. A custom header is your best bet to accomplish this.
Create a custom title header for section. There you can use the label and assign the number of lines into it on the basis of length of the title. You will also need to set height of section header accordingly.
Just check the 'str' before adding it in NSMutableArray, is it having one or more word?
and select the range how much you want and add it in your array..
USe NSmakeRange to make the range of characters, that you want to show in index of the each section..
Related
Here i need to hide the phone number, email , birthDate, anniversary date and other labels in case there is no values for those fields. How can i do this?
Many ways, starting with the simplest:
self.emailLabel.hidden = YES;
But you probably want to reformat the other parts of the view to fit the empty space. Keeping it simple, you would then do something like this:
self.phoneLabel.frame = CGRectOffset(self.phoneLabel.frame, 0, -self.emailLabel.bounds.size.height);
... and so on for anything below. But you can see how this would become tedious. The next and probably best alternative is a UITableView that adjusts it's section count based on whether some of that data is present. That would go like this. Prepare a mutable array of arrays with the parts of your model and their values.
- (void)prepareModel {
self.model = [NSMutableArray array];
[self.model addObject:#[#"Name", #"Judy"]; // get "Judy" from your data
if (/* model has email */) {
[self.model addObject:#[#"Email", #"judy#gmail.com"]; // get email from your model
}
// and so on for conditional parts of your model
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return self.model.count;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
return self.model[section][0];
}
And the cellForRow would init the cell using self.model[section][1].
What you can do is simply hide the UILabel's if the value for the NSStrings that you are putting them in is NULL/nil .
NSString *labelString;
if([labelString length]>0)
{
}
else
Label.hidden = YES;
It is probably a better idea to use a UITableView to do this, by putting the labels in rows of the tables. If the labels are empty, you can delete the table rows and iOS will dynamically resize the table height for you.
I am producing a JSON string that I need to parse out and display onto the page. My JSON string outputs information about the contents of a CD like this:
[{"song_name":"Song 1","artist":"John","price":"$1"},
{"song_name":"Song 2","artist":"Anna","price":"$2"},
{"song_name":"Song 3","artist":"Ryan","price":"$3"}]
I would like to display the contents in my viewController in a list format displaying the song_name, artist, and price. I do not want to use a tableView to display this information, but would rather just have a list displayed. How might I go about doing this? I would assume that I need to use NSJSONSerialization, but have only used that for a tableView in the past. Thank you!
In addition to other answers, you can use only one label, just create NSMutableString (for dynamicly adding tracks info) with #"\n" between tracks info, pass it to label.text and set UILabel's property numberOfLines to 0
Follow these steps:
Parse the JSON and store the key-value pair(NSDictionary of CDs) in an NSArray (say infoArray)
Add a UIScrollview as a subview on your viewController's view.
Allocate UILabels dynamically, depending on infoArray count. Looking at your data I believe you can initialize labels with static frames i.e your y can remain static.
Add the text from the infoArray on this label.
Still, I would suggest use UITableView only. It is much simpler and a better approach
You make an array of dictionaries using NSJSONSerialization indeed, then you parse this array one by one and create a view of every dictionary. You're probably best of using a method for this:
-(UIView *) listView: (NSString *)songName andArtist:(NSString *)artist andPrice:(NSString *)price andIndex:(int)viewIndex {
//create your view here and do anything you want
UIView *subView = [[UIView alloc] init] autoRelease];
subView.frame = CGRectMake(0, viewIndex * 70, self.view.frame.width, 70);
//add labels and other stuff
// return the view
return subView;
}
The you add it to the current view by setting different Y values so they appear underneath each other by using the viewIndex of the former method... So if you have an array it goes something like this:
for (int i = 0; i < [array count]; i++) {
NSDictionary *dict = [array objectAtIndex:i];
NSString *songName = [dict valueForKey:#"song_name"];
NSString *artist = [dict valueForKey:#"artist"];
NSString *price = [dict valueForKey:#"price"];
UIView *tempView = [self listView:songName andArtist:artist andPrice:price andIndex:i];
[self.view addSubView:tempView];
}
You have to add it all to a scrollview otherwise you will run into the problem of to many rows on the page. Google for UIScrollView if you don't know how.
But I would recommend against this approach.. Tableviews are there with a reason. They are made for this stuff. Because the also provide for scrolling, drawing and refreshing. If you can, use them!
I want to add more columns in my iPhone/iPad application. Is it possible to add more columns in one UITableView? Can you please suggest any sample code/block/project that using multiple columns in one UITableView? Please help me. Thanks in advance.
No it is not possible, in fact UITableView is badly named a represents a List more than a Table.
If you want to have multiple column, one method is to create specific cells, with multiple label, and pack your data by row then column.
short answer is no, but you always can create custom cell what will look like multiple columns
You can use my library, UIGridView.
It is created with UITableView, in which UITableViewCell contains many cells inside.
Here is how it looks like:
No Yuvaraj.M we can't create. but you do something like multicolumn by adding component like label or image or button what u want or else using custom cell.
I've done a grid by using a table view where I have basically faked it by adding subviews to a cell. So if you for example create a cell, add three subviews to it, you can then get the items you need by doing something like this when it asks you for a cell for a specific row:
// get the items for the row (a row is one cell)
NSArray *rowItems = nil;
int startIndex = indexPath.row * NumOfItemViewsPerRow;
if (startIndex + NumOfItemViewsPerRow < [items count]) {
rowItems = [items subarrayWithRange:NSMakeRange(startIndex, NumOfItemViewsPerRow)];
} else {
rowItems = [items subarrayWithRange:NSMakeRange(startIndex, [items count] - startIndex)];
}
Then just after that you can loop the subviews of your row something like this:
[cell.itemViews enumerateObjectsUsingBlock:^(MyItemView *itemView, NSUInteger idx, BOOL *stop) {
NSDictionary *item = [rowItems objectAtIndex:idx];
itemView.titleLabel.text = [item valueForKey:#"title"];
};
It is a bit fiddly, but the upside is that you get row unloading for free from the table view, so you don't have to mess with your own custom grid views or anything like that.
Hope that helps.
How do i display set number of rows in a UITableView?
i.e if my data source has only 4 objects then i want the table to display on those 4 rows without any blank rows. any ideas?
thanks!
EDIT: i wasn't too clear about the question so..
So this is my table: http://i.stack.imgur.com/glkWZ.png ..
i want to display only the 3 rows and not the blank rows below it. The number of rows change depending on my data source.
any ideas how to go about doing so?
You have to change your table appearance, I think. Once you correctly set the numberOfSectionsInTableView: and tableView:numberOfRowsInSection: methods, you should change your viewDidLoad method adding this line:
[self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
This way you will remove all lines from the table.
If you still want to make a line appear between lines, I suggest you to create a custom UITableViewCell, or to build a standard one adding a subview to mimic the line. Eg. something like this:
CGRect lineFrame = CGRectMake(0,cell.frame.size.height-1,cell.frame.size.width,1);
UIView *line = [[UIView alloc] initWithFrame:lineFrame];
line.backgroundColor = [UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:1];
[cell.contentView addSubview:line];
[line release];
Let me know if this helps.
Check the UITableView DataSource protocol, there are two relevant methods you have to implement:
– numberOfSectionsInTableView:
– tableView:numberOfRowsInSection:
The first one should return 1, the second one 4.
If you want to keep a set number of lines in your tableview and not display the extra blank lines, you could insert a empty footer view in viewdidload function.
self.tableview.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
I did not actually understand what you mean with "display on those 4 rows without any blank rows" but I guess what you ask is just a simple data retrieval process. I suppose the data source is NSarray.
-numberOfRowsInSection:(NSInteger)section{
return [MyArray count];
}
-cellForRowAtIndexPath(NSIndexPath*)indexPath{
NSInteger row=indexPath.row;
cell.textLabel.Text=[MyArray objectAtIndex:row]
return cell;
}
I assume you know what should be put in those blank spaces.I just wrote the major points.
try this
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 4
}
also implements the rest of delegate methods required to populate tableview..
Hope it helps you.......
You can use this
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 4
}
Or you this also
Check the UITableView DataSource protocol, there are two relevant methods you have to implement:
– numberOfSectionsInTableView:
–
tableView:numberOfRowsInSection:
The first one should return 1, the second one 4.
Or you can also use
GroupBy table in your view by changing the table style to gourpby table. use
The standard Grouped UITableView style allows UITableViewCells to be drawn with rounded corners at the top and bottom of each section. How is this accomplished? How does the cell know its own location within its section, and how does it know when to change its rounded edges?
I want to make my own rounded cells, and I have images to use, but don't know when to show which image
Note: I already know how the UITableView works, and I know how to use it. I just thought that since a UITableView is able to automatically draw rounded corners at the correct places, I should be able to as well, without needing to add anything to my data source or delegate.
NSIndexPath *indexPath = [(UITableView *)self.superview indexPathForCell: self];
int rows = [(UITableView *)self.superview numberOfRowsInSection:indexPath.section];
if (indexPath.row == 0 && rows == 1) {
// the one and only cell in the section
}
else if (indexPath.row == 0) {
//top
}
else if (indexPath.row != rows - 1) {
//middle
}
else {
//bottom
}
It's very simple. suppose cell is the object, whose position is to be found out.
UITableView* table = (UITableView *)[cell superview];
NSIndexPath* pathOfTheCell = [table indexPathForCell:cell];
NSInteger sectionOfTheCell = [pathOfTheCell section];
NSInteger rowOfTheCell = [pathOfTheCell row];
There is sectionLocation method of UITableViewCell that returns integer telling you what you need:
1 - middle cell
2 - top cell
3 - bottom cell
4 - single cell
I had no issues using this in several production apps since 2010.
UPDATE: one of our binaries was automatically rejected recently (end of 2018) because we were using 'sectionLocation' property, so it's not a good option anymore.
Add something like this into your header files and you can use it:
typedef NS_ENUM(NSInteger, MMMTableViewCellLocation) {
MMMTableViewCellLocationUndefined = 0,
MMMTableViewCellLocationMiddle = 1,
MMMTableViewCellLocationTop = 2,
MMMTableViewCellLocationBottom = 3,
MMMTableViewCellLocationSingle = 4
};
#interface UITableViewCell ()
/** Undocumented method of UITableViewCell which allows to know where within section the cell is located,
* so the cell can draw its borders properly. */
- (MMMTableViewCellLocation)sectionLocation;
/** Override this one to know when the value of sectionLocation changes. */
- (void)setSectionLocation:(MMMTableViewCellLocation)sectionLocation animated:(BOOL)animated;
#end
You can use
- (NSIndexPath *)indexPathForCell:(UITableViewCell *)cell
for this issue. In my example I am using this to scroll the cell (with custom content) to the top of the view.
If you need more robust and general stuff, take a look at http://cocoawithlove.com/2009/04/easy-custom-uitableview-drawing.html - Matt Gallagher shows what you need, pretty effectively. He basically recreates UITableViewController from UIViewController, while adding ability to use your own custom graphics. I'm just working on applying this to one my projects, so far it looks it would do the job.
Unfortunately, I have found no solution to this problem, and have resorted to subclassing UITableViewController and UITableViewCell into a generic solution that I can extend as necessary.
You don't do this in cell. Rounded corners are drawn in [tableView viewForHeaderInSection] and viewForFooterInSection.
The way I do it is to use Plain tableview style, then use these two views for roundness and cells are normal, no rounds.
Without getting into who draws what, you can know which cell is the last cell in its section inside of cellForRowAtIndexPath very easily.
You're passed in the indexPath of the cell you need to provide, right? You're also passed the tableView.
call [tableView numberofRowsInSection:indexPath.section] and if it's == ([indexPath.row]-1) you know you're being asked to supply the last cell in that section.
At the time that cellForRowAtIndexPath is being called, the cell is guaranteed to be at the indexPath passed in.
To expand upon Darren's answer (which I found most useful, thanks Darren!), what you can do is to iterate through all of the superviews' until you find the parent UITableView. This should be future proof since you do not rely on a fixed hierarchy of views.
I use a recursive method that will return the UITableView if it finds one or return nil if there is none.
- (UITableView *)parentTableViewOf:(UIView *)view {
Class class = [view.superview class];
NSLog(#"Class : %#", NSStringFromClass(class));
if([view.superview isKindOfClass:[UITableView class]]) {
return (UITableView *)view.superview;
} else {
return [self parentTableViewOf:view.superview];
}
return nil;
}
So far I've used this one and it seems to work without hiccups. Hope it helps! :)
The cells dont know where they go...The table view has cells, You are the one telling the table view WHAT goes in the cell. You do this in the DataSource where you implement cellForRowAtIndexPath...The way this works :
An index path has a row and a section
For a grouped table view
A section pertains to a group, and a row pertains to 1 entry in that section,
the way UITableView knows how many rows are in a section and how many sections there are is the DataSources methods numberOfSectionInTableView and the method numberOfRowsInSection, this will make the right calls to cellForRowAtIndexPath, it is up to you to recognize which section and row is being queried and you need to build your cell according to these specifications.
A good way to do this i s you can have a Dictionary with keys of section names and values of NSArray with the values that go in that section.
So you implementation for numberOfSectionsInRows would look like
return [[dictionary allKeys] count]
And the implmentation of numberOfRowsInSection would look like
NSString* key=[[dictionary allKeys] objectAtIndex:sectionNumber]
return [[dictionary objectForKey:key] count]
You can always refer to the UITableView programming guide at http://developer.apple.com/iphone/library/documentation/UserExperience/Conceptual/TableView_iPhone/Introduction/Introduction.html
Hope that helps
Simply add a property to your custom UITableViewCell (depending on implementation) class that contains an int, NSNumber, or an NSIndexPath specifying which one it is. In you're using a data structure instead, then put it in you element in that data structure. Then you simply set the property when you create the data structure, something like elt.id=i, and then you access it in the cellForRowAtIndexPath, something like if (elt.id == 0 || elt.id == n-1) where n is the number of rows in your section.
I might have totally missed your question, but if I did, just comment and I'll post again.