After quite a lot searching around Google, Stackoverflow and apples documentation, I have almost given up.
I am making an app to index costumers and because of a potentially very long list, I use section index to navigate faster. My problem is shown in the picture below.
When I drag an item to reveal the delete button, it is partially hidden below my section index bar.
I have no code setting tableview or tableviewcells width and the section index can't really be changed, as far as i am concerned.
EDIT:
The question is how I can have the tableview cells end before they get overlapped, so the delete button is fully visible.
EDIT 2:
I already tried setting the cell frame smaller without any luck.
cell.frame = CGRectMake(cell.frame.origin.x, cell.frame.origin.y, cell.frame.size.width-30, cell.frame.size.height);
I also tried the same with the tableview, but as it is in a UITableViewController it cannot be resized.
self.tableView.frame = CGRectMake(self.tableView.frame.origin.x, self.tableView.frame.origin.y, self.tableView.frame.size.width-30, self.tableView.frame.size.height);
As a simple work-around we resolved the visual overlap of the index by setting the background color of the index to clearColor.
self.tableView.sectionIndexBackgroundColor = [UIColor clearColor];
* This looks visually better, but the index will still overlap your tableViewCell.
Another possible work-around would be to hide the index bar when entering edit mode:
// allow editing
[self.tableView setEditing:YES animated:YES];
// hides the index
self.tableView.sectionIndexMinimumDisplayRowCount = NSIntegerMax;
The inEditMode method should do the trick. Below I embed a complete code that hides the index while editing and shows it again when the editing is done.
-(void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath{
[self inEditMode:YES];
}
-(void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath{
[self inEditMode:NO];
}
//on self.editButtonItem click
-(void)setEditing:(BOOL)editing animated:(BOOL)animated{
[super setEditing:editing animated:animated];
[self inEditMode:editing];
}
-(void)inEditMode:(BOOL)inEditMode{
if (inEditMode) { //hide index while in edit mode
self.tableView.sectionIndexMinimumDisplayRowCount = NSIntegerMax;
}else{
self.tableView.sectionIndexMinimumDisplayRowCount = NSIntegerMin;
}
[self.tableView reloadSectionIndexTitles];
}
Just Use this code before allocating any subview in cellForRowAtIndexPath
for (id object in cell.contentView.subviews)
{
[object removeFromSuperview];
}
Related
I receive a color from the server and in cellForRowAtIndexPath method I'm trying to apply this color to a view inside the cell.
The problem is that all the cells display the same color until I scroll down the table. When I start scrolling they update well their color.
I'm new on iOS and Objective-C, so if you could help me it would be appreciated, thanks.
Before scrolling:
After scrolling:
Some code: (If you want more please tell me)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CalendarDayCell *cell = (CalendarDayCell *) [tableView dequeueReusableCellWithIdentifier:#"CalendarDayCell"];
if (cell == nil) {
cell = [[CalendarDayCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"CalendarDayCell"];
}
if (self.events.count) {
CalendarEvent *ce = self.events[indexPath.row];
CalendarDayCell *dayCell = (CalendarDayCell *) cell;
// ...
dayCell.viewColorBar.backgroundColor = [self colorWithHexString:ce.color];
return dayCell;
} else {
// Not important
}
}
PS: I've also tried it at willDisplayCell method with the same results.
EDIT:
Finally I figured out what were the solutions.
IDK why XCode redimensioned the color bar height to be 980px from the 50px that I specified in the nib file. And that was causing that all cells below had the same color.
I put all the views in another view, and assigned that view to the cell because some cells were not showing their color.
that's all
The problem is with reusing the cells - that means that in cellForRowAtIndex path you have to set color for every condition. This is easily reproducible with images. If you set image only sometimes, you will have to set image to none when you don't need to display it. What you need to do is to handle in the else block the control you want to change.
if(self.events.count){
dayCell.viewColorBar.backgroundColor = [self colorWithHexString:ce.color];
}
else{
dayCell.viewColorBar.backgroundColor = [UIColor clearColor];
}
Or something like that.
Are you sure that self.events.count is actually non-zero? Perhaps the tableview is being populated before self.events is setup properly.
For example, the view controller might be loading via viewDidLoad, then the UITableView, then you're setting self.events. If that's the case, self.events will be nil until the whole view/viewcontroller is loaded. That would account for it working after you start scrolling.
I have a tableView, with a UIWebView in each row.
When the webView is tapped, I'd like for it to just expand and take over the entire screen.
However, there a few problems, and I'm not sure which is interfering. First I tried something like this:
webView.frame = self.view.bounds;
webview.bounds = self.view.bounds;
cell.clipsToBounds = NO;
webView.clipsToBounds = NO;
However, the webView seems to have trouble overtaking the cell, doesn't expand to proper width and generally doesn't work. I also thought about manipulating the cell height, but it seems to be more trouble than it should be.
So basically, I'd like to move this webView to the top of the stack and change its frame size.
Otherwise I may just instantiate a new webView which seems like a waste. Any ideas? Thanks
Don't change the frame of the web view. Have the web view tied to all four sides of the cell using constraints (or at least the top and bottom), and when you tap on the cell, and it gets selected, use the indexPathForSelectedRow property in heightForRowAtIndexPath to make that cell as big as the table view.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if ([[tableView indexPathForSelectedRow] isEqual:indexPath]) {
return tableView.frame.size.height;
}else{
return 44;
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
I don't know why you would put a WebView in a cell.. I'm no expert but wouldn't the webview be recreated everytime you scroll?
You could use SVWebViewController and place the following code in your didselectrowatindexpath to present it modally.
SVModalWebViewController *webViewController = [[SVModalWebViewController alloc] initWithAddress:#"http://google.com"];
[self presentViewController:webViewController animated:YES completion:NULL];
I'm using tableView:willDisplayHeaderView:forSection: to customize my header views. And it seems to work under normal user scrolling just perfectly. But if the UITableView is scrolled via an animation (ie. a Deleted row) the method is not called, even though the header comes into view as a result of that animation.
Please note this is NOT tableView:viewForHeaderInSection: :)
The code is as follows:
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
{
//Type Cast the view to UITableViewHeaderFooterView
UITableViewHeaderFooterView *header = (UITableViewHeaderFooterView *)view;
//Change tintColor property of header to black
header.tintColor = [UIColor blackColor];
//See if there is an existing custom subview in the header
CustomHeaderView* headerContentView = (CustomHeaderView*)[header viewWithTag:1007];
//If it doesn't exist make it.
if(headerContentView == nil){
headerContentView = [[CustomHeaderView alloc] initWithFrame:CGRectMake(0, 0, view.frame.size.width, 40.0f)];
headerContentView.tag = 1007;
if(section==0){
headerContentView.label.text = #"Current Members";
}
if(section==1){
headerContentView.label.text = #"Others Nearby";
}
[header.contentView addSubview:headerContentView];
}
}
Okay. This does what I'd expect when I'm scrolling through the table. It makes the headers black, adds the custom view, and makes the text in those custom views whatever I specify.
However, it doesn't seem to be calling tableView:willDisplayHeaderView:forSection: if I perform an animation on the UITableView, (after a delete for instance) and as a result of the animation the header comes in without rendering properly at all (blank white):
- (void)cellDidSelectDelete:(UITableViewCell *)cell {
[self.tableView beginUpdates];
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
[self.tableModel removeItemForUser:cell.userID];
[self.tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];
}
The header that is revealed by the animation comes in white (not black as specified), and the tableView:willDisplayHeaderView:forSection: method is not even called (I've tried logging it).
Would any one have any idea what the heck is happening here? Is it a bug?
Thanks so much for any leads!
I've got a problem in that I cannot get my UISearchBar to scroll underneath my UINavigationBar.
-(void)awakeFromNib
{
[super awakeFromNib];
self.tableView.tableHeaderView = self.taskSearchBar;
}
-(UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
return self.taskSearchBar;
}
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 44;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.tableView.frame = self.view.bounds;
// Load our table with current data
[self.tableView reloadData];
// Tuck UISearchBar under navigation bar
self.tableView.contentOffset = CGPointMake(0, self.taskSearchBar.frame.size.height);
}
I've spent a LOT of time searching through SO to try to find relevant discussions.
This one, for example, makes it sound OH SO SIMPLE: Scroll UITableView so that the header isn't visible
I was previously able to get this to work when creating everything from Story Board, but I can no longer do that due to the nature of my app - I had to break things out to have a parent UIView to the UITableView which I was unable to do while using a UITableViewController.
Any help on this would be MUCH appreciated!!!
You are assigning the search bar as the tableHeaderView which will be what you need I think. BUT you are returning it as a section header for every section which is not logical(I guess you need this search bar show only in one place). Section headers are always visible and that is what's causing your problem I think.
I am trying to create a UITableView that has a selection bar that scrolls to whichever row the user has selected (please don't ask why, I just have to do this). This is different from the typical selection bar that the UITableView has, because there is no animation there. What I've done is added a TableView in Interface Builder to my main view, and I've also added an imageView to my main view. I need this to work similar to the selection bar in the UIPickerView except that in this case it is the selection bar that moves. I figure the code for this would reside inside:
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
CGRect rect = [tableView rectForRowAtIndexPath:indexPath];
_imageView.frame = rect;
}
Can anyone explain to me how I would code the animation of the selection bar from cell to cell?
Thanks in advance to all who reply
Assuming the code you currently have works:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[UIView animateWithDuration:.3 animations:^{
CGRect rect = [tableView rectForRowAtIndexPath:indexPath];
_imageView.frame = rect;
}];
}
There is also +animateWithDuration:animations:completion: and +animateWithDuration:delay:options:animations:completion: