UISearchDisplayController frame for UITableView in iOS - iphone

I have a UITable that has a UISearchDisplayController.
The UITable is less than the width of the screen (it's 280px width centered).
When I tap on the search bar, the UISearchDisplayController table is all the way to the left of the screen.
Even when changing the frame of the table of the UISearchDisplayController, I still get the same positioning.
I set the frame here:
- (void)searchDisplayController:(UISearchDisplayController *)controller didLoadSearchResultsTableView:(UITableView *)tableView {
tableView.backgroundColor = [UIColor colorWithRed:29.0/255.0 green:30.0/255.0 blue:32.0/255.0 alpha:1];
tableView.rowHeight = self.myTable.rowHeight;
tableView.frame = myTable.frame;
NSLog(#"search table origin: %f",tableView.frame.origin.x);
}
Even weirder, when I log the search table position at the end, it shows 16. However, it is at position 0 in the view.
Any help is appreciated.

I answered my own question. The frame needs to be set in this delegate method:
- (void)searchDisplayController:(UISearchDisplayController *)controller didShowSearchResultsTableView:(UITableView *)tableView {
tableView.frame = self.myTable.frame;
}

Try this Simple Method:
//--Search display controller frame
- (void)searchDisplayController:(UISearchDisplayController *)controller didShowSearchResultsTableView:(UITableView *)tableView
{
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
[tableView setFrame:CGRectMake(my_table.frame.origin.x, tableView.frame.origin.y, my_table.frame.size.width, my_table.frame.size.height)];
}

Related

UITableView slide not editable row with editable rows Xcode iPhone

I'm developing an iPhone app and I have one problem. I have a UITableView with a few editable rows(
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{ )
and one not editable row. If I click edit, the editable rows slide a bit to the right and there is a red round button at the left of it, but the not editable row doesn't slide at all. Is there a way to also slide it to the right but without the red button at the left? It doesn't look that nice at the moment. I hope someone can help me with this:)
I am not sure if it's a good idea to change the default behavior of the tableView.
But if you really want to, you could e.g. use indentation.
// Might be target of button
- (void) setEditingMode
{
tableView.editing = YES;
[tableView reloadData];
}
// Might be target of button
- (void) resetEditingMode
{
tableView.editing = NO;
[tableView reloadData];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell* cell = ...;
....
Boolean cellIsEditable = ...;
if( tableView.editing && !cellIsEditable )
{
cell.indentationWidth = ...; // (please experiment to find the exact value)
cell.indentationLevel = 1;
}
else
{
cell.indentationLevel = 0;
}
}
Subclass the UITableViewCell and slide the uneditable row yourself.
#interface MyHistoryTableViewCell : UITableViewCell
#end
#implementation MyHistoryTableViewCell : UITableViewCell
#define CELL_SLIDE_WIDTH 32 // found empirically
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
if ( self.editingStyle == UITableViewCellEditingStyleNone ) { // not editable
CGRect frame = self.frame;
UITableView *tableView = ((UITableView *)(self.superview));
if ( tableView.editing ) { // going to editing mode
frame.origin.x = CELL_SLIDE_WIDTH;
frame.size.width = tableView.frame.size.width - CELL_SLIDE_WIDTH;
} else { // ending editing
frame.origin.x = 0;
frame.size.width = tableView.frame.size.width;
}
[UIView animateWithDuration:0.3 animations:^{ // match the tableView slide duration
self.frame = frame;
}];
}
}
#end
If you have subviews that need to be anchored to the right of the cell (e.g., a button that should not slide), then do
mySubview.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin; // anchors to the right margin
Also, you have to be creative when setting the subview's frame.origin.x. I experimented with many values until I found something that worked (the value made no sense to me).

UIButton in UITableViewCell

I have a UIButton with an image inside of a UITableViewCell. When the cell is being highlight, the button is also entering the highlighted state (i.e. a darker shade of the image), regardless of whether the user is clicking within the bounds of the button or not.
I don't want this functionality - I only want the button to be highlighted when the button is clicked, not when the entire cell is being clicked.
I've tried to set the image in the highlighted state to be the same as the normal image. This fixes the issue however it stops the button from changing color when it really is highlighted.
Any ideas how to achieve the desired effect?
This was driving me crazy. I figured out that you need to override setHighlighted:animated: and setSelected:animated:
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
[super setHighlighted:highlighted animated:animated];
self.yourButton.highlighted = NO;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
self.yourButton.selected = NO;
// If you don't set highlighted to NO in this method,
// for some reason it'll be highlighed while the
// table cell selection animates out
self.yourButton.highlighted = NO;
}
One approach would be to "deselect" or "unhighlight" the button when the table view cell is selected:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[yourButton setHighlighted:NO];
// do something cool
}
codecaffeine's suggestion didn't work for me (iOS 8.3), but it did put me on the right track. I modified it like this (it's in Swift though):
override func setHighlighted(highlighted: Bool, animated: Bool) {
var colorBefore = self.myButton.backgroundColor
super.setHighlighted(highlighted, animated: animated)
self.myButton.highlighted = false
self.myButton.backgroundColor = colorBefore
}
I've used a different approach, it's a little bit easier, I hope it works for you. Just set the button's highlighted state to false inside the two above delegate methods:
-(void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath {
UIButton *btnAction = (UIButton *) [[tableView cellForRowAtIndexPath:indexPath] viewWithTag:3];
btnAction.highlighted = NO;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UIButton *btnAction = (UIButton *) [[tableView cellForRowAtIndexPath:indexPath] viewWithTag:3];
btnAction.highlighted = NO;
}
Haven't actually tried this, but could you maybe add a target / action to the button for UIControlEventTouchDown that updated its highlighted-state image to what you wanted, then another target / action for UIControlEventTouchUpInside / UIControlEventTouchUpOutside / UIControlEventTouchCancel that reset the highlighted image to match the normal-state image?
A possible workaround would be that, you set the cell selection style to be none. In that case when you select the cell, it would not be highlighted.
This is only, the possible workaround. May be you have other things in your mind.
To make it work, I had to use the following subclassing on the UITableViewCell. The 'button' object is the button inside the custom cell:
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
[self.button setShowsTouchWhenHighlighted:NO];
[super setHighlighted:highlighted animated:animated];
self.button.highlighted = NO;
[self.button setShowsTouchWhenHighlighted:YES];
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[self.button setShowsTouchWhenHighlighted:NO];
[super setSelected:selected animated:animated];
self.button.highlighted = NO;
// Configure the view for the selected state
[self.button setShowsTouchWhenHighlighted:YES];
}
Interverting the various line may result in the highlighting of the button.

UITableView won't scroll to certain position

[self.tableView setContentOffset:CGPointMake(0,48) animated:NO];
I have a UITableView that has a a UIView in the header. My UITableView won't scroll to (0,48) unless animated: YES. I don't want it to animate.
Anyone know whats up?
To set the UIView for the section header, you're using function:
- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;
I suspect you invoke setContentOffset somewhere in viewWillAppear, but that function is called later. And I think it overwrites your contentOffset. ...not sure why it doesn't when animated is YES, but anyway, just put your setContentOffset into this function like this:
- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *headerView = nil;
if (section == SEC_WITH_IMAGE_HEADER) {
headerView = self.neededView;
}
[self.tableView setContentOffset:CGPointMake(0,48) animated:NO];
return headerView;
}
Worked for me, hope so will for somebody else.
You can try the method named -scrollRectToVisible:animated.
I misunderstand your question. So, what you want is to initialize the tableview with a shift of y-coordinate about 48 pixels ?
This will make the tableView begin from yPos 48.
tableView.contentInset = UIEdgeInsetsMake(48, 0.0, 0.0, 0.0);
Hope this can help you....

Table View scroll when text field begin editing iphone

I have table view controller in iphone application. Table view has two sections. First section has two rows and second section has one row. Second section has a custom table view cell.
Second section has a textfield which hides when text field begin editing and keyboard pops up. I want this table view to scroll when keyboard pops up.
I tried the following code which I came across on different websites but in vain.
Thanks in advance.
-(void) textFieldDidBeginEditing:(UITextField *)textField {
CGRect textFieldRect = [textField frame];
[self.tableView scrollRectToVisible:textFieldRect animated:YES];
}
atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}
-(void) textFieldDidBeginEditing:(UITextField *)textField {
UITableViewCell *cell = (UITableViewCell*) [[textField superview] superview];
[self.tableView scrollToRowAtIndexPath:[tableView indexPathForCell:cell]
atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}
I have run into this on Static Cell TVC's. There is an issue when overriding viewWillAppear and NOT calling its Super. So if you are doing that, make sure to call
[super viewWillAppear:animated];
at the top of viewWillAppear
You want to use the setContentOffset method of the table view. Determine the magnitude of the vertical scroll (in pixels), and then:
CGFloat verticalScroll = ... your code here ...
[self.tableView setContentOffset:CGPointMake(0, verticalScroll) animated:YES];
My problem was I was adding the table cell containing the UITextField in the
- (UIView*)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
function. If you do this the automatic UITableView scrolling doesn't work.
So, you have to do some arithmetic to work out when your last row is showing and put your special UITableViewCell in here along with all the others.
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {

Adding a subview larger than cellHeight to a UITableViewCell?

I'm trying to add a subview to a UITableViewCell and the design that I'm working from demands that this particular subview (an image) needs to be larger than the actual UITableViewCell and thus partly overlap its siblings.
So I've set up my table cell, generated my image and added it to the cell's contentView:
// rowHeight for the UITableView is 45.0f
UIImage *image = [self createCellThumbnail: someImage];
UIImageView *thumbView = [[UIImageView alloc] initWithFrame: CGRectMake(150, -5, 55,55)];
thumbView.transform = CGAffineTransformMakeRotation(0.1f);
thumbView.image = image;
cell.clipsToBounds = NO;
cell.contentView.clipsToBounds = NO;
[cell.contentView addSubview: thumbView];
While the image will 'overflow' into the cell below it, the top of the image is always clipped, as demonstrated here:
Does anyone know if what I'm trying to do is possible with the current approach?
Or should I just figure out a way to draw these images onto the UITableView after all the cells are drawn (it's a non-scrollable tableview, so that would work and be fairly easy).
Update:
Have also tried adding the following, to no avail:
cell.opaque = NO;
cell.contentView.opaque = NO;
cell.clearsContextBeforeDrawing = NO;
cell.contentView.clearsContextBeforeDrawing = NO;
cell.clipsToBounds = NO;
cell.contentView.clipsToBounds = NO;
I seems that the tableView renders its cell from bottom to top, so the cells above one cell overlap that one cell. To avoid this, you'd have to set the backgroundColor of all cells to +[UIColor clearColor] so that you won't see those overlap problems.
But setting the backgroundColor to clear in -tableView:cellForRowAtIndexPath: does not make any sense. UIKit does a lot of stuff with the cell before it's drawn, so does it reset the backgroundColor property of the cell.
What we need to do is setting the backgroundColor in a later state. Luckily there is this -[UITableViewDelegate tableView:willDisplayCell:forRowAtIndexPath:] which we can implement like this:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
cell.backgroundColor = [UIColor clearColor];
}
Now we're setting the backgroundColor just before the cell is drawn an this turns out to be working.
UPDATE:
So I've done some more experimentation and the following solution still works without having to set the background of the cell to transparent, this involved moving the z order of the covered cell. This works with highlighting and selecting of the other cell (via the relevant callbacks), and if the two cell's backgrounds are different colors. Solution is as follows (you can ignore the didHighlight and didSelect methods if they don't matter to you):
(note that "covered row" is the one whose content we are trying to keep visible and In my case its content goes slightly into the row above, which was clipping it)
-(void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0 && indexPath.row == ROW_ABOVE_COVERED_ROW)
{
NSIndexPath * rowbelow = [NSIndexPath indexPathForRow:indexPath.row+1 inSection:indexPath.section];
UITableViewCell* cell = [tableView cellForRowAtIndexPath:rowbelow];
[cell.superview bringSubviewToFront:cell];
}
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0 && indexPath.row == ROW_ABOVE_COVERED_ROW)
{
NSIndexPath * rowbelow = [NSIndexPath indexPathForRow:indexPath.row+1 inSection:indexPath.section];
UITableViewCell* cell = [tableView cellForRowAtIndexPath:rowbelow];
[cell.superview bringSubviewToFront:cell];
}
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0 && indexPath.row == COVERED_ROW)
{
[cell.superview bringSubviewToFront:cell];
cell.contentView.superview.clipsToBounds = NO;
}
}
NOTE: you should also set the background color of your content to clear, or it will adopt the bgcolor of the rest of your cell, and so when you manage to bring your content to the front of the covering cell, it will take the background color with it and leave a nasty looking block in the other cell (in my case my only content was the detailTextLabel and the textLabel):
// in cellForRowAtIndexPath:
[cell setBackgroundColor:[UIColor redColor]]; //using red for debug
cell.detailTextLabel.backgroundColor = [UIColor clearColor];
cell.textLabel.backgroundColor = [UIColor clearColor];
I hope that's helpful to anyone else trying this....
ORIGINAL:
For me the solution was to use:
self.contentView.superview.clipsToBounds = NO;
My cells were already transparent, but my content was still getting clipped. In my case I was using a custom cell which moves it's content up in layoutSubviews. So layoutSubviews for my custom cell wound up as follows:
-(void)layoutSubviews
{
[super layoutSubviews];
self.contentView.frame = CGRectOffset(self.contentView.frame, 0, -11);
self.contentView.superview.clipsToBounds = NO;
}
I don't know if this would work if the cell above was opaque, or if the cells were to highlight when pressed, whether this would cover up my content.
However, I didn't need to make the cell transparent again in the viewWillDisplayCell callback method - doing it in the normal cellForRowAtIndexPath was sufficient
I had this problem and I made sure my custom tableviewcell's main background had clip subviews checked and it solved the problem. This was with a custom tableview cell loaded from a xib though. Not exactly the same but similar situation.
I actually had the opposite just yesterday, I had created a custom table cell and for some reason I got an overflow which I didn't want to have. My solution was to add the following code to my view controller class:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 175;
}
When it matched the height of the table cell there was no overlap; when it was too small there was overlap. Mind you though that I got very quicky behavious so I'm not sure it's a very good idea to do this.