I have a custom UITableViewCell composed by two detail labels located at the beginning of the cell (one above the other) a thin view (used as a separator which the labels have their constraints related to), the main label and a button.
I implemented an animation to "hide" (actually moving to a non-visible position) the detail labels after some time when the tableview is loaded.
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
self.tableView.visibleCells.forEach { (cell) in
let songCell = cell as! SongCell
songCell.layoutIfNeeded()
songCell.leadingHoursSeparatorConstraint.constant = -10
UIView.animate(withDuration: 0.33) {
songCell.layoutIfNeeded()
}
}
}
I want to be able to see the detail labels when swiping the cell to the right. Any suggestions on how to achieve this? Any help will be appreciated :D
Related
I have a tableview which grows and shrink on user click. When user lands to the screen the height of tableview is same as cell(single cell). On click of that cell multiple cells get populated and tableview height would be same as no. Of cells. I want have animation from last cell to first cell, but what I am getting is animation from first cell to last cell, my tableview is at bottom of the screen(which grows in upper direction)
This is my code inside will display method
cell.alpha = 0
UIView.animate(with
duration:0.4,
delay:0.05*Double
(
indexPath.row),animation: {
cell.alpha = 1
}
According to my understanding, you want a tableView to scroll from bottom to top.
// scroll from bottom to top with delay
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
tableView.setContentOffset(.zero, animated: true)
}
So I have a collection view within a UIView that is contained in a scroll view. (See below)
The collection view's content within changes size depending on the tab selected.. When the number of items in the collection view is small (I.E. <= 4 items), I want to show the next button at the bottom of the screen. If the collection view's content is larger (I.E. >4 items), I want to allow the screen to be scrolled down (which works currently), and the next button to be placed below the collection view's content.
On first loading of the screen, on the tab with <=4 items, the next button is placed in the correct position. If I switch to the tab with >4 players, the next button is placed correctly below the collection view as expected. However, when I switch back to the tab with <=4 players, the next button is placed in the incorrect position, much higher up on the screen.
Now back to the tab with less players, issue arises:
See issue here:
https://drive.google.com/file/d/12eREBZlBZoCs-F5DJd-I26YcLc3pRqRJ/view?usp=sharing
Notice how when I switch back from forwards to midfielders, the next button is placed incorrectly where as the first time on midfielders the next button was placed correctly.
My code for resizing the collection view & changing the position of the next button is below.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CollectionViewCell
//Setup Img & Label
cell.playerImageView.image = playerArray!.filter({ $0.position == pos })[indexPath.row].image
resizeCollectionView() //Setup view size after items calculated
return cell
}
Resize method (called above):
func resizeCollectionView() {
self.collectionViewHeightConstraint.constant = collectionView.collectionViewLayout.collectionViewContentSize.height
if self.playerArray!.filter({ $0.position == pos }).count <= 4 {
self.nextBtn.topAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -120).isActive = true
}
else {
self.nextBtn.topAnchor.constraint(equalTo: collectionView.bottomAnchor, constant: 50).isActive = true
}
self.nextBtn.translatesAutoresizingMaskIntoConstraints = false
self.view.layoutIfNeeded()
}
Written in swift 4
Can anyone point me in the right direction why this issue occurs? Thanks in advance!
EDIT:
#Dris, when I add your change for the constraint the result is :
I have custom layout with fullscreen cells. When removing cell from the left (it's not visible at the time), UICollectionView jumps to the next cell.
It's like current cell was at index 4 and when cell on the left removed the next cell has index 4 now and immediately scroll to the next cell.
Describing in 3 steps (A is cell that need to be fullscreen, x will be removed, o other cells, large letter is fullscreen):
ooooAoo
oooxAoo
oooaOo
But must keep this oooAoo
Here is my solution if it can help to anybody, did not found how to achieve desired offset natively, so just scrolling contentOffset to the desired position right after reloadData():
var currentCell: MyCollectionViewCell? {
return (visibleCells.sorted { $0.frame.width > $1.frame.width }.first) as? MyCollectionViewCell
}
//-----------------------------------------
//some model manipulating code, removing desired items here...
let currentList = currentCell?.parentList
reloadData()
if let list = currentList, let index = self.lists.firstIndex(of: list) {
self.scrollToItem(at: IndexPath(row: index, section: 0), at: .centeredHorizontally, animated: false)
}
currentCell is computed property, returns optional middle cell.
Detect which cell is the largest, because of custom flowlayout logic.
parentList is the model item, I can compare cell by it to make life
easier. I check which list was attached to the cell before
reloadData().
I have a horizontal scrollable collectionView with two cells that take up the screen. Inside those cells is an embedded collection view that scrolls vertically. Is there a way for me to scroll the vertical CV inside the first cell, while using its ContentOffset to scroll the vertical CV in the second cell?
Here's how I'm trying to accomplish it:
let scrollView = notification.userInfo!["scrollView"] as! UICollectionView
if scrollView.contentOffset.y <= 250.0 {
childViewControllerForPosts.collectionViewForGroups?.collectionView.setContentOffset(CGPointMake(0, scrollView.contentOffset.y), animated: false)
self.topVerticalConstraint?.constant = -scrollView.contentOffset.y
}
else {
if self.topVerticalConstraint?.constant > -250 {
// Make sure it stays at -250
self.topVerticalConstraint?.constant = -250
}
}
The FeedCell would be the main collection view (which horizontally scrolls) that contains the vertical scrolling collection view. I'm trying to access the second one to change the vertical contentOffset when I scroll the one in first one.
Here's how I'm trying to save the variable that should contain the second main collection view:
collectionViewForGroups = collectionView(collectionView!, cellForItemAtIndexPath: NSIndexPath(forItem: 1, inSection: 0)) as? FeedCell
EDIT:
Note that when I scroll horizontally, the vertical scroll view didn't change. But I want it to change with the one I just scrolled in the gif. If I were to scroll the 2nd vertical collection view, the UIView above will reappear because the topLayConstraint changes due to the vertical contentOffset change.
The thing I want to achieve is a gallery, it can contain up to 300 images, using a UIScrollView will result in non optimized ram/cpu usage since it doesn't do pooling (correct me if I'm wrong), and it has a limitation on width, I can't make it 300 times the width of the screen (again correct me if I'm wrong).
so the right choice would be to use a UITableView
1 - how to make it scroll horizontally like in this gif ?
2 - how to make it snap to cells centers ?
EDIT
I'm using this, it gives the result I want but it has a problem, it has no tolerance for how much I should swipe to move to the next cell, I still need help..
func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool)
{
// Find collectionview cell nearest to the center of collectionView
// Arbitrarily start with the last cell (as a default)
var closestCell : UICollectionViewCell = collectionView.visibleCells()[0];
for cell in collectionView!.visibleCells() as [UICollectionViewCell]
{
let closestCellDelta = abs(closestCell.center.x - collectionView.bounds.size.width/2.0)
let cellDelta = abs(cell.center.x - collectionView.bounds.size.width/2.0)
if (cellDelta < closestCellDelta)
{
closestCell = cell
}
}
let indexPath = collectionView.indexPathForCell(closestCell)
collectionView.scrollToItemAtIndexPath(indexPath!, atScrollPosition: UICollectionViewScrollPosition.CenteredHorizontally, animated: true)
}
func scrollViewWillBeginDecelerating(scrollView: UIScrollView)
{
// Find collectionview cell nearest to the center of collectionView
// Arbitrarily start with the last cell (as a default)
var closestCell : UICollectionViewCell = collectionView.visibleCells()[0];
for cell in collectionView!.visibleCells() as [UICollectionViewCell]
{
let closestCellDelta = abs(closestCell.center.x - collectionView.bounds.size.width/2.0)
let cellDelta = abs(cell.center.x - collectionView.bounds.size.width/2.0)
if (cellDelta < closestCellDelta)
{
closestCell = cell
}
}
let indexPath = collectionView.indexPathForCell(closestCell)
collectionView.scrollToItemAtIndexPath(indexPath!, atScrollPosition: UICollectionViewScrollPosition.CenteredHorizontally, animated: true)
}
EDIT :-
I managed to do it without above code.
You should use UICollectionView with one cell or UIPageViewController to achieve this kind of effect. There is no way to use tableview horizontally. Somehow you can say UICollectionView as a horizontal representation of UITableView. UIPageViewcontroller is also good solution. You should read about both in detail and then decide what's more suitable for you!
and yes that's not good to use single scroll view with that much different size. It can create memory or performance issue!!
Update :
Have you tried to enable paging in your collection view's scroll view ?
look at screenshot below
Check the checkbox paging enable!
then after If you not feel smooth effect then you should try to uncheck adjust scroll view insets under viewcontroller under attribute inspector which you got by selecting your view controller
check the screenshot for that
EDIT by person who asked the question : -
adding this worked for me, as UICollectionView don't have
adjust scroll view insets option.
layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 0
you can use UICollectionView and configure collection view cell
set collectionViewLayout size... This size based on above view
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return CGSizeMake(250, 150);
}