Collectionview scroll cross top uiview - swift

Hello I was using collection-view since year everything was fine , but after update xcode 11 i am facing problem , when i scroll collection-view it cross the boundary of collection-view and cell shows after crossing the top just like in the image please guide me
Code
extension BusinessHomeViewController : UICollectionViewDataSource,UICollectionViewDelegate{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 50
//AppStrings.DashBoardMenu.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "home", for: indexPath) as! BusinessCollectionViewCell
// let model = AppStrings.DashBoardMenu[indexPath.row]
// cell.lblTitle.text = model
return cell
}

Can you check to make sure that your collection view's clipsToBounds property is set to true? You can find this in the interface builder, or set it programmatically via yourCollectionView.clipsToBounds = true.
What clipsToBounds does is determines whether a view's subviews will still be visible, even if they are moved beyond the parent view's bounds. Setting it to false will let the subviews still be visible, even when scrolled beyond the collection view's bounds, so you'll want this property to be set to true.

Related

Make the first cell automatically selected when VC opens is not working

I have a ViewController that have a collectionView and I managed to make it selectable and all but the problem is that I have a checkmark image that stays in the first cell when the VC opens but in fact the cell is not selected at all and still the checkmark is there!
Code of the VC:
var selected = IndexPath(item: 0, section: 0)
var properties = connectedProperties(StatusCode: 0)
var propertiesNew = connectedProperties(StatusCode: 0)
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return properties.Result?.count ?? 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "dashboardCollectionViewCell", for: indexPath) as? dashboardCollectionViewCell else { return UICollectionViewCell() }
let currentPropertie = properties.Result?[indexPath.row]
cell.checkMarkButton.isHidden = !(indexPath == selected)
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let selectedCell = properties.Result?[indexPath.row]
changeCustomerKey.DefaultsKeys.keyTwo = indexPath.row
changeCustomerKey.DefaultsKeys.keyThree = selectedCell!.id!
let previous = selected.dropLast()
selected = indexPath
collectionView.reloadItems(at: [previous, selected])
}
If you want to tell your collection view to select a specific cell, you need to call the UICollectionView method selectItem(at:animated:scrollPosition:).
The "tricky bit" is that you can't call that until the collection view has finished populating itself (by calling your data source methods) and the first cell has been added to the collection view.
You might need to resort to something a bit hacky like adding an "initialDisplay" bool property who's value starts as true.
In your data source method that returns cells, check if initialDisplay==true and the requested indexPath is (0,0). If so, set initialDisplay=false, and fire a one-shot timer with a short delay. In the timer's closure, call selectItem(at:animated:scrollPosition:). The timer delay will return control to the event loop and give the system time to add the cell to the collection view.
There might be a better way to do this, but I can't think of it offhand, since you can't be sure when you will be asked to return your cell at IndexPath (0,0)

SWIFT: How to fix cell highlighter and make the whole collection view scroll instead of the highlighter?

I am building a TVOS app where I have this collectionView:
The current cell (The cell which has scrolled to), gets highlighted in Orange.
For example, here the user scrolls to the third cell:
WHAT I AM TRYING TO ACHIEVE:
When the user scrolls to another cell, I want the Orange square, to remain in the first cell, and the whole collection to scroll to the left(or to the right if the user is scrolling in the opposite direction.
And I honestly have no idea how to achieve this, or what should I use exactly.
Should I embed the whole collection view inside of a scrollView?
Anyway, here's how implemented that collection view:
extension MoviesViewController2: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
print("first function collectionView detected")
return items2.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier:
cellIdentifier, for: indexPath) as! movieCardCell
cell.movieImageView.sd_setImage(with: URL(string: items2[indexPath.item].imageURL))
return cell
}
// Handle collectionViewItem selection
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("didSelectItem\(indexPath)")
}
// Highlight the current cell
func collectionView(_ collectionView: UICollectionView, didUpdateFocusIn context: UICollectionViewFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) {
if let pindex = context.previouslyFocusedIndexPath, let cell = collectionView.cellForItem(at: pindex) {
cell.contentView.layer.borderWidth = 0.0
cell.contentView.layer.shadowRadius = 0.0
cell.contentView.layer.shadowOpacity = 0.0
}
if let index = context.nextFocusedIndexPath, let cell = collectionView.cellForItem(at: index) {
cell.contentView.layer.borderWidth = 8.0
cell.contentView.layer.borderColor = UIColor.orange.cgColor
cell.contentView.layer.shadowColor = UIColor.orange.cgColor
cell.contentView.layer.shadowRadius = 10.0
cell.contentView.layer.shadowOpacity = 0.9
cell.contentView.layer.shadowOffset = CGSize(width: 0, height: 0)
collectionView.scrollToItem(at: index, at: [.centeredHorizontally, .centeredVertically], animated: true)
}
}
}
If anyone can answer the question above, it'd be great. Also any tip or what I should use is most welcome.
As I understand, you want the orange rectangle to remain always on the same place. When scrolling you can make it disappear and re-appear once the scrolling has stopped maybe but that's a detail.
So you could put a UIView with the same dimensions as a cell (since all seem to have the same height and width) and make it appear once the user has stopped scrolling.
Anyway I'm looking again at your question and I think I didn't understand your issue correctly, specifically this part The current cell (The cell which has scrolled to), gets highlighted in Orange. in combination with this When the user scrolls to another cell, I want the Orange square, to remain in the first cell
The process might be as follows:
Set your collectionView's size to single cell size. And align it to the left
Make your collectionView's clipsToBounds property to false
Make UICollectionView paging enabled.
Place a rectangle view on top of your collectionView

Swift reconfigure collectionview cells

so I am trying to change the background color of the collection view cell that is clicked, however, when I call the CollectionView.reloadData() method the backgrounds don't change. I am thinking that reloading the data only checks for adding and deleting cells, but does not actually call the configure function for each cell again. I was wondering how I can reconfigure these cells so that the background color can change for the selected cell. Thanks for the help in advance!
This is the method that I call:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
...
bagCollectionView.reloadData()
}
Instead of calling reloadData, you can try:
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath)
cell?.backgroundColor = yourColor
}
Even though you do your logic in did select by finding a cell or implement logic in didSelectItemAt and didDeSelectItemAt, I suggest you should store the Index. Due to reusability of cell, there is chance that selected cell do not show color on scroll or if you have large number or records.
So save index in array(for multiple selections) or a single variable(single selection) and manage logic for the same.
For example:
cell.backgroundColor = selectedIndex == indexPath.item ? .red : .yellow

How to Set Corner Radius for Collection View Cells of Different Size

I want to have oval shaped collection cells with width based on the label/text length, but I am having trouble making all the cells look oval. I don't know how to resize based on the label's text length.
I am essentially trying to get something like the blank/pink picture below I saw on another post but the solution didn't work. I have also added what my view controller currently looks like.
1) How do I resize to get oval shape correctly and also 2) why are there longer spaces between some cells and how do I fix that?
Ideal Pic
Current Controller
Storyboard cell
(width of label is set to 150)
class HobbiesViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate{
#IBOutlet weak var collectionView: UICollectionView!
var items = ["karateeeeeeeeeee", "signup", "last", "madur", "open", "somelongword", "nice", "looooooooong", "karate", "karate","karate", "signup", "last", "madur"]
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.items.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "hobbyCell", for: indexPath) as! HobbiesViewCell
cell.label.text = self.items[indexPath.item]
cell.backgroundColor=UIColor.blue //try with different values untill u get the rounded corners
cell.layer.cornerRadius = cell.bounds.size.height / 2
cell.layer.masksToBounds=true
return cell
}
}
extension HobbiesViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "hobbyCell", for: indexPath) as! HobbiesViewCell
cell.label.text = items[indexPath.row]
cell.label.sizeToFit()
return CGSize(width: cell.label.frame.width + 10 , height: 70)
}
}
Ans 1. While setting the width of the collection view cell you need to have some minimum width for the cell so that the cell does not get so small that it looks like a circle. Your current height is 70 so that you should keep a condition that if the cell.label.frame.width + 10 is less than 160 then keep the size of the cell as 160.
Ans 2. Collection view itself manages the spacing between the cells according to the frame provided to collection view and the sized to the cell. To set the spacing right may be below link will be helpful to you.
Cell spacing in UICollectionView
From screen shot I can see that your font size also differs from the expected output so may be you can check that also.
Hope this helps you in some way.

Proper Timing to Draw Circles using Autolayout inside UICollectionView

Inside each collection view cell I have a view which I'd like to make a perfect circle. I'm basing the width of the cells on the main views width using Autolayout.
My problem: some of the views don't have a perfect circle. I'm guessing its a conflict in timing, that I don't have the main views bounds set yet before making these UIViews into circles. Should I draw the cornerRadius at a specific time? Everything else works fine. Thanks!
func collectionView(_ collectionView: UICollectionView, layout: UICollectionViewLayout, sizeForItemAt: IndexPath) -> CGSize {
return CGSize(width: self.view.frame.width/3, height: 400)
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let sessionCell = (collectionView.dequeueReusableCell(withReuseIdentifier: Storyboard.cellID, for: indexPath)) as? DayCollectionViewCell {
sessionCell.circleView.layer.cornerRadius = sessionCell.circleView.frame.width/2
return sessionCell
}
}
You need to set it here
override func layoutSubviews() {
super.layoutSubviews()
self.circleView.layer.cornerRadius = self.circleView.frame.width/2
}
Inside DayCollectionViewCell class