UITableViewCell UIButton dynamic height - objective-c

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.

Related

iOS: Dynamic Height For UITableViewCell

I'm using iOS9 XCode7
I need to change the height of cell Dynamically according to labelText Height
I have used:
self.tableView.rowHeight=UITableViewAutomaticDimension;
But it is not working for custom made cell.
sizetoFit is removed in iOS9.
Please suggest something.
Thanks
Give your label constrains relative to the cell, top, bottom, left and right.
Than your cell size will grow with the content height.
also make your label multiline.(by setting Lines property to 0 in attribute inspector)
#pragma mark- Menu table Delegates
-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewAutomaticDimension;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewAutomaticDimension;
}
I'm not quite sure what this sentence means (a screenshot would've helped):
"I need to change the height of cell Dynamically according to labelText Height"
So, you have a UITableViewCell, containing a UILabel, and want each cell in your table to have a height depending on that cell's label ?
Here's the code I use.
In my UITableViewCell class, I'll define a static function to measure, and return the height of my .xib file:
#implementation MikesTableViewCell
...
+(CGSize)preferredSize
{
static NSValue *sizeBox = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// Assumption: The XIB file name matches this UIView subclass name.
NSString* nibName = NSStringFromClass(self);
UINib *nib = [UINib nibWithNibName:nibName bundle:nil];
// Assumption: The XIB file only contains a single root UIView.
UIView *rootView = [[nib instantiateWithOwner:nil options:nil] lastObject];
sizeBox = [NSValue valueWithCGSize:rootView.frame.size];
});
return [sizeBox CGSizeValue];
}
#end
Then, in my UIViewController class, I'll tell my UITableView to use this cell, find out it's height.
#property (nonatomic) float rowHeight;
UINib *cellNib = [UINib nibWithNibName:#"MikesTableViewCell" bundle:nil];
[self.tableView registerNib:cellNib forCellReuseIdentifier:#"CustomerCell"];
rowHeight = [MikesTableViewCell preferredSize].height;
...
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return (float)rowHeight;
}
Again, this might not be exactly what you're looking for, but I hope this helps.
try this.
it is so simple.
set this height in heightForRowAtIndexPath method
float vendorNameHeight = [vendorNameLbl.text heigthWithWidth:width andFont:[UIFont fontWithName:#"Signika-Light" size:21.0]];
then
UILabel*vendorNameLbl=[[UILabel alloc]initWithFrame:CGRectMake( 13, 11, 100, 22)];
vendorNameLbl.numberOfLines = 0;
[vendorNameLbl sizeToFitVertically];

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?

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

How to make UITableView look like the one in Contacts?

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.

What are the possible reasons why -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath didn't get called?

I got a really strange problem.
My tableView has all the delegate and datasource set up.
Everything is fine.
However, clicking the rows do not activate:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
I used custom cells.
After I click and click and click and click and click, sometimes it goes through.
I wonder what can possibly cause that? It's as if the customCell is "absorbing" the touch event or something or what?
Could that be why? If so, if we want to implement customCell and we want the tableView to handle the touch up event, what should we do?
Additional symptom:
If I remove user interaction enabled from the custom cell then the problem is solved with a catch.
However, clicking the button will somehow erase all the label texts in the customCell.
The implementation of the custom Cell is the following:
- (BGUIBusinessCellForDisplay *) initWithBiz: (Business *) biz
{
if (self.biz == nil) //First time set up
{
self = [super init]; //If use dequeueReusableCellWithIdentifier then I shouldn't change the address self points to right
NSString * className = NSStringFromClass([self class]);
//PO (className);
[[NSBundle mainBundle] loadNibNamed:className owner:self options:nil];
self.frame =self.view.frame;
[self addSubview:self.view]; //What is this for? self.view is of type BGCRBusinessForDisplay2. That view should be self, not one of it's subview Things don't work without it though
}
if (biz==nil)
{
return self;
}
_biz = biz;
self.prominentLabel.text = [NSString stringWithFormat:#"Isi: %#", biz.isiString];
self.Title.text = biz.Title; //Let's set this one thing first
self.Address.text=biz.ShortenedAddress;
//if([self.distance isNotEmpty]){
self.DistanceLabel.text=[NSString stringWithFormat:#"%dm",[biz.Distance intValue]];
self.PinNumber.text =biz.StringPinLineAndNumber;
NSString * URLString=nil;
if(biz.Images.allObjects.count!=0){
//self.boolImage=[NSNumber numberWithBool:true];
Image * image=(biz.Images.allObjects)[0];
URLString = image.URL;
URLString = [NSString stringWithFormat:#"http://54.251.34.144/thumbnailer/Thumbnailer.ashx?imageURL=%#",URLString.UTF8Encode];
//url=[NSURL URLWithString:image.URL];
}else{
float latitude = biz.getCllLocation.coordinate.latitude;
float longitude = biz.getCllLocation.coordinate.longitude;
URLString = [NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/staticmap?&zoom=16&size=160x160&maptype=roadmap&sensor=true&center=%f,%f&markers=size:small|color:blue|%f,%f",latitude,longitude,latitude,longitude];
URLString = URLString.UTF8Encode;
}
//Should add code and add loading indicator here
[BGHPTools doBackground:^{
UIImage * imageBiz = [BGMDImageCacherAndDownloader getImageFromURL:URLString];
[BGHPTools doForeGround:^{
self.Image.image=imageBiz;
[self.Image makeRound];
}];
}];
//self.view=self.view;
/*if (self.tableViewCell == Nil)//Instantiate that tableviewCell
{
PO(self.tableViewCell);
}
self.tableViewCell.business = bis;
self.pinLbl.text = bis.StringPinLineAndNumber;
self.lblTitle.text=bis.Title;
//self.pinLbl.text=bis.pinNumber;*/
//}
/*self.name=[dict objectForKey:#"Title"];
self.address=[dict objectForKey:#"Street"];
CLLocation * cll=[[CLLocation alloc]initWithLatitude:[[dict objectForKey:#"Latitude"] doubleValue] longitude:[[dict objectForKey:#"Longitude"] doubleValue]];
self.distance=[NSNumber numberWithDouble:[cll distanceFromLocation:[cachedProperties currentLocation]]];*/
return self;
Update: I already figure out why the texts are gone. Turns out my background is white. When a row got selected, the text suddenly turn into white. So by setting selected style to blue I sort of get that "fixed".
However, I still do not see where in my code I specify that all label texts should be white if the underlying tableViewCell is selected.
After all, what's selected is the cell, not the label. How the hell the label knows that it has to turn white is beyond me.
If you are using a Storyboard to handle the interface, instead of using:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
Try using
#pragma mark --- Push selectedObject to the detailView ---
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
RRAppDelegate *myAppDelegate = [[UIApplication sharedApplication]delegate];
if ([[segue identifier] isEqualToString:#"PushObjectSegue"]) {
NSIndexPath *selectedRowIndex = [self.tableView indexPathForSelectedRow];
RRObjectViewController *detailViewController = [segue destinationViewController];
detailViewController.selectedObject = [myAppDelegate.goals objectAtIndex:selectedRowIndex.row];
}
}
I was having the same problem with the method you used and instead used this, it started working perfectly. Of course you'd have to adapt the code to your app's viewControllers and data source because I used my AppDelegate as the datasource, and I wasn't using a custom cell.
The most likely thing is that a view in your custom cell is absorbing the touch. Sometimes this is what you want, e.g. a button that does something, rather than selecting the entire cell. Assuming you don't want this, then just set those views' userInteractionEnabled property to NO.
--Additional code for custom NIB loading.
All you have to do is register the NIB in your viewDidLoad routine:
[tableView registerNib: [UINib nibWithNibName:#"yourCellNibName" bundle:nil] forCellReuseIdentifier:#"yourCellTypeID"]
and then in your cellForRowAtIndexPath just call:
newCell = [tableView dequeueReusableCellWithIdentifier #"yourCellTypeID"];
...
return newCell;
And it will load a cell from your XIB (or give you one from the previously used queue).
I just want to update that I think I have figured out what the problem is but still can't solve that quite right yet. And well the update is comprehensive so I think it should be an answer though I hope it's not the answer because some puzzle is still missing.
All the problem is interrelated.
The problem is in this line:
[self addSubview:self.view];
I basically turn that into:
Basically the my custom view cell has a view whose type is also tableViewCell. That view cover the real tableViewCell.
That's why when user interaction is enabled, that view will absorb the user's interaction.
That's also why the label "disappear". What happen is the label doesn't disappear. The label got highlighted and become white. However, what's highlighted is the tableViewCell not the opague view. The white opague self.view is still white while the tableCell itself is tinted with blue. So the label becomes white in the middle of white background and is gone.
I think I should replace [self addSubview:self.view] into self= self.view
However, that would mean changing the value of self. Yes it's in init. But it's still awkward. If anyone has the WAY to implement custom subclass of UI with XIB it'll be great because I haven't found one till now.
Awkward.
I wonder if we can draw a pointer to an XIB and specify that the outlet is self itself.
If that fail, I'll set background of self to white and background of self.view to transparent.
After tons of error and trying I did this:
self.contentView.backgroundColor = [UIColor whiteColor];
//self.view.backgroundColor = [UIColor redColor];
self.frame =self.view.frame;
/*PO(self.view.subviews);
PO(self.subviews);
PO(self.Title.superview);
PO(self.Title);
PO(self.view);
PO(self.Title.superview);
PO(self.view.contentView);*/
//Suck all the subviews from my minions
for (UIView* aSubView in self.view.contentView.subviews) {
[self.contentView addSubview: aSubView];
//[self.contentView add]
}
Basically I "move" all the subViews of my view object to my self object. There is a catch though that when subclassing tableViewCell I should move the subviews of the contentView. Who knows why.
At the end I just set self.view to nil for it's no longer needed and my program works as expected.
Also to set background of your tableViewCell, you need also to set the background of self.contentView rather than self.view.
Another approach you can try is to use story board. Alternatively you can just move the contentView of the self.view to self.
Make sure you'r implementing that method and not
deselectRowAtIndexPath:animated