Convert origin of UICollectionViewCell to ViewController's frame - iphone

When a user selects a collectionView cell, I animate that cell's frame to grow and reposition so that it is sitting has this size/location:
CGRectMake(114, 148, 540, 620)
This works well if I haven't scrolled down to other cells in the collectionView. When I try this on a lower cell, it still animates, but the cell goes shooting up so that it's y coordinate can be at 148 for the collectionView.
I have tried all sorts of variants of convertRect and convertPoint, but I am unable to conceptualize the correct solution.
What do I need to do to convert the selected cell's y value to move to the equivalent of 148 in the superview's coordinate system?
EDIT: To reduce confusion
I tap on a cell at the bottom (meaning I scroll down several rows) of my collectionView and this is the origin:
(x=394.5, y=4114)
The x here is fine, but I have a problem with the y. I want to animate this cell that I just selected so that it appears as though it's y coordinate is at 148 of the outer view. Just like a form sheet modal view controller. But setting that origin to 148 causes the cell to fly up to the top of the collectionView because it is all the way down at 4114. How can I get the correct y value that looks like 148 to the user, but in reality will be something closer to the cell's original origin?
EDIT 2: PIC

If I understood correctly what you want to do then the solution is simple: the "y" position of your cell should be self.collectionView.contentOffset.y + 148.
CGRectMake(114, self.collectionView.contentOffset.y + 148, 540, 620);
This will work with any given scroll value.
Hope this helps!

Related

Collection View Insert Item Weird Animation

I have a messages collection view that is rotated 180 degrees (so that the cells are appended from the bottom).
collectionView?.transform = CGAffineTransform.init(rotationAngle: (-(CGFloat)(Double.pi)))
cell.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi))
I want to use the insertItem option when appending new cells, but it causes the cells to perform an awkward animation where the ones visible on the screen are flipped upside down and over to the opposite side. However, when they are scrolled out of view and back into view, they reset into the right positions.
This is a video of the bug: https://www.youtube.com/watch?v=2X8FjOf5AqA
This is happening because when performBatchUpdates is called when you add the new cell, all visible cells are re-rendered and the transform is applied again, essentially removing the transform.
You only want this to happen once, so the cells will maintain their transform. To do this, ensure the transform of the cells matches that of the collectionView, which we know won't change (because the collection view itself is not re-rendered on performBatchUpdates).
Also, you don't need to invert one of the transforms - a rotation by -π is equal to a rotation by π.
collectionView?.transform = CGAffineTransform.init(rotationAngle: CGFloat(Double.pi))
cell.transform = collectionView!.transform
I believe I fixed the issue by creating a UIView inside the custom collection view cell, and fitting all of the content (like the text bubble) inside that view then rotating the view by pi (instead of rotating the cell by pi). I still rotated the collection view using Bradley's answer above.
collectionView?.transform = CGAffineTransform.init(rotationAngle: CGFloat(Double.pi))

In Swift, how to change table cell layout when a orientation happens?

I have a Table View and I try to change a cell's layout after an orientation happens by changing auto-layout constraints as well as a cell's height.
I update the new constraints in a function, say setMyConstraints() inside a cell class. If an orientation happens, I try to call setMyConstraints() inside layoutSubViews() in a cell.
However, this is not the right place because multiple layoutSubViews() are called and some of them are still using the old height until the last one. Here are some logs I trace after an orientation happens:
cell layoutSubviews called, frame.height = 69
tableview heightForRowAtIndexPath called, return height = 170
cell layoutSubviews called, frame.height = 69
cell layoutSubviews called, frame.height = 170
What makes worse is that if I don't clean up all the constraints before the first layoutSubViews, conflict might already happen.
Hence, here is the process needed:
The device orientation happens
Clean up all the constraints for the views inside the cell
The cell view rotates and gets the updated height
Add updated constraints for the views inside the cell
I can't find the right place to do (2) and (4). I have tried several ideas but all fail, some are pretty close, but I still can't find the reasonable/perfect place to do so.
In another words, how to change cell layout (including constraint changes and cell height change) when a orientation happens?
UIView has an updateConstraints() function that you can override. That's a good place to set the constraint changing code.
That method may get called automatically after the rotation. But if not, you can send the cell a setNeedsUpdateConstraints() message right after the rotation starts, or after it finishes.

UITableView scroll both vertically and horizontally

I have too many columns in my table and too much data too. For that reason I need to scroll my UITableView both vertically and horizontally. Is there a direct way to do so or I need to go through sources like Easy tables?
You can use an UIScrollView and then inside add the UITableView. This UIScrollView will have the same size that your UITableView have now, but the UIScrollView contentSize property will have the same height but it would have a greater width.
I have a similar situation: a lot of columns and rows, the tableView needs to be horizontally scrollable. My solution is like that:
predefine a column header with width same as the desired tableView, say 537
top view (320 x 455)
+ scroll view (320x455), content size = (537x455)
+ view as a container (537 x 455)
+ column header (0, 0, 537, 44)
+ tableView (0, 44, 537, 455-44)
Create a function to compute these numbers and reattach the frames to each object
after tableview reload, call this function
Here is a trick to do both vertical and horizontal scrolling with a UITableView.
Playing with width and contentsize to make it work:
https://stackoverflow.com/a/41230797/860488

Aligning rows in UITableView

This may sound a newbie question, however I'm new to iOS dev.
I've got a UITableView on my iPad app. TableView has obly three rows, is there a way to tell UITableView to view rows vertically centered, i.e. to not from the top to down.
Figure out the sum of the heights of all 3 rows, call it MyTotalHeight.
float MyTotalHeight = heightOfRow0 + heightOfRow1 + heightOfRow2;
Set your
tableView.frame = CGRectMake(start_X, start_Y, tableWidth, MyTotalHeight);
If you want the contents of each row/cell to be centered vertically within the cell, this will depend greatly on what is in the cell. You will need to calculate the height of the content and then center that content vertically within the cell by adjusting it's frame.
You may want to try the UiTableView.sectionHeaderHeight property. Play with the number until the cells are centered vertically. If your using a plain table view, I don't know how well this will work for you.
--John

Height of UIPicker

I've been trying to change the height of a pickerView. I would like it to show a single row instead of the default five rows.
help me plz
Better u can use PickerView Frame like this,
Pickerview.frame = CGRectMake(30,100,170,200);
You can't. UIPickerView can show either 5 rows or 3 rows, depending on the height of the frame you pass to the -setFrame: method. When I need a short UIPickerView, I'll pass a height of 100. The code in UIKit will adjust that height to be the closest allowed value.
I'll also note that this is for a very good reason. A one row pickerView, as has been noted elsewhere, would be fiendishly difficult to scroll. Also, the number of visible rows must be odd so that the currently selected row will be centered vertically. This means 3 or 5 rows, because 7 would make the thing way too tall to be practical on an iPhone.
As an aside, this also works with UIDatePicker for the same reasons. The exception is when the date picker is in the UIDatePickerModeCountDownTimer, which does not support the 3-row variant.
If you absolutely MUST have a one row picker view:
Create a UIView sized 170 wide by 55 tall.
Set the view properties clip subviews = YES
Add a UIPickerView as a subview of the UIView. Set its origin to 0, -80.5.
Then add a UIImageView sized 170, 55 as a subview to the UIView. Set its image to the one shown below.
(You can modify the image and make it stretchable to resize it horizontally)
Final Result:
did you try to implement numberOfRowsInComponent: ? If this doesn't change the size, did you try to set the picker's frame ?
ps: I agree with #Ritheesh#BoltClock, one row isn't a good idea