How to get the position of tableviewcell after scrolling the tableview - iphone

I want to get the position of UITableVIewCell relative to the screen, not relative to tableview. So, if I scroll the tableview, the position is updated.

You should use two steps to achieve this:
Get the CGRect information for a selected cell/header or footer by using one of these methods of UITableView:
- (CGRect)rectForHeaderInSection:(NSInteger)section;
- (CGRect)rectForFooterInSection:(NSInteger)section;
- (CGRect)rectForRowAtIndexPath:(NSIndexPath *)indexPath;
2. Convert the CGRect to table's container view by using UITableView's convertRect method. Eg. to get the current pos of the first header you can use this code:
CGRect rect = [mytable convertRect:[mytable rectForHeaderInSection:0] toView:[mytable superview]];
If you want these above dinamically you might want to include this code in UITableView's delegate method:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView_ {.....
One example what I've done using similar techniques is at github - how to make table header row fixed:
https://github.com/codedad/SO_Fixed_TableHeader_iOS
Hope it helps you!

You need to get position from child to parent:
float x = cell.frame.origin.x;
float y = cell.frame.origin.y;
UIView* parent = cell.parent;
while(parent != nil)
{
x += parent.frame.origin.x;
y += parent.frame.origin.y;
parent = parent.parent;
}

Use the -[UITableView rectForRowAtIndexPath:] method. Keep in mind that if you attempt to get this when the cell is off screen you will get unexpected results. You can then convert it to your view controller's view (which i think is what you mean by screen) with the -[UIView convertRect:toView:] method.
Ref: https://developer.apple.com/library/ios/documentation/uikit/reference/UITableView_Class/Reference/Reference.html#jumpTo_49
https://developer.apple.com/library/ios/documentation/uikit/reference/uiview_class/UIView/UIView.html#jumpTo_65

Related

UICollectionViewCells with UICollectionViewFlowLayout - strange layout happening

I am currently testing in xcode a UICollectionView with just one horizontal row like a kinda cover flow. Basically I have my own Custom Cell class and xib file for the cell and then on each cell I am adding another UIView with a xib. In case you are wondering why, it is so I can add different UIViews to the cell. Right now I am only adding one.
Edit I have followed the WWDC 2012 video on creating a linelayout of a UICollectionViewCell with one difference. Instead of the cell in the middle getting bigger all the other cells get smaller.
Everything below is new to my question.
-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
NSArray *array = [super layoutAttributesForElementsInRect:rect];
CGRect visibleRect;
visibleRect.origin = self.collectionView.contentOffset;
visibleRect.size = self.collectionView.bounds.size;
for (UICollectionViewLayoutAttributes *attributes in array){
if (CGRectIntersectsRect(attributes.frame, rect)) {
CGFloat distance = CGRectGetMidX(visibleRect) - attributes.center.x;
CGFloat normalizedDistance = distance / ACTIVE_DISTANCE;
if (ABS(distance) < ACTIVE_DISTANCE) {
//THIS WOULD MAKE THE MIDDLE BIGGER
//CGFloat zoom = 1 + ZOOM_FACTOR *(1- ABS(normalizedDistance));
//attributes.transform3D = CATransform3DMakeScale(zoom, zoom, 1.0);
//attributes.zIndex = round(zoom);
} else {
//THIS MAKES ALL THE OTHERS NOT IN THE RECT SMALLER
CGFloat zoom = 1 + ZOOM_FACTOR *(1- ABS(normalizedDistance));
attributes.transform3D = CATransform3DMakeScale(zoom, zoom, 1.0);
attributes.zIndex = round(zoom);
}
}
}
return array;
}
The problem can be seen in the attached image.
Pink = Collection View Size
Brown = Cell size
Green = Cells Content size and an attached xib to the content size.
The problem I THINK I have is with the layout. When the sell is dequeued it is made smaller by the above code. Then when it is reused the CELL gets bigger again but the content view does not.
I have tired to manually set the frame of the content view but that does nothing.
UPDATE 1: This also only happens when I add a xib to the Cells content view. If there is no subview to the content view then there is no problem
UPDate 2: It appears that the subview of the cell, my xib is not resizing. I have tried to manually change its frame size but the only place this helps is in the cells drawrect method which feels like a hack to me.
reused cell not able to redraw itself so give call to
-(void)setFrame:(CGRect)frame {
[super setFrame:frame];
[self setNeedsDisplay]; // force drawRect:
}
from cellForItemAtIndexPath of the UICollectionView.
also have a look at this link
and this question
My answer is very specific and I am not sure it will help anyone.
The problem was that I had a constraint on the bottom of the grey view. After I changed this constraint to a less than or equal too then for some reason it worked.
Now I know this does not explain why it was not happening to every cell but it fixed my problem.
As such Harsh's answer might also be worth looking at if you have landed here after doing a search.
Edit: there also appears to be some bugs in the 6.0 UiCollectionView controller which seem to be fixed in 6.1

How to select a row in table view when it reach a specific position?

I want to select a table view row when the person reaches the center of the table view. Basically whenever the table reaches a point y I want the cell at that point to be selected.
I imagine it is similar to uiPickerView.
In your UITableViewController you should implement -scrollViewDidScroll: like this:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (prevCell != nil)
self.prevCell.selected = NO;
CGPoint offset = self.tableView.contentOffset;
CGPoint point = offset;
point.y += self.tableView.center.y;
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:point];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
cell.selected = YES;
self.prevCell = cell;
}
This is tested and works. prevCell is a property of type UITableViewCell.
You must get the current offset of the scroll view for the table view and add this to the position of the cell you want (in this example, I take the cell in the center of the table view).
Then, using -indexPathForRowAtPoint: we grab the index path for the cell at the point and using -cellForRowAtIndexPath: we get the cell for the index path. Set it to selected and store it for later use (to deselect it on the next scroll).
have you tried
[[yourTableView cellForRowAtIndexPath:[yourTableView indexPathForRowAtPoint:wantPoint]] setSelected:true]
?
I think it can be achieved by getting all visible indexpaths, then data on visible indexpaths. The best answer you may see your own cz you know your problem well. Go through this class reference:
https://developer.apple.com/library/ios/#documentation/uikit/reference/UITableView_Class/Reference/Reference.html

Get the position of an element

I'm having trouble trying to scroll up a tableView when the user start editing a UITextField displayed in one of the cells.
My problem is that I can't find a way to know the position of the UITextField in the view. If I try to do activeTextField.frame.origin.y, I get the position of the TextField inside the cell, but not inside the tableView.
The way I build the view is the following :
I've got a TableViewController, which creates cells using a custom class that initializes the UITextField. Then my TableViewController set the UITextField delegate to itself, so I can trigger the textFieldDidBeginEditing event. But if I try to NSLog the y origin of the TextField, I always get the same value for each UITextField, which is its position in the cell.
Any idea on how I can solve this?
It's always confusing with these coordinate system changes ...
This should work to get you the point in the table view coordinate system:
CGPoint textFieldCenter = textField.center;
CGPoint pointInTableView = [tableView convertPoint:textFieldCenter fromView:textField.superview];
If you want to have it in a different view, you should replace tableView with the view you want to have the coordinate in.
And if you want to get the cell in the table the textField was in:
NSIndexPath* path = [tableView indexPathForRowAtPoint:pointInTableView];
UITableViewCell* cell = [tableView cellForRowAtIndexPath:path];
To get the position of your textfield should use the UIView method convertRect:toView:
convertRect:toView: Converts a rectangle from the receiver’s
coordinate system to that of another view.
(CGRect)convertRect:(CGRect)rect toView:(UIView *)view
example :
CGRect textFieldFrame = [self.tableview convertRect:yourTextField.frame toView:self.view];
this should help you out
This is simple and easy way of doing what you want
Yes, try using this method :
- (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated
When you prompt the keyboard, scroll the tableView to the selected cell it should bring the cell to the top of the screen.
try this
CGPoint locationinView=[cellView convertPoint:location fromView:tableView];
here location is the point of textField in cellView.

Shifting UITableView down (UITableViewController)

I am just wondering whether or not it is possible to shift a UITableView down the page by, say, maybe 50 pixels. I know this would usually work if I had used a UIViewController then added a table view on top, but would I be able to do this and still keep it as UITableViewController?
I had the same problem and the answer above didn't work. This did:
[self.tableView setContentInset:UIEdgeInsetsMake(50,0,0,0)];
My solution is to override tableViewcontroller's method viewWillLayoutSubviews
- (void) viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
self.tableView.frame = CGRectMake(0,0,CGRectGetWidth(self.view.frame),300);
}
Works great and always for me with changing orientations and in all situations
A UITableView is actually a UIScrollView. This means that you can scroll the UITableView to the point you want. This is a previous link which shows you how to do this, including sample code and discussion.
Edit: In order to shift the WHOLE tableview down, just use:
float yOffset = 50.0f; // Change this how much you want!
tableview.view.frame = CGRectMake(tableview.view.frame.origin.x, tableview.view.frame.origin.y + yOffset, tableview.view.frame.size.width, tableview.view.frame.size.height);
Hope that Helps!
Since a Table View is backed by a UIScrollView you can move in around using the content Offset.
self.tableView.contentOffset = CGPointMake( x, y);
You might want to wrap in a UIView animation
If you are trying to add a UI element at the top of the table, why not just set it to the tableHeaderView instead?
UILabel *someLabel;
// configure label
self.tableView.tableHeaderView = someLabel;
If you need a view behind (or on top of) the tableview, then you'll have to subclass UIViewController instead and add a UITableView afterwards.
Another solution could be to set the table's header view (reference) but in this case, keep in mind that this view will scroll together with the table.
More information about the limitations of UITableViewController in this article: "Clean table view code".
Swift 2.2:
To shift the tableView inside a UITableViewController down:
let edgeInsets = UIEdgeInsetsMake(20, 0, 0, 0)
self.tableView.contentInset = edgeInsets
UITableViewController is actually a UIViewController, only plus is it gives you some methods to override and useful for table actions. so you can do whatever you want
check this, once you get the idea of what UITableViewController actully is you will do whatever you want
http://cocoawithlove.com/2009/03/recreating-uitableviewcontroller-to.html

Determine coordinates of a UITableViewCell while scrolling

My goal is to have the UITableViewCells fade in/out when they are approaching the bounds of the UITableView and about to be covered/revealed.
The approach I have been trying is to get the coordinates of the UITableViewCell during a scroll event. The problem is that every cell seems to be at 0,0. I have tried converting the coordinates to the parent table and view, but they still come out at 0,0.
So in general, if anyone knows a way to get the coordinates, or of a better way to go about fading UITableViewCells in and out based on their position, I would greatly appreciate any advice you may have.
Thanks for your time,
Joel
The first step is to use
CGRect rectInTableView = [tableView rectForRowAtIndexPath:indexPath];
which will report the CGRect of a cell within the tableView. However, this value does not change as the tableView scrolls. It is the position relative to the first row of the table (and not the first visible row). To get the position of the cell on the screen you have to convert it to the superviews coordinate system using
CGRect rect = [tableView convertRect:rectInTableView toView:[tableView superview]];
So the following line does it all
CGRect rect = [tableView convertRect:[tableView rectForRowAtIndexPath:indexPath] toView:[tableView superview]];
Swift 4
// Consider the indexPath at row 1, section 0.
let rectWithinTableView : CGRect = self.tableView.rectForRow(at: IndexPath(row: 1, section: 0))
let rectWithSuperViewCoordinates : CGRect = self.convert(rect: rectWithinTableView, to: self.tableView.superview)
Why not an overlay with a partially transparent gradient PNG in a UIImageView that's less translucent at the top and bottom?
Messing with cell drawing in table scrolling is going to take a big performance hit.
You can call
- (CGRect)rectForRowAtIndexPath:(NSIndexPath *)indexPath;
to get the rect of any given cell. This will contain it's coordinates in the origin struct within the rect.
I suspect the cells are held within 'cell sized' subViews of the UITableView so you are seeing a frame relative to that view.
I don't have an actual an answer for you but, I would suggest checking out UIScrollView's delegate class: UIScrollViewDelegate. It responds to – scrollViewDidScroll: and you can manually work out your offset from that. UIScrollView is a superclass of UITableView.
You can convert points (such as your origin) to another view's co-ordinates using UIView's - (CGPoint)convertPoint:(CGPoint)point toView:(UIView *)view method.