iOS Change Width of UIButton in UITableViewCell - ios

In my custom UITableViewCell I have a UIButton. For a particular cell (row) object I want to change the width of the button. I tried many ways, but can't change the size of button in any ways. I am not using AutoLayout in this cell, as this button contains text and image and using auto layout am not able to set the spacing between text ands image properly.
Code of cellForRowAtIndexPath that initiates cell and calls resize function :
} else if ([text isEqualToString:#"Now"] ) { //(indexPath.row == 2) {
vcell.listDataSource = inList;
count = inList.count;
vcell.listsTableView.tag = 2;
[vcell reSizeButton];
Method in custom UITableViewCell :
-(void) reSizeButton {
CGRect btnFrame = self.button.frame;
btnFrame.size = CGSizeMake(157.0, btnFrame.size.height);
[self.button setFrame:btnFrame];
//[self.button sizeToFit];
//[self.button setNeedsDisplay];
[self.button setNeedsLayout];
return;
}
Method is being called properly. As it is being called during initing cell properties, so I don't think I need to call to reload the cell.
UPDATE :
After calling the reSizeButton method, I am calling the setText method :-
-(void) setButtonText :(NSString *) text withCount:(int)count isExpanded:(BOOL)expanded {
titleText = text;
countNums = count;
cellExpanded = expanded;
[self updateButtonText];
return;
}
-(void) updateButtonText {
countNums = (int)[self.listDataSource count];
NSString *str = [NSString stringWithFormat:#"%# (%d) ", titleText, countNums ];
[self.button.titleLabel setFont:[UIFont fontWithName:#"OpenSans" size:12.0] ];
[self.button setTitle:str forState:UIControlStateNormal];
//[self.button sizeToFit];
[self.button setNeedsLayout];
return;
}
Maybe his be causing the problem....
Can you point where am I going wrong ? Since long am trying with this, but couldn't solve it. Thanks.

Thanks #Greg and #Grzegorz Krukowski . Thanks for your time and effort to help me.
Don't know what was the problem, but I again un-checked (which was already unchecked) AutoLayout checkbox from xib for the cell. Tried again. My Code remains same as shown in question. And it started to work as expected.
Godness, can't recognize the problem and solved the issue.

Related

Why can't I access to nested UIView from viewWithTag method using StoryBoard?

I created some UIImageViews inside a nested UIView by Storyboard and I created a different TAG for each UIImageView. This is how the tree of the ViewController looks according to Storyboard:
ViewController
View
ViewNested
UIImageView1
UIImageView1
UIImageView1
UIImageView1
I have to change programmatically these ImageViews so, to get the images I use the method viewWithTag but it doesn't work because it returns NIL.
This happens even if I add to my class the ViewNested IBOutlet and getting the views using the following code:
// View is the top View with Tag:40
UIView * view = [self.view viewWithTag:40]; //This works
// The nestedView with Tag:44
UIView * viewNested = [view viewWithTag:44]; //DOESN'T work it returns NIL even if the TAG is exact
Then if I try to access to the imageView using the same method of course, it returns NIL. I don't know why, I also tried to use this code to view all the recursive nested view but it seems that they don't exist even if they are present in the storyboard.
- (void)showAllSubView:(UIView *)view
{ int i = 0;
for (UIView * subView in [view subviews]) {
NSLog(#"%#, tag:%ld", subView, (long)subView.tag) ;
[self showAllSubView:subView] ;
i++;
}
NSLog(#"Numb of Views %d", i) ;
}
The TAGS are 40 for the root View, 44 for the nested and for the images are 1,2,3,4. So the TAGS are all different.
Any help will be appreciate :). Thanks in advance
UIImageView *imageView=(UIImageView *)[self.view viewWithTag:yourTag];
[imageView setImage:[UIImage imageNamed:#"yourImageName"]];
replace yourTag with UIImageView tag;
replace yourImageName with some Image name
and if you want change only images of ImageViews - you don't need
UIView * view = [self.view viewWithTag:40]; //This works
// The nestedView with Tag:44
UIView * viewNested = [view viewWithTag:44];
Also you can change all images:
for (int i=0; i<18; i++)
{
UIImageView *imageView=(UIImageView *)[self.view viewWithTag:i];
NSString *imageName = [NSString stringWithFormat:#"imageName_%d", i];
[imageView setImage:[UIImage imageNamed:imageName]];
}

How to right align text of UISearchbar in iOS7

Could you tell me how to right align UISearchbar text in iOS 7? , I was using this in iOS6 but now it does not work in iOS7:
//hacking search bar
UITextField *searchField;
for (UIView *subview in self.searchBar.subviews)
{
if ([subview isKindOfClass:[UITextField class]]) {
searchField = (UITextField *)subview;
break;
}
}
if (searchField) {
searchField.textAlignment = NSTextAlignmentRight;
}
Unfortunately this cannot be done safely without completely re-implementing the class from scratch, as text alignment is adjusted by the internals of the object's code when the user begins and finishes editing.
The closest thing to what you want to do would be to use the three position adjustments to shift the text horizontally, but this doesn't affect alignment, only absolute position, and even then only when the user is typing.
If you want to try this, look up searchTestPositionAdjustment, setPositionAdjustment:forSearchBarIcon:, and searchFieldBackgroundPositionAdjustment. I don't think it will be of much use to you though.
-Ash
It's too late, but if anyone is still wondering the solution, then you can follow this.
UITextField *searchTextField = [searchBarController.searchBar valueForKey:#"_searchField"];
You can get the search field using above code. Now simply use the properties you want to use, like.
searchTextField.layer.cornerRadius = 10.0f;
searchTextField.textAlignment = NSTextAlignmentRight;
I've got a solution to this problem. It's a bit hacky and not very neat, but it does the trick.
Since UISearchBar itself does not allow you to edit the placeholder, I've set a UITextField underneath it and disabled it from any touches by doing this:
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if([touch.view isDescendantOfView:self.placeHolderTextField]){
return NO;
}
return YES;
}
Note: don't forget to include <UIGestureRecognizerDelegate> in your .h file.
If this doesn't work however, you can always use [self.view sendSubViewToBack:self.placeholderTextField];
Next on, I've just set events on which I want to display the placeholder and when not.
In the viewDidLoad, I'm just calling self.placeHolderTextFiew.placeholder = #"search"
And in
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
if(searchText.length > 0){
self.placeHolderTextfield.placeholder = #"";
} else{
self.placeHolderTextfield.placeholder = #"search";
}
}
Note again: Make sure to include <UISearchBarDelegate> in your .h file in order for this to work.
I am using a tableView as well, so when the method DidSelectRowAtIndexPath is called, I'm also setting the placeholder to an empty string.
Hope this helps.
you can try like this also..
searchbar.placeholder = #"Hai.. whitespace ";
way to set text right align
searchbar->attribute inspector->search text->custom offset->horizontal(set as per requirement)
After playing with subviews of UISearchBar I found this solution, it works for iOS 6 and iOS 7
//hacking search bar
UITextField *searchField;
for (UIView *subview in self.searchBar.subviews)
{
//this will work in iOS 7
for (id sub in subview.subviews) {
if([NSStringFromClass([sub class]) isEqualToString:#"UISearchBarTextField"])
{
[sub setTextAlignment:NSTextAlignmentRight];
}
}
//this will work for less than iOS 7
if ([subview isKindOfClass:[UITextField class]]) {
searchField = (UITextField *)subview;
break;
}
}
//for less than iOS 7
if (searchField) {
searchField.textAlignment = NSTextAlignmentRight;
}

my chat system looks a little wierd, cant get dynamic height for cell

Ive got a chat system in my app, and im attempting to make dynamic cells to have dynamic height according to how much text is in the cell, pretty common thing people try to do, however i cant get to get mine working properly.
Also the messages align to the right, the sender is supposed to be on the left and the reciever should be on the right... heres what i have done with the storyboard.
created a TableView with 2 dynamic prototypes, inside a UIViewControllerhere is the viewController for that... each cell has a label, one left one right, the whole right and left thing work... heres my issue. Its only pulling to the right for all, so basically my if isnt happening and my else is overruling. Heres a SS.
So i have two issues... Text wont have multiple lines... along with wont do dynamic height, also... if someone can point me i the right dirrection for getting sender and reciever to show on different sides.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSArray *myWords = [[getMessage objectAtIndex:indexPath.row] componentsSeparatedByString:#":oyr4:"];
if (myWords[1] == [MyClass str]){
static NSString *sender = #"sender";
UITableViewCell* cellSender = [_tableView dequeueReusableCellWithIdentifier:sender];
messageContentTo = (UILabel *)[cellSender viewWithTag:83];
self->messageContentTo.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.8];
self->messageContentTo.lineBreakMode = NSLineBreakByWordWrapping;
[self->messageContentTo sizeToFit];
messageContentTo.text = myWords[4];
return cellSender;
} else {
static NSString *reciever = #"reciever";
UITableViewCell* cellReciever = [_tableView dequeueReusableCellWithIdentifier:reciever];
messageContentFrom = (UILabel *)[cellReciever viewWithTag:84];
messageContentFrom.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.8];
messageContentFrom.lineBreakMode = NSLineBreakByWordWrapping;
messageContentFrom.font = [UIFont systemFontOfSize:22];
messageContentFrom.numberOfLines = 0;
messageContentFrom.text = myWords[4];
return cellReciever;
}
}
#pragma mark - UITableViewDelegate methods
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
CGSize size = [[getMessage objectAtIndex:indexPath.row]
sizeWithFont:[UIFont systemFontOfSize:22]
constrainedToSize:CGSizeMake(1000, CGFLOAT_MAX)];
return size.height + 15;
}
The left-right problem might be due to this:
if (myWords[1] == [MyClass str])
If myWords[1] is a string, you need to use isEqualToString: not "==" to compare it.
if ([myWords[1] isEqualToString:[MyClass str]])
As far as the label height not adjusting properly, it's hard to tell what's going on without knowing how your labels are set up. I usually do it by making constraints between the label and the top and bottom of the cell in IB. That way, when you change the height of the cell, the label will follow (and of course, set numberOfLines to 0). Also, in your sizeWithFont:constrainedToSize: method, the width you pass into CGSizeMake() should be the width of the label, not 1000.

Static UITableViewCell changes during viewWillAppear not reflected in display

I am using some static UITableViewCell's configured in the Storyboard to display some setting information.
Some of the other cells should be disabled if one of the other settings is toggled off.
In order to put the cells into the proper state, during viewWillAppear I read the settings from NSUserDefaults and then change the cells accordingly.
- (void) viewWillAppear:(BOOL)animated
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"OtherCellEnabled"]) {
[self otherCell].alpha = 1.0;
[self otherCell].userInteractionEnabled = YES;
}
else {
NSLog(#"Changing alpha to 0.3");
[self otherCell].alpha = 0.3;
[self otherCell].userInteractionEnabled = NO;
}
The problem is that when I actually run the program, even though it says in the log that the alpha is changed, the alpha doesn't actually change. The userInteractionEnabled does seem to stick, but the alpha is left at 1.0.
It's not a problem of cell reuse, or cell's not being instantiated in time, because the other settings can be changed just fine.
Changing it from cell.alpha to cell.contentView.alpha works, but that is a different setting.
It seems like all of the settings "stick" except for the alpha setting, which somehow is getting overwritten.
I am answering my own question because I was able to solve it.
First, I tried putting the alpha change in cellForRowAtIndexPath, but that didn't work either. After a lot of tinkering, I've come to the conclusion that UITableViewCell's alpha setting is somehow special in that it keeps getting overwritten or set to 1.0.
I found two fixes:
First, instead of doing the change in cellForRowAtIndexPath, do it in the UITableViewDelegate method willDisplayCell. For whatever reason, changing the cell's alpha in this method will actually stick. Of course, if you do it this way you have to re-arrange your logic so that the changes are done on a cell-by-cell basis, i.e.:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell
forRowAtIndexPath:(NSIndexPath *)indexPath {
if (cell == [self otherCell]) {
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"OtherCellEnabled"]) {
cell.alpha = 1.0;
cell.userInteractionEnabled = YES;
}
else {
NSLog(#"Changing alpha to 0.3");
cell.alpha = 0.3;
cell.userInteractionEnabled = NO;
}
}
}
As I said, I'm not sure exactly why this works in willDisplayCell but not in cellForRowAtIndexPath. Others seem uncertain also:
What is -[UITableViewDelegate willDisplayCell:forRowAtIndexPath:] for?
UITableView background with alpha color causing problem with UITableViewCell
The other solution is to, instead of using the problematic alpha, use another setting which will achieve the same effect. In my case, that was the contentView.alpha and the backgroundColor. For whatever reason, these settings will stick, and you can even set them in viewWillAppear and it will work as expected:
- (void) viewWillAppear:(BOOL)animated {
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"OtherCellEnabled"]) {
[self otherCell].backgroundColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
[self otherCell].contentView.alpha = 1.0;
[self otherCell].userInteractionEnabled = YES;
}
else {
NSLog(#"Changing alpha to 0.3");
[self otherCell].backgroundColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.3];
[self otherCell].contentView.alpha = 0.3;
[self otherCell].userInteractionEnabled = NO;
}
}
The disadvantage to the second approach is that now you are overwriting the Storyboard's cell color settings, but you could work around that by asking the storyboard for the color if you care about that.
I'm not sure why cell.alpha is treated differently. Maybe something about the way static cells are implemented.
You could try to hint the cell should be redrawn after your if { .. } else { .. }, by using setNeedsDisplay:
[self otherCell setNeedsDisplay]
Based on your comment, how do you get to otherCell?
Is this a post that might help?

UITableViewCell contentView custom disclosure image frame issue

Disclaimer: I've been working too late. But, I'm determined to get through this one tonight.
I have an app where I support different color themes. The dark cell backgrounds have been problematic.
I've been poking around trying to find a formidable way to draw the accessory disclosure icon in uitableviewcells with black backgrounds.
I decided to try overriding setAccessoryType to inherit the functionality for my 50+ views:
-(void) addWhiteDisclosureImage {
UIImageView *disclosureView = (UIImageView*) [self.contentView viewWithTag:kDisclosureReplacementImageTag];
if(!disclosureView) {
[super setAccessoryType:UITableViewCellAccessoryNone];
disclosureView = [[UIImageView alloc] initWithImage:self.whiteDisclosureImage];
disclosureView.tag = kDisclosureReplacementImageTag;
disclosureView.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin;
DebugLog(#"%f, %f", self.frame.size.width, self.frame.size.height);
[self.contentView addSubview:disclosureView];
[self.contentView bringSubviewToFront:disclosureView];
[disclosureView release];
}
}
- (void)setAccessoryType:(UITableViewCellAccessoryType)accessoryType {
if(accessoryType == UITableViewCellAccessoryDisclosureIndicator) {
if ([self.viewController isKindOfClass:[ViewControllerBase class]]) {
ViewControllerBase *view = (ViewControllerBase*) self.viewController;
if(view.colorTheme && view.colorTheme.controlBackgroundColor) {
if([ViewColors colorAverage:view.colorTheme.controlBackgroundColor] < 0.2) { //substitute white disclosure indicator
[self addWhiteDisclosureImage];
return;
} else { //not dark enough
[self removeWhiteDisclosureImage];
[super setAccessoryType:accessoryType];
return;
}
} else { //no colorTheme.backgroundColor
[self removeWhiteDisclosureImage];
[super setAccessoryType:accessoryType];
return;
}
} else { //viewController is not type ViewControllerBase
[self removeWhiteDisclosureImage];
[super setAccessoryType:accessoryType];
return;
}
}
UIView *disclosureView = [self.contentView viewWithTag:kDisclosureReplacementImageTag];
if(disclosureView)
[disclosureView removeFromSuperview];
[super setAccessoryType:accessoryType];
}
This override is typically called in cellForRowAtIndexPath.
It seemed like a good option until I drill down and come back. For some cells, the cell frame will be a great deal larger than the first time through. This consistently happens to the same cell in a list of 6 that I've been testing against. There's clearly something unique about this cell: it's frame.size.
Here is the size of the cell that I log for the first tableview load (in some cases every load/reload):
320.000000, 44.000000
This is the difference in what I get for some (not all) of the cells after call to reloadData:
759.000000, 44.000000
Does anyone know why this might happen?
Update: the suspect cell's custom accessory disclosure view almost acts like it's autoresizing flag is set to none. I confirmed this by setting all to none. I say almost because I see it line up where it should be after reloadData. A split second later it moves clear over to the left (where they all end up when I opt for no autoresizing).
Don't mess around with subviews and calculating frames.
Just replace the accessoryView with the new imageView. Let iOS do the work.

Resources