How to make UITableView look like the one in Contacts? - objective-c

I'm trying to make UITableViewController look like following.
(it has picture and several rows for someone's identify.)
I wonder how to make like following programmatically.
How to adjust UITableViewCell's origin.x and width?
How to add a picture at left top?
Please help me.. I will thank you.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell;
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SimpleTableIdentifier];
cell.frame = CGRectMake(50, 0, 250, 44) <--- ?????? I think this is wrong way.
return cell;
}

My best bet is that either there are two static UITableViews inside a UIScrollView or that it's some custom subclass UIView set as tableHeaderView and styled to look as on the picture. If I were to implement it I'd go with the second choice.

Make a subclass of UITableView. Give your subclass properties referring to the photo well and the three special row cells.
Override layoutSubviews to call [super layoutSubviews] and then set the frames of the photo well and the three special row cells.
The photo well should not be a cell.

Related

Drawing + UITableViewCell + UIScrollView subclass?

My (rather complicated) situation is as follows:
TestView is a subclass of UIScrollView which implements -drawRect:, but at some point inside -drawRect: it'll call a method, let's say -drawAnotherPartWithRect:context:. This method is implemented by subclasses of TestView to draw individually a certain part of the context.
There are two subclasses of TestView which implement -drawAnotherPartWithRect:context:, which currently do the same thing inside it: Subclass1 and Subclass2.
As of now, frame size is the only different between the two during initialization.
An instance of Subclass1 is used as a table view's section header, and it works perfectly, yet if Subclass2 is used as a subview of the cell's content view, it'll display, yet not scroll. Its initialization is as follows:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"PortoAppSubjectViewTableViewCell"];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"PortoAppSubjectViewTableViewCell"] autorelease];
Subclass2 *contentView = [[[Subclass2 alloc] initWithFrame:CGRectMake(0.f, 0.f, [tableView bounds].size.width, 32.f)] autorelease];
[contentView setContentSize:CGSizeMake(tableView.bounds.size.width * 3, 32.f)];
[contentView setTag:55];
[[cell contentView] addSubview:contentView];
}
[(SubjectTableViewCellContentView *)[[cell contentView] viewWithTag:55] setContainer:[[[[$container subGradeContainers] objectAtIndex:[indexPath section]] subGradeContainers] objectAtIndex:[indexPath row]]];
return cell;
}
The interesting thing is, the horizontal scroll indicator shows up and shows me that it's scrolling finely, yet the text (drawn with CoreText) doesn't move left/right along with it. That works out-of-the-box with Subclass1. Additionally, if Subclass2 is used instead as the view class of the section header view, it'll work finely.
So, what's up with horizontal scroll views and table view cells? I've checked out other related questions on SO but haven't been able to find any solution.
I solved the issue by instead of drawing directly to a UIScrollView subclass, drawing to a UIView subclass added as a subview of UIScrollView.
I'd still like some follow-ups, therefore leaving the question unanswered – why did it work with the header view and not with the table view cell then?

Setting Text Color on Static UITableViewCell

I have static cells and want to change text colour. I've made an outlet for the label. In the implementation i'm using
sine.textColor=[UIColor colorWithRed:191 green:48 blue:48 alpha:1.0];
In this case the text colour shows white. However if I use sine.textColor=[UIColor redColor]; it comes up red as expected. How?
Is there any way to change all text labels in one table view controller with one code (so i wouldn't need an outlet for every cell)?
1) UIColor requires a float from 0-1. (That really bugs me too) You can divide values by 255.0 like:
[UIColor colorWithRed:191.0f/255.0f green:48/255.0f blue:48/255.0f alpha:1.0]
In method
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
set cell.textColor = [UIColor yourColor];
The way to do this for a STATIC cell is to create OUTLETS for all your cells, and change each individually... Otherwise you have to do this dynamically.
In your .h file:
#property (weak, nonatomic) IBOutlet UITableViewCell *myCell;
In your .m file
[self.myCell.textLabel setTextColor:[UIColor blackColor]];
For clarification the colour change should look like: cell.textLabel.textColor = [UIColor colorWithRed:191.0f/255.0f green:48.0f/255.0f blue:48.0f/255.0f alpha:1.0]; (from UIColor forward you can put whichever RGB values your heart desires) thanks Tier
However -(UITableViewCell *)tableView:(UITableView) *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath; doesn't work (for changing all cells' labels with one code ... maybe it's for DYNAMIC cells , however I'm looking for STATIC cells.

UITableViewCell UIButton dynamic height

I have CustomCellView which is custom view for cell in tableview. I have UIButton in xib and set it's default frame in xib.
In MainViewController (viewDidLoad)
// Get nib for custom cell
UINib *nib = [UINib nibWithNibName:#"CustomFeedCell" bundle:nil];
[self.mainTableView registerNib:nib forCellReuseIdentifier:#"CustomFeedCell"];
In cellForRow...
CustomFeedCell *cell = [self.mainTableView dequeueReusableCellWithIdentifier:#"CustomFeedCell"];
// here i need to set UIButton frame (height) depending on image height.
// I have tried diferent ways and it always return height set in CustomCellView xib
If you want to create buttons, images etc in UIView dynamically, you have to use viewDidLoad: method and do not use xibs.
Ok so what I am understanding from your question is you are having problem setting the dynamic height of a button present in your tableview cell. It sometimes might be more then the height of the cell and sometimes quiet less then height of the cell. And you want to adjust it accordingly. Correct ?
If thats your problem then you can set height of your each tableview cell in its delegate
tableView:heightForRowAtIndexPath:
as
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return [indexPath row] * 20; // your desired height
}
Hope this solves your problem.

Updating subviews in cells on a UITableView

I'm developing an application in iPad 6.0 using Storyboards.
Let me first explain my goal. I'm trying to achieve a Master-Detail (SplitViewController-like) View Controller using 2 UITableViewControllers.
The first UITableView("Master"), let's call this HeaderTableView, as the name implies, lists down the Headers for the...
...Second UITableView("Detail"), let's call this the EncodingTableView, which contains a programmatically changing CustomTableViewCell (subviews contained within each cell may be a UITextField, UIButton or UISwitch).
See EncodingTableView.m
- (void)updateEncodingFields:(NSArray *)uiViewList
{
// Add logic for determining the kind of UIView to display in self.tableView
// Finally, notify that a change in data has been made (not working)
[self.tableView reloadData];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *encodingFieldsTableId = #"encodingFieldsTableId";
CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:encodingFieldsTableId];
if (cell == nil) {
cell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:encodingFieldsTableId];
}
// Change text in textView property of CustomTableViewCell
cell.encodingFieldTitle.text = uiViewList.title;
// added methods for determining what are to be added to [cell.contentView addSubView:]
// data used here is from the array in updateEncodingFields:
}
My HeaderTableView.m, contains the didSelectRowAtIndexPath to update the EncodingTableView
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (![selectedIndexPath isEqual:indexPath]) {
selectedIndexPath = indexPath;
[self updateDataFieldTableViewForIndexPath:indexPath];
}
}
- (void)updateDataFieldTableViewForIndexPath:(NSIndexPath *)indexPath {
[self.encodingTableView updateEncodingFields:self.uiViewList];
}
Question
- Data is all ok but why doesn't EncodingTableView "redraw"ing the fields? My
suspicion is that reusing cells has something to do with this but I just can't figure out why.
Screenshots on the result:
Initial Selection in HeaderTableView
Second Selection in HeaderTableView
What I've tried :
I kept seeing suggestions such as [UITableView setNeedsDisplay],
[UITableView reloadData] and [UITableView setNeedsLayout] but none of
them worked.
Removing the reuse of tableViewCells works fine but this causes parts of my
CustomTableView.encodingFieldTitle to disappear. Not to mention that this might cause performance issues if I were to drop reusing cells.
Restrictions:
I know that a good idea is to use a SplitViewController but this is just a subpart of my app (hence not the RootViewController).
Finally, thanks for reading such a long post. ;)
It looks like you are most likely adding subviews inside tableView:cellForRowAtIndexPath:.
The issue is that if you use cell reuse then are not always starting from a blank slate inside tableView:cellForRowAtIndexPath: instead you can possibly be given a cell back that has already been configured once. This is what you are seeing, a cell that has previously had labels added to it is handed back to you and then you add some more labels over the top.
There are a few way to deal with this:
(My preferred option) Create a subview of UITableViewCell with these extra sub views available as properties.
Ensure the cell setup is only done once
A great place to do this is when you actually create a cell when one does not already exist e.g. inside the if (cell) check
if (cell == nil) {
cell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:encodingFieldsTableId];
// add subview's here and give them some way to be referenced later
// one way of doing it is with the tag property (YUK)
UILabel *subView = [[UILabel alloc] initWithframe:someFrame];
subView.tag = 1;
[cell.contentView addSubview:subView];
}
UILabel *label = (id)[cell.contentView viewWithTag:1];
label.text = #"some value";
One problem i can see in your code is that the cell identifiers used are different in tableView cellForRowAtIndxPath function.
While dequeueing you are using this identifier - > "encodingFieldsTableId"
&
while creating a cell you are using this identifier - > "dataFieldUiGroupTableId".
Ideally these two identifiers should be same !!!
Try adding,
cell.encodingFieldTitle.text = nil;
Before if(cell == nil)
So that whenever your cellForRowAtIndexPath method is called, the string already present in the cell you are going to reuse will get deleted and the new text in uiViewList.title will be displayed.

Customization tableView

How I can add a bar with 3 UIButtons above a UITableView? Please, I need examples. I want to make it like this.
You can create a cell in your storyboard that contains a segment controller on it.
Now in the
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
You can dequeue that cell for the first on in the table.
In your viewDidLoad, create a UIView with a clear background colour.
Then, create a UISegmentedControl and add that as a subview to the clear view.
Finally, set your clear view as the table header view:
self.tableView.tableHeaderView = myClearView;
Bar is called as segmented control in iPhone.
To create it sub class UIViewControl class and add segmented control on top and then add UITableView below that better you can use Xib or you can find Coordinates and add both controls programatically.
refer to this link
you can do by implementing Header View Section delegate methods for your UITableView in your ViewController
In the following delegate method, give the size of your view you want to implement
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 60.0f;
}
Implement UISegmentedControl to get your three buttons and implement that in your viewForHeaderInSection method
-(UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc]initWithItems:segments] autorelease];
segmentedControl.frame = GRectMake(60, 10, 200, 40);
........
// Do other Stuffs of Segmented Control
........
return segmentedControl;
}