UIImageView is disappearing behind cell row in UITableView in iOS - ios

I have a UIImageView that is supposed to cover the selected row from a UITableView. Both, the UIImageView, and UITableView are added to the main View inside Interface Builder. Instead of covering up the cell when it is selected, the UIImageView moves to the selected cell and disappears behind it. What I need it to do is move up to the selected row, and cover it up (i.e. the image should be in front of the cell, not behind it). Please also bear in mind that my image needs to only cover the selected row. Here is my relevant code:
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[UIView animateWithDuration:.3 animations:^{
//CGRect rect = [tableView rectForRowAtIndexPath:indexPath];
CGRect rect = [self.view convertRect:[tableView rectForRowAtIndexPath:indexPath] fromView:tableView];
_imageView.frame = rect;
}];
}
Can anyone see what I am doing wrong, and know how to fix this?
Thanks in advance to all who reply.

It is simply because the imageView is added before the table view in the subviews, I guess. Hence you can use bringSubviewToFront method and apply it to the imageView after you add your tableView to the subviews, for example.

Related

Image on cells not all the way to the left

I am learning about UITableview on iOS and following a course online. I get the table showing fine, but the images on my cells are not all the way to the left (whereas the instructor's ones are). Here is a screenshot of the cells in question:
I don't want that gap, I want the images to be positioned right at the beggining of the cell, all the way to the left. I have done some research and it seems Apple has changed the default look of the cells between ios6 and ios7 so that now the images in cells show a little gap at the left. To get rid of it, I have tried UIEdgeInsets:
[tableView setSeparatorInset:UIEdgeInsetsZero];
and that's not working. I also have tried this approach:
cell.imageView.frame = CGRectMake( 0, 0, 50, 55 );
Nothing happens. So how would I go about it? Thanks
edit-------------------------------------------------------------------------------------------------------------------------------
Still not have found the answer to this. The solutions posted here don't work. I found this piece of code:
self.tableView.contentInset = UIEdgeInsetsMake(0, -50, 0, 0);
Which besides completely puzzling me (as the parameter affected should be the y?) I thought solved the issue by making the image on the cell appear all the way to the left, until I realised it only moved the whole view to the left (as I should have expected I guess) leaving an equal gap on the other side of the screen. All I want is for my images in the cells to appear all the way to the left of the cell as it used to be the case on previous ios. Thanks
It happens because default table content offset from left is 15, you should change it with 0.
See this once, you get idea Remove empty space before cells in UITableView
If you create custom cells. UITableViewCell have owner imageView. Change title of image in your cell.
If you use default cell, use custom cell with constraint Leading space = 0.
It is better not use default imageView of the cell. Drag and drop UIImageView from objective library, create a custom table view cell (Child class of UITableViewCell) then create and outlet of the image view just dragged.
The spacing in the UITableViewCell is because of the default TRUE returned by shouldIndentWhileEditingRowAtIndexPath method of UITableViewDelegate.
I was able to reproduce your problem by the below scenario:
UITableView is in editable mode:
self.tableView.editing = true
And you have implemented:
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView
editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleNone;
}
To correct your code:
If you do not want to set Editing Style then you can turn off the editing mode by
self.tableView.editing = false
and remove editingStyleForRowAtIndexPath.
Else if you need editing mode then set the appropiate Editing style(UITableViewCellEditingStyleDeleteor UITableViewCellEditingStyleInsert) or simply turn the indentation off.
- (BOOL)tableView:(UITableView *)tableView
shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath {
return FALSE;
}
You must create a custom cell, by adding a new class as a subclass of UITableViewCell. then you can design cell with autolayout and constraints which will resolve the issue.
there is a another concrete way to achieve this by creating subclass uitableviewcell (custom class).
steps to follow
create a class subclass of UITableViewCell.
in .h file create properties and outlets of UI components.
go to storyboard and add table view cell inside the tableview.
now add UI components like: imageview or button etc and set the x, y values according to.
make class of custom cell your className using identity inspector see image.
connect all outlets of UI components.
use below code uitableview
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *MyIdentifier = #"uniqueIdentifire";
yourCustomClassForCell *cell = (yourCustomClassForCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil){
cell = [[yourCustomClassForCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier];
}
cell.imageView.image = [imageAry objectAtIndex:indexPath.row];
}
Dont forget to give identifire by selecting your cell using storyboard Attribute inspector uniqueIdentifire to identifire property see image.
Also you can give some vertical space between cells by just to add this below code (Method only) inside customeCellClass.
- (void)setFrame:(CGRect)frame { // method to insert gap between table view cell
frame.origin.y += 6;
frame.size.height -= 2 * 6;
[super setFrame:frame];
}
You can not really change the frame of the inbuilt subviews of uitableviewcell like imageview, accessoryview. But if you create a custom tableviewcell class(even if you do not add any other subelement to it), you can change the frame of the inbuilt imageview by overriding the layoutSubviews method inside the UITableViewCell. I have tried it and it works.
#import "TableViewCell.h"
#implementation TableViewCell
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
-(void) layoutSubviews{
[super layoutSubviews];
CGRect frame = self.imageView.frame;
frame.origin.x = 0;
self.imageView.frame = frame;
}
#end

Change view position when configuring cell. Strange behavior

I have a standard UINavigationController with a UITableViewController at it's root. In IB, I paint a prototype cell with a label and a UIView. The UIView contains a button. I'd like the UIView to be x-aligned after the label, as a function of the length of text in the label.
In IB, the view's left side is initially aligned with the label's left side. There are no layout constraints in IB.
Here's my cellForRowAtIndexPath ...
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSArray *labels = #[#"SOME STRING", #"SHORTER", #"A VERY MUCH LONGER ONE", #"REGULAR ONE", #"TINY"];
UILabel *label = (UILabel *)[cell viewWithTag:32];
label.text = labels[indexPath.row];
UIView *view = [cell viewWithTag:33];
CGSize size = [label.text sizeWithAttributes:#{NSFontAttributeName:label.font}];
view.frame = CGRectOffset(label.frame, size.width, 0);
return cell;
}
Two problems: I've set breakpoints and watch this code running the first time the view appears. I see the view.frame get changed for each row, but the view does not change position. I remains in it's IB-position, right on top of the label. If I scroll the table down, the views on lower cells (presumably reused) are in the desired position. If I scroll back up, the upper rows are also good. It just fails to work on the initial presentation of the upper cells.
Second problem is that the button contained in only the first row has a subtle, strange effect applied to it's text, like a blur. See attached...
First Row Button (zoomed in mac preview... see that extra blur on the left edge of the letters?)
Other Row Buttons
Stuff I tried:
I've tried a few variations, including using a regular view controller with a table view added (rather than a UITableViewController). I've found that if I reloadData on viewDidAppear, that solves the placement problem, but not the blurry button. (Also, I don't like the idea of needing to reload on viewDidAppear). Doing so on viewWillAppear has no effect at all. I've also tried animating the label change slowly. It happens, but again, only on the second time the cell is configured. I try changing the UIView color to prove the code is being run. The color change happens every time, including the first time, but not the view placement. Am I nuts?
For problem 1:
Try calling [cell layoutIfNeeded] before returning the cell, there should be no performance hit when it does not need relayout.
For problem 2:
try calling CGRectIntegral before you set the frame. ie
view.frame = CGRectIntegral( CGRectOffset(label.frame, size.width, 0) );

Avoid animation on an UIView

So to make it simple I'm trying to have the same view as in iMessage: a reversed UITableView.
I have a rotated UITableView :
self.tableView.transform = CGAffineTransformMakeRotation(-M_PI);
Each UITableViewCell is also rotated to appear the right way:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [[UITableViewCell alloc] init];
cell.transform = CGAffineTransformMakeRotation(M_PI);
return cell;
}
When the keyboard appears, the frame of my UITableView is changed, so that the bottom of my UITableView follows the top of the keyboard. Same thing when the keyboard hides. To do this I use an animation.
My problem is that when the keyboards hide, the frame of the UITableView increases, and some new cells are displayed. As they are displayed, the delegate calls tableView:cellForRowAtIndexPath: and the animation also applies on the
cell.transform = CGAffineTransformMakeRotation(M_PI);
So I see my new cells rotating!
Is there any way I could avoid the animation on the rotation?
You need to disable animations if you don't want the setting of animatable properties to be animated:
BOOL wasEnabled = [UIView areAnimationsEnabled];
[UIView setAnimationsEnabled:NO];
cell.transform = CGAffineTransformMakeRotation(M_PI);
[UIView setAnimationsEnabled:wasEnabled];
On iOS 7, you can use [UIView performWithoutAnimation:...].
Also, I would avoid doing
self.tableView.transform = CGAffineTransformMakeRotation(-M_PI);
Last I checked (iOS 5 or 6?), this would cause the cell sizes to be incorrect, as if UITableView used its frame's width to decide how "wide" cells should be. Stick it in a view and set the transform of that view instead (or check that it does the right thing on each major OS version you need to support).
Hey mate try to maintain a bool variable when you dont need the animation set the bool variable to false during some editing or any other event. So put the condition of bool variable if it is True then only go for animation.
regards and have a nice year ahead

Trying to create a selection bar for a UITableView in iOS app

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:

Need to control movement of UIImageView on UITableView in iOS

I have a UIImageView that currently moves to whichever row in a UITableView is selected by the user. This functionality is working fine. However, what I want to do now is also control its movement by using a button. I have two buttons, one for going up one row, and one for going down one row. Both buttons have different tag values but call the same IBAction method. What I want to know is how do I move the UIImageView up/down by one row? I presently have the following code which works fine:
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self.view bringSubviewToFront:_imageView];
[UIView animateWithDuration:.3 animations:^{
CGRect rect = [self.view convertRect:[tableView rectForRowAtIndexPath:indexPath] fromView:tableView];
_imageView.frame = rect;
}];
}
The above method works fine in moving the UIImageView to whichever row the user has selected.
How do I modify this code so that it strictly moves up exactly one row each time the up button is pressed, and down exactly one row each time the down button is pressed?
Get the table view cell's indexPath from the last selected row in didSelectRowAtIndexPath: method in a NSIndexPath object.
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self.view bringSubviewToFront:_imageView];
self.indexPath = indexPath;
[UIView animateWithDuration:.3 animations:^{
CGRect rect = [self.view convertRect:[tableView rectForRowAtIndexPath:indexPath] fromView:tableView];
_imageView.frame = rect;
}];
}
Process the indexPath in your button action method to see if the above/below cell will be in same section,in which case increment/decrement the row and if in other section, you might want to calcuate new indexPath.
-(IBAction)btnActn:(id)sender{
if(btn.tag ==0){
self.indexPath=[NSIndexPath indexPathForRow:self.indexPath.row+1 inSection:self.indexPath.section];
//Put animation code or call animation function
}
}
And then get the rect of one cell above or below's frame using the same method you already are using and translate the _imageView's location to the new location.

Resources