I want to remove the selection color that appears when I touch a cell in my tableview.
In IB there is a "shows selection" checkbox that does nothing and it seems from what I can gather that it is just a bug in IB.
But then there is the
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
that I can set to each cell.
This also does nothing, so this is where I am stuck, all documentation say that if I set this property it should not appear but it does.
I push another UIViewController on a UINavigationController, and when I go back to the view in question, the blue background on the cell is stuck until I touch another one.
The only thing special is that I instantiate this UITableViewController with the help of storyboard and I use prototype cells. Then I put it inside a UIScrollView to have horizontal paging between multiple UITableViewControllers. There is no way to access the navigation controller when I do this so I pass the UINavigationController along to the UITableView.
Sorry that I can't make the keywords appear as code, it says I should press the tab key then type a $ but that moves my cursor to tags.
You might try to set the selectedBackgroundView of your cell like this :
customCell.selectedBackgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"background.png"]];
In the delegate method cellForRowAtIndexPath
From code you can use (for example for grey):
cell.selectionStyle = UITableViewCellSelectionStyleGray;
And put this at:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
In your ViewController.
The solution was to set the style on the prototype cell in IB. Many things are wierd about prototype cells.
Related
I have three separate "UIViewControllers" in my app. Each has UITableView attached to it.
First UITableView displays just a single table of rows of data (news items).
Second UITableView displays a search view, which has a few sections where users type in different search criteria.
Third UITableView displays the article details.
In each of the UITableView, there is a button.
First UITableView has "Load more articles" button.
Second UITableView has "Search" button
Third UITableView has "Visit article page" button.
Since all three views are UITables, I created a custom UITableCellView and added to each of the UITableViews. Here's an example of my "ButtonCell" in the 2nd UITableView
ButtonCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ButtonCell"];
NSString *cellText = #"Search";
[[cell buttonLabel] setText:cellText];
return cell;
This works well - exactly how I want it.
Now I added the same "ButtonCell" to the first and third UITableView, but a few strange things happened.
The background color of the ButtonCell is not correct - in the ButtonCell ".xib" file, I set it to a blue-ish color. This works well for the 2nd UITableView, but for others, it's just "white".
The ButtonCell doesn't have "rounded corners" anymore.
Any ideas on how to properly "re-use" my custom button cell in any UITableViews?
It sounds like your second table is grouped, and the other two plain (you get rounded corners with a grouped table view style). Setting the color of custom cells in IB for plain tables doesn't work. You should set the color of your cells in the tableView:willDisplayCell:forRowAtIndexPath: delegate method:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
cell.backgroundColor = [UIColor colorWithRed:.67 green:.93 blue:1 alpha:1];
}
I have three UITableViewCell subclasses. I'm displaying these in a table view in a view controller. I have, in the view controller, returning nil for tableView:willSelectRowAtIndexPath: since I want the UITextFields, in two of my UITableViewCell subclasses, to get focus and become first responder.
For the third UITableViewCell subclass, I have a custom UIView subclass that houses a UIWebView. Currently the div in the html content loaded in the UIWebView is one line tall. I previously made the div height 100% but found that scrolling started to act up. If I tap in the div the keyboard comes up. However, if the user taps any where else within this custom UITableViewCell the UIWebView div is not selected and the keyboard does not come up.
How can I get either my custom UITableViewCell or custom UIView subclass to become the first responder? Or am I going about this the wrong way?
I believe you're going about this the wrong way. Returning nil for tableView:willSelectRowAtIndexPath: won't really help your cause here.
Instead, you have a couple options. First, you could make a UIButton that sits behind your text fields in your table cell which fills the entire view, and then respond to touches on it and tell the text field to become active. Like so:
Wire up the button within your UITableViewCell subclass:
[self.button addTarget:self action:#selector(handleTouch) forControlEvents:UIControlEventTouchUpInside];
Set focus on the text field when touched:
- (void)handleTouch
{
[self.textField becomeFirstResponder];
}
The other option, and the one I like less, is to handle the selection of the cell in the delegate methods and tell the cell's textfield to become active. Like so:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
MyCustomCellSubclass *cell = [tableView cellForRowAtIndexPath:indexPath];
[cell.textField becomeFirstResponder];
}
In which of course you would need to add a textField property to your MyCustomCellSubclass in order to do this.
Hope this helps!
I'm trying create TableViewCells which mimic buttons. This means that on touch down, there should be a highlight effect and on touch up should trigger the standard selected state. This works as intended, but the problem is that there is a split second delay between touch down and the highlighted state appearing. Why is this? How can I make the highlight appear immediately on touch down without the delay?
Here's the code I'm using on my TableView delegate:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[[tableView cellForRowAtIndexPath:indexPath] setSelected:YES animated:NO];
// do something here
[[tableView cellForRowAtIndexPath:indexPath] setSelected:NO animated:NO];
}
I suppose I don't really understand your question as you've asked it. UITableViewCell already acts "like a button" when pressed in the sense of it highlighting. From the looks of your code, it really does nothing that the tableView doesn't do natively.
Basically, the reason you are seeing a delay is because the cell already highlights on touch, and what you are doing is setting Selected to YES, then NO, but the cell already does this, so it's kind of doing the same thing twice, once on it's own, then once forced — this is the reason for the delay you are seeing.
The only thing that should go in didSelectRowAtIndexPath: is the actions you want to happen when the button is pressed, NOT what you want the cell to do or how it should behave upon being touched. There are other delegate methods that would handle these behaviors.
If you are looking to change the highlight color of the cell, then see my question/answer here.
Update
By default, the UITableView code provided by Apple does not contain the deselect method. So when you select the cell it stays selected. To deselect the cell, add the following method to didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
/* The following will deselect the cell on touchUp */
[tableView deselectRowAtIndexPath:[tableView indexPathForSelectedRow] animated:YES];
}
I have my own table view cell which is defined in my storyboard. I have also defined a custom UITableViewCell class for this special cell. So when I want to create an Outlet for my custom prototype cell I get an error that the Outlet cant be created.
Since this is not possible I have to do some ugly workarounds and use the tags in IB to reference the individual labels and buttons later on in my code.
I don't really see why this is not possible and I wonder if working with tags and [myCell viewWithTag:] is the best possible way to go here?
Because the outlet is a one-to-one connection between your controller and a specific item within the view. In the case of a prototype cell, it is simply a description of a cell that can have an arbitrary number of different items (i.e. rows in your table view). How would the controller know which item you are referring to (e.g. row 5 or 500)? That is why you are receiving the error message.
Lucas provided one method to refer to your connection via tags which works perfectly well.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CellIdentInIB"];
UIImageView *img = (UIImageView*) [cell.contentView viewWithTag:1];
//img.image = ...
//Access you prototype cell here to alter its style, example:
[[cell layer] setCornerRadius:10];
[cell setClipsToBounds:YES];
return cell;}
I assume you are using dynamic prototypes - in the attribute inspector of the tableview in the storyboard there is an option to select "static cells" or "dynamic prototypes". You can do what you are trying to do if you select "static cells" as there is only one cell in your tableview at run time for each cell in the storyboard. Using this approach you will only be able to use the cells you create in storyboard i.e. you will not be able to select the number of cells in your code.
I have not yet found any really good examples on how to do this. There is an image that I want to use as the accessory button and when I put it in and click on it doesn't work. So it looks correct but doesn't work...
Here is my code:
[cell setAccessoryType:UITableViewCellAccessoryDetailDisclosureButton];
cell.accessoryView = [[UIImageView alloc]
initWithImage:[UIImage imageNamed:#"TableView_Green_Disclosure.png"]];
So how do I get my UIImageView to call accessoryButtonTappedForRowWithIndexPath whenever it is tapped?
A thorough reading of accessoryView and accessoryType would reveal that they are mutually exclusive ways to customize a cell.
Setting the accessoryType will cause the table view delegate method to be called when it is tapped.
Setting the accessoryView will ignore the setting of accessoryType and give you something to display. If you want to receive a callback from the custom view you've put in place, it should be a control that is wired up to do so. (Or any view with a gesture recognizer.)
If you use a button, and set its action to accessoryTapped:, you will receive the button as the "sender" argument. You can walk up the view hierarchy until you find a table view cell, and then ask your table view what the indexPath of that cell is. This will then get you an index into your model objects and you be able to act on it appropriately.
Alternate to the button, you can enable interaction on the UIImageView above, and add a gesture recognizer to it.
To make the button actually do something, you'll need to implement - (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath from UITableViewDelegate.
When an accessory button is tapped in a row, this method will be called and you'll have the chance to act appropriately using the passed in index path to determine which row's accessory was tapped.
Check the blog post hdr->cmdline for creating custom accessory view for UITableView.
The author used UIButton objects with images for custom accessory view.
To make use of the accessoryView - you would need to set the cell's accessoryType to UITableViewCellAccessoryNone deposit a UIButton (with associated image) into the cell and then wire it up to receive user touches. You might use something like the code below as the IBAction response to the cell's UIButton being touched:
- (IBAction) accessoryButtonPressed:(id) sender
{
NSUInteger pathInts[] = { 0,0 };
pathInts[1] = self.currentselectedrow; // ivar set when tableview row last selected
NSIndexPath* indexPath = [NSIndexPath indexPathWithIndexes:pathInts length:2];
[self tableView:mytableview accessoryButtonTappedForRowWithIndexPath:indexPath];
}
The UIButton would be wired to execute this glue code by way of a line inside your tableview's "cellForRowAtIndexPath:" function
[thecell setButtonTarget:self action:#selector(accessoryButtonPressed:)];
One thing I noticed is that the UIButton seems to want a 'swipe right' versus a simple 'tap' touch in order to trigger the event - but it could be my beta iOS that's the problem. Note that I had added a UIButton* object named 'cell_accessoryButton' to the Custom Cell source.
In the cell's source you'd support the 'setButtonTarget' call with code like this:
- (void) setButtonTarget:(MyViewController*)inTarget action:(SEL) inAction
{
[self.cell_accessoryButton addTarget: inTarget
action: (SEL) inAction
forControlEvents: UIControlEventTouchUpInside];
}
It's so much easier to just use the accessoryType reference and let iOS do the heavy lifting - but, if you want a custom graphic, etc - this is another path that works.