Collectionview animated - ios

I have collection view with items, each item has dimension (65 * 65) with horizontal flow, and I have button.
So when I click on the button all items must stack over first item, then I need to make collection layout vertically (like table view).
How to make it (with animation)?
func collectionView(collectionView: UICollectionView,layout collectionViewLayout: UICollectionViewLayout,sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
if self.isClose {
return CGSizeMake(50, 50)
}else{
if self.isOpen {
return CGSizeMake(320, 50)
}else {
return CGSizeMake(50, 50)
}
}
}
Screenshot

In Swift 3 and 4
func collectionView(_ collectionView: UICollectionView, didHighlightItemAt indexPath: IndexPath) {
UIView.animate(withDuration: 0.5) {
if let cell = collectionView.cellForItem(at: indexPath) as? SSProductCell {
cell.imageView.transform = .init(scaleX: 0.95, y: 0.95)
cell.contentView.backgroundColor = UIColor(red: 0.95, green: 0.95, blue: 0.95, alpha: 1)
}
}
}
func collectionView(_ collectionView: UICollectionView, didUnhighlightItemAt indexPath: IndexPath) {
UIView.animate(withDuration: 0.5) {
if let cell = collectionView.cellForItem(at: indexPath) as? SSProductCell {
cell.imageView.transform = .identity
cell.contentView.backgroundColor = .clear
}
}
}

Related

After reload collectionview,it always move to the first cell if also select the last cell

I have attached this image. You can see the problem here I have implemented the horizontal collection view where cells contains label. When we select the not visible items of the cell (after the first load 4 to 5 items are visible) and reload the cell it always moves to first visible cells.how should I handle the this problem?
func collectionView(
_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier:
"profile_CollectionViewCell_city", for: indexPath as IndexPath) as!
profile_CollectionViewCell
cell.contentView.translatesAutoresizingMaskIntoConstraints = false
if ((self.data_array[indexPath.row] as! NSMutableDictionary)["title"] != nil) {
cell.city_name.text = ((self.data_array[indexPath.row] as! NSMutableDictionary)["title"] as? String)?.uppercased()
}
if (indexPath.row == selectedIndex) {
cell.city_name.textColor = UIColor(red: (0.0 / 255.0), green: (120.0 / 255.0), blue: (56.0 / 255.0), alpha: 1)
cell.city_name.font = UIFont(name: "Poppins-Bold", size: 14)
cell.lower_view.isHidden = false
} else {
cell.city_name.textColor = UIColor(red: (156.0 / 255.0), green: (156.0 / 255.0), blue: (156.0 / 255.0), alpha: 1)
cell.city_name.font = UIFont(name: "Poppins-Light", size: 14)
cell.lower_view.isHidden = true
}
return cell
}
func collectionView(
_ collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
return data_array.count
}
func collectionView(
_ collectionView: UICollectionView,
layoutCollectionViewLayout: UICollectionViewLayout,
sizeForItemAtIndexPath: IndexPath) -> CGSize {
let size = ((self.data_array[indexPath.row] as!
NSMutableDictionary)["title"] as? String)?.size(withAttributes:
nil) ?? CGSize.zero
return size
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAtIndexPath: IndexPath) {
selectedIndex = indexPath.row
self.city_table.reloadData()
}

How to make the left and right image opacity down?

How to lower the opacity of the the left and right image? I am using a CollectionView to show all the data in the image. I want to lower the opacity of the views to the left and right of the center. I don't know how to do that. I can do all stuff in viewDidLayoutSubviews. Please resolve this issue. This is my code:
var arrHeading = ["Total Visitors in last 30 Days", "Total Departments", "Total Employees"]
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return arrHeading.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "VisitorDashboardCell", for: indexPath) as! VisitorDashboardCell
cell.imgBG.layer.cornerRadius = 10
cell.imgBG.layer.masksToBounds = true
//Set Gradient Color to CollectionViewCell
cell.layer.shadowColor = UIColor.black.cgColor
cell.layer.shadowOffset = CGSize(width: 0, height: 0)
cell.layer.shadowRadius = 2.0;
cell.layer.shadowOpacity = 0.9;
cell.layer.cornerRadius = 10
cell.layer.masksToBounds = false
cell.imgBG.layer.shadowPath = UIBezierPath(rect: CGRect(x: -8, y: -18, width: cell.frame.size.width + 8 , height: cell.frame.size.height + 18)).cgPath
cell.layoutIfNeeded()
cell.imgBG.image = UIImage.init(named: arrImage[indexPath.row])
cell.imgIcon.image = UIImage.init(named: arrIcon[indexPath.row])
cell.lblHeading.text = arrHeading[indexPath.row]
cell.lblNum.text = arrNum[indexPath.row]
return cell
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let middleValue = round(Double(arrHeading.count / 2))
print("Middle Value \(middleValue)")
if arrHeading.count < Int(middleValue)
{
var leftArray = [Int]()
for i in 0..<(Int(middleValue) - 1) {
leftArray.append(i)
}
print("Left Array \(leftArray)")
}
else if arrHeading.count > Int(middleValue)
{
var rightArray = [Int]()
for i in Int(middleValue)..<arrHeading.count
{
rightArray.append(i)
}
print("Right Array \(rightArray)")
}
else
{
//Show middle element of the collection view
let selectedIndex = IndexPath(item: Int(middleValue), section: 0)
self.collectionView.scrollToItem(at: selectedIndex, at: .centeredHorizontally, animated: false)
}
}
Try something like this on your delegate:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
UIView.animate(withDuration: 0.5) {
cell.alpha = cell.isSelected ? 1 : 0.5
}
}

How to animate UICollectionview cells as i scroll

How can i animate Horizontal Collectionview as it is scrolled i changed alpha to 0 in the cell and in cellForItemAt i animate the alpha back to 1 but that only happens when the Collectionview is scrolled through the first time here is the code i have tried
UIView.animate(withDuration: 0.8) {
cell.imageView.alpha = 1
cell.onboardLabel.alpha = 1
}
I also tried to do this in scrollViewDidEndDecelerating but still not working
let index = Int(scrollView.contentOffset.x) / Int(scrollView.frame.width)
let indexPath = IndexPath(item: index, section: 0)
let cell = collectionView.cellForItem(at: indexPath) as? OnboardingCell
UIView.animate(withDuration: 0.8) {
cell?.imageView.alpha = 1
cell?.onboardLabel.alpha = 1
}
Swift 4:
Use this function from UICollectionViewDelegate:
override func collectionView(_ collectionView: UICollectionView,
willDisplay cell: UICollectionViewCell,
forItemAt indexPath: IndexPath) {
cell.alpha = 0
UIView.animate(withDuration: 0.8) {
cell.alpha = 1
}
}
Firstly you need to know which cells are visible so set this variable at the top of the file.
var visibleIndexPath: IndexPath? = nil
In scrollViewDidEndDecelerating use this code to set the visibleIndexPath:
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
var visibleRect = CGRect()
visibleRect.origin = collectionView.contentOffset
visibleRect.size = collectionView.bounds.size
let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)
if let visibleIndexPath = collectionView.indexPathForItem(at: visiblePoint) {
self.visibleIndexPath = visibleIndexPath
}
}
Now that you have a visibleIndexPath you can animate the cell in the willDisplay cell function.
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if let visibleIndexPath = self.visibleIndexPath {
// This conditional makes sure you only animate cells from the bottom and not the top, your choice to remove.
if indexPath.row > visibleIndexPath.row {
cell.contentView.alpha = 0.3
cell.layer.transform = CATransform3DMakeScale(0.5, 0.5, 0.5)
// Simple Animation
UIView.animate(withDuration: 0.5) {
cell.contentView.alpha = 1
cell.layer.transform = CATransform3DScale(CATransform3DIdentity, 1, 1, 1)
}
}
}
}

Items in UICollectionView disappeared on scrolling

I have an UICollectionViewController which will be displayed both on its own full screen mode as well as in a pop-up view of another controller. The full screen mode works perfectly. However, in the pop-up mode, all items disappears after the user scroll the content up and down for a few times (sometimes more than 10 times, but also happen at the first or second time)
let vc = storyboard.instantiateViewController(
withIdentifier: "myCollectionView") as? MyColle ctionViewController
// set up the overlap in the parent controller
let bounds = CGRect(x: x + 22, y: parentFrame.origin.y + dy,
width: width, height: parentFrame.height - dy - 10)
overlayView = UIView(frame: bounds)
overlayView!.layer.cornerRadius = 5.0
overlayView!.backgroundColor = UIColor(red: 0.8, green: 0.8, blue: 0.8, alpha: 0.4)
self.view.addSubview(overlayView!)
vc.showAsPopup(overlayView!)
// in MyCollectionViewController, add itself to the parent popup view
func showAsPopup(_ parentView: UIView) {
view.backgroundColor = UIColor.red // test color to show the view is never gone
view.layer.cornerRadius = 5.0
collectionView?.backgroundColor = UIColor.clear
collectionView?.layer.cornerRadius = 5.0
parentView.addSubview(view)
view.frame = CGRect(x: 0, y: 20,
width: parentView.frame.width,
height: parentView.frame.height - 20)
NSLog("my view bounds after: \(view.frame.origin.x) \(view.frame.origin.y)")
NSLog(" : \(view.frame.width)x\(view.frame.height)")
}
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(_ collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
NSLog("\(items.count) items in section \(section)")
return items.count
}
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
let screenRect = view.bounds
let scale = UIScreen.main.scale
let width = screenRect.size.width - 20
return CGSize(width: width, height: 45 * scale)
}
override func collectionView(_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let item = items[indexPath.item]
let cellId = "RCCell_\(item.id)"
NSLog("creating cell \(cellId)")
// Register cell classes
self.collectionView!.register(RemoteControlViewCell.self,
forCellWithReuseIdentifier: cellId)
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId,
for: indexPath) as! RemoteControlViewCell
// Configure the cell, override the icon in Cell
cell.itemId = item.id
cell.itemIcon.image = item.icon
cell.itemDescriptionLabel.text = item.description
return cell
}
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 12.5, left: 0, bottom: 12.5, right: 0)
}
override func collectionView(_ collectionView: UICollectionView,
didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
NSLog("removed cell at \(indexPath.row)")
}
// MyCollectionViewCell
override init(frame: CGRect) {
super.init(frame: frame)
let scale = UIScreen.main.scale
NSLog("Cell frame w: \(frame.size.width) h: \(frame.size.height), scale \(scale)")
let spacing = CGFloat(10)
contentView.backgroundColor = UIColor.white
contentView.layer.cornerRadius = 5
contentView.layer.masksToBounds = true
itemIcon = UIImageView(frame: CGRect(x: spacing, y: spacing,
width: CGFloat(24.0), height: CGFloat(24.0)))
itemIcon.contentMode = UIViewContentMode.scaleAspectFit
contentView.addSubview(itemIcon)
NSLog("icon w: \(itemIcon.frame.size.width)")
let labelX = spacing + 5 + itemIcon.frame.size.width
let font = UIFont.systemFont(ofSize: 20)
itemDescriptionLabel = UILabel(
frame: CGRect(x: labelX, y: spacing,
width: frame.size.width - labelX - spacing,
height: font.lineHeight))
itemDescriptionLabel.textColor = UIColor(colorLiteralRed: 0x66 / 255.0, green: 0x66 / 255.0, blue: 0x66 / 255.0, alpha: 1.0)
moduleDescriptionLabel.font = font
contentView.addSubview(itemDescriptionLabel)
NSLog("item desc \(String(describing: itemDescriptionLabel.text)) w: \(itemDescriptionLabel.frame.size.width)")
}
I tried changing the background color of the collectionView to visible and can see that the collect view itself was never gone even though the items disappeared. I also added logging to the collectionView() callback methods and found that they were never called again after the initial view presentation.
What could cause the items to disappear during scrolling?
Try using prepareForReuse in RemoteControlViewCell class
override func prepareForReuse() {
itemId = ""
itemIcon.image = nil
itemDescriptionLabel.text = ""
}

UICollectionView indexPath.row strange behaviour

I'm having strange issue while scrolling one of my collectionViews. When I'm printing indexPath.row is goes ok from 0..6 but then last indexPath.row is 3, and then if I scroll back it either crashes with excbadadress or prints 1, 2, 4 in random order. I assume that I have and error in my code but really don't understand where is it.
Here is my code:
VC:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize {
if collectionView == mainEventsCollectionView {
return CGSize(width: UIScreen.main.bounds.width - 40, height: 180)
} else {
return CGSize(width: 150, height: 200)
}
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if collectionView == mainEventsCollectionView {
return 3
} else {
return 7
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if collectionView == mainEventsCollectionView {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "mainEventsCell", for: indexPath) as! MainEventCollectionViewCell
cell.eventTitle.text = "Hello world".uppercased()
cell.setupCell()
return cell
} else {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "importantEventsCell", for: indexPath) as! ImportantEventsCollectionViewCell
print(indexPath.row)
cell.setupCell()
return cell
}
}
Cell:
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.roundCorners(.allCorners, radius: 6, borderColor: .clear, borderWidth: 0)
}
func setupCell() {
self.content.backgroundColor = colorWithAlpha(.black, alpha: 0.7)
self.eventDate.textColor = .white
self.eventTime.textColor = .white
self.eventName.textColor = .white
if self.content.layer.sublayers!.count > 3 {
self.content.layer.sublayers!.removeLast()
}
if self.eventDate.text == "Today" {
self.content.backgroundColor = .clear
DispatchQueue.main.async(execute: {
self.content.drawGradient(colors: [UIColor(red: 250/255, green: 217/255, blue: 97/255, alpha: 0.7).cgColor, UIColor(red: 255/255, green: 135/255, blue: 67/255, alpha: 0.7).cgColor], locations: [0, 1])
})
self.eventDate.textColor = .black
self.eventTime.textColor = .black
self.eventName.textColor = .black
}
}
Ok, the problem was that I've tried to apply gradient to a UIView, which had elements (UILables). What I had to do is add a subview to the UIView and apply gradient to it.

Resources