수평으로 UICollectionView 셀을 중앙에 배치하는 방법은 무엇입니까?
몇 가지 연구를 수행했지만 UICollectionView에서 셀을 가로로 가운데에 배치하는 방법에 대한 코드 예제를 찾을 수 없습니다.
첫 번째 셀이이 X00 과 같은 것이 아니라이 0X0 과 같기를 원합니다 . 이것을 달성하는 방법이 있습니까?
편집하다:
내가 원하는 것을 시각화하려면 :
CollectionView에 요소가 하나만있을 때 버전 B처럼 보이도록해야합니다. 요소가 두 개 이상 있으면 버전 A와 비슷하지만 요소가 더 많아야합니다.
지금은 요소가 하나 뿐인 버전 A처럼 보이며 어떻게 B처럼 보이게 만들 수 있는지 궁금합니다.
도와 주셔서 감사합니다!
라이브러리를 사용하는 것은 좋은 생각이 아닙니다. 만약 당신의 목적이 이것이 바로 중앙 정렬이라면.
collectionViewLayout 함수에서이 간단한 계산을 더 잘 수행 할 수 있습니다.
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {
let totalCellWidth = CellWidth * CellCount
let totalSpacingWidth = CellSpacing * (CellCount - 1)
let leftInset = (collectionViewWidth - CGFloat(totalCellWidth + totalSpacingWidth)) / 2
let rightInset = leftInset
return UIEdgeInsets(top: 0, left: leftInset, bottom: 0, right: rightInset)
}
스위프트 4.2
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
let totalCellWidth = 80 * collectionView.numberOfItems(inSection: 0)
let totalSpacingWidth = 10 * (collectionView.numberOfItems(inSection: 0) - 1)
let leftInset = (collectionView.layer.frame.size.width - CGFloat(totalCellWidth + totalSpacingWidth)) / 2
let rightInset = leftInset
return UIEdgeInsets(top: 0, left: leftInset, bottom: 0, right: rightInset)
}
스위프트 3
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {
let totalCellWidth = 80 * collectionView.numberOfItems(inSection: 0)
let totalSpacingWidth = 10 * (collectionView.numberOfItems(inSection: 0) - 1)
let leftInset = (collectionView.layer.frame.size.width - CGFloat(totalCellWidth + totalSpacingWidth)) / 2
let rightInset = leftInset
return UIEdgeInsetsMake(0, leftInset, 0, rightInset)
}
프로토콜을 추가하는 것을 잊지 마십시오
UICollectionViewDelegateFlowLayout
Swift 4에 사용해보세요
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
let cellWidth : CGFloat = 165.0
let numberOfCells = floor(self.view.frame.size.width / cellWidth)
let edgeInsets = (self.view.frame.size.width - (numberOfCells * cellWidth)) / (numberOfCells + 1)
return UIEdgeInsetsMake(15, edgeInsets, 0, edgeInsets)
}
165.0 대신 cellWidth 추가
이를 위해 KTCenterFlowLayout 을 사용 하며 훌륭하게 작동합니다. UICollectionViewFlowLayout
원하는대로 중앙에있는 셀 의 사용자 지정 하위 클래스입니다 . (참고 : 이것은 일부 코드를 게시하여 해결하는 사소한 일이 아니기 때문에 GitHub 프로젝트에 연결하고 있습니다!)
Darshan Patel의 답변에 대한 객관적인 C 버전 :
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(nonnull UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
CGFloat totalCellWidth = kItemWidth * self.dataArray.count;
CGFloat totalSpacingWidth = kSpacing * (((float)self.dataArray.count - 1) < 0 ? 0 :self.dataArray.count - 1);
CGFloat leftInset = (self.bounds.size.width - (totalCellWidth + totalSpacingWidth)) / 2;
CGFloat rightInset = leftInset;
UIEdgeInsets sectionInset = UIEdgeInsetsMake(0, leftInset, 0, rightInset);
return sectionInset;
}
@Safad Funy의 답변을 약간 수정하면 Swift 및 iOS의 최신 버전에서 저에게 효과적이었습니다. 이 경우 셀 너비가 컬렉션 뷰 크기의 1/3이되기를 원했습니다.
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
let totalCellWidth = Int(collectionView.layer.frame.size.width) / 3 * collectionView.numberOfItems(inSection: 0)
let totalSpacingWidth = (collectionView.numberOfItems(inSection: 0) - 1)
let leftInset = (collectionView.layer.frame.size.width - CGFloat(totalCellWidth + totalSpacingWidth)) / 2
let rightInset = leftInset
return UIEdgeInsetsMake(0, leftInset, 0, rightInset)
}
이 확장 프로그램 (Swift 4)을 사용할 수 있습니다.
당신 collectionView
이 가지고 있다면 그것은 세포를 중심에 둘 수 있습니다 layout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize
.
모든 세포 크기에서 작동하며 다음과 같은 경우 완벽하게 작동합니다. scrollDirection = .horizontal
public extension UICollectionView {
func centerContentHorizontalyByInsetIfNeeded(minimumInset: UIEdgeInsets) {
guard let layout = collectionViewLayout as? UICollectionViewFlowLayout,
layout.scrollDirection == .horizontal else {
assertionFailure("\(#function): layout.scrollDirection != .horizontal")
return
}
if layout.collectionViewContentSize.width > frame.size.width {
contentInset = minimumInset
} else {
contentInset = UIEdgeInsets(top: minimumInset.top,
left: (frame.size.width - layout.collectionViewContentSize.width) / 2,
bottom: minimumInset.bottom,
right: 0)
}
}
}
final class Foo: UIViewController {
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
collectionView.centerContentHorizontalyByInsetIfNeeded(minimumInset: yourDefaultInset)
}
}
도움이되기를 바랍니다!
스위프트 4
extension ViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
let cellWidth: CGFloat = 170.0 // Your cell width
let numberOfCells = floor(view.frame.size.width / cellWidth)
let edgeInsets = (view.frame.size.width - (numberOfCells * cellWidth)) / (numberOfCells + 1)
return UIEdgeInsetsMake(0, edgeInsets, 0, edgeInsets)
}
}
패딩 만 추가하려는 사용자 ( top, left, bottom, right ) :
프로토콜 추가 UICollectionViewDelegateFlowLayout
이 예는 왼쪽과 오른쪽에 40으로 패딩을 표시합니다.
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsetsMake(0, 40, 0, 40)
}
SWIFT 4.2
private lazy var contentView: UICollectionView = {
let layoutView: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layoutView.scrollDirection = .horizontal
layoutView.minimumInteritemSpacing = 0
layoutView.minimumLineSpacing = 5
let collectionView: UICollectionView = UICollectionView(frame: .zero, collectionViewLayout: layoutView)
collectionView.dataSource = self
collectionView.delegate = self
collectionView.showsHorizontalScrollIndicator = false
collectionView.isPagingEnabled = true
collectionView.registerCell(Cell.self)
collectionView.backgroundColor = .clear
collectionView.translatesAutoresizingMaskIntoConstraints = false
return collectionView
}()
//
extension CustomCollectionView: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView.frame.width*4/5, height: collectionView.frame.height)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
let cellWidth : CGFloat = collectionView.frame.width*4/5
let numberOfCells = floor(collectionView.frame.width / cellWidth)
let edgeInsets = (collectionView.frame.width - (numberOfCells * cellWidth)) / (numberOfCells + 1)
return UIEdgeInsets(top: 0, left: edgeInsets, bottom: 0, right: edgeInsets)
}
}
Swift 4.2 (수평 및 수직). Pink Panther 코드의 작은 업그레이드이며 그에게 큰 감사를드립니다!
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout
let cellWidth: CGFloat = flowLayout.itemSize.width
let cellHieght: CGFloat = flowLayout.itemSize.height
let cellSpacing: CGFloat = flowLayout.minimumInteritemSpacing
let cellCount = CGFloat(collectionView.numberOfItems(inSection: section))
var collectionWidth = collectionView.frame.size.width
var collectionHeight = collectionView.frame.size.height
if #available(iOS 11.0, *) {
collectionWidth -= collectionView.safeAreaInsets.left + collectionView.safeAreaInsets.right
collectionHeight -= collectionView.safeAreaInsets.top + collectionView.safeAreaInsets.bottom
}
let totalWidth = cellWidth * cellCount + cellSpacing * (cellCount - 1)
let totalHieght = cellHieght * cellCount + cellSpacing * (cellCount - 1)
if totalWidth <= collectionWidth {
let edgeInsetWidth = (collectionWidth - totalWidth) / 2
print(edgeInsetWidth, edgeInsetWidth)
return UIEdgeInsets(top: 5, left: edgeInsetWidth, bottom: flowLayout.sectionInset.top, right: edgeInsetWidth)
} else {
let edgeInsetHieght = (collectionHeight - totalHieght) / 2
print(edgeInsetHieght, edgeInsetHieght)
return UIEdgeInsets(top: edgeInsetHieght, left: flowLayout.sectionInset.top, bottom: edgeInsetHieght, right: flowLayout.sectionInset.top)
}
}
클래스가 UICollectionViewDelegateFlowLayout 프로토콜을 준수하는지 확인하십시오.
내 솔루션을 시도해 볼 수 있습니다.
func refreshCollectionView(_ count: Int) {
let collectionViewHeight = collectionView.bounds.height
let collectionViewWidth = collectionView.bounds.width
let numberOfItemsThatCanInCollectionView = Int(collectionViewWidth / collectionViewHeight)
if numberOfItemsThatCanInCollectionView > count {
let totalCellWidth = collectionViewHeight * CGFloat(count)
let totalSpacingWidth: CGFloat = CGFloat(count) * (CGFloat(count) - 1)
// leftInset, rightInset are the global variables which I am passing to the below function
leftInset = (collectionViewWidth - CGFloat(totalCellWidth + totalSpacingWidth)) / 2;
rightInset = -leftInset
} else {
leftInset = 0.0
rightInset = -collectionViewHeight
}
collectionView.reloadData()
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsetsMake(0, leftInset, 0, rightInset)
}
허용 대답은 정답입니다하지만이 경우 totalCellWidth
미만 CollectionView
의 width
이에 대해,하지만 단지 경비에 당신은 다음과 같이 할 수 있습니다.
if (leftInset > 0) {
return UIEdgeInsetsMake(0, leftInset, 0, rightInset)
} else {
return UIEdgeInsetsMake(0, 10, 0, 10)
}
이 코드는 수정없이 Swift 4.0 에서도 수평 컬렉션 뷰를 중앙에 배치해야합니다 .
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout
let cellWidth: CGFloat = flowLayout.itemSize.width
let cellSpacing: CGFloat = flowLayout.minimumInteritemSpacing
let cellCount = CGFloat(collectionView.numberOfItems(inSection: section))
var collectionWidth = collectionView.frame.size.width
if #available(iOS 11.0, *) {
collectionWidth -= collectionView.safeAreaInsets.left + collectionView.safeAreaInsets.right
}
let totalWidth = cellWidth * cellCount + cellSpacing * (cellCount - 1)
if totalWidth <= collectionWidth {
let edgeInset = (collectionWidth - totalWidth) / 2
return UIEdgeInsetsMake(flowLayout.sectionInset.top, edgeInset, flowLayout.sectionInset.bottom, edgeInset)
} else {
return flowLayout.sectionInset
}
}
클래스가 UICollectionViewDelegateFlowLayout
프로토콜을 준수하는지 확인하십시오.
I ended up taking a completely different approach here, which I believe is worth mentioning.
I set a constraint on my collection view to be horizontally aligned in the center. Then I set another constraint that specifies the width. I created an outlet for the width constraint inside of my viewController that holds the collection view. Then, when my data source is changed and I am updating the collection view, I take the count of the cells and do a (very similar) calculation to reset the width.
let newWidth = (items.count * cellWidth) + (items.count * cellSpacing)
Then I set the constraint outlet's .constant
value to the calculation result and autolayout does the rest.
This may conflict with the `UICollectionViewDelegateFlowLayout, but this worked perfectly for me to create a left-justified collection view. Without a delegate, it only seems to work when the cells filled up the majority of the view.
General solution for flowlayout that centers the pages if they are less than the width and aligns left if there are more
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(nonnull UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
// Centering if there are fever pages
CGSize itemSize = [(UICollectionViewFlowLayout *)collectionViewLayout itemSize];
CGFloat spacing = [(UICollectionViewFlowLayout *)collectionViewLayout minimumLineSpacing];
NSInteger count = [self collectionView:self numberOfItemsInSection:section];
CGFloat totalCellWidth = itemSize.width * count;
CGFloat totalSpacingWidth = spacing * ((count - 1) < 0 ? 0 : count - 1);
CGFloat leftInset = (self.bounds.size.width - (totalCellWidth + totalSpacingWidth)) / 2;
if (leftInset < 0) {
UIEdgeInsets inset = [(UICollectionViewFlowLayout *)collectionViewLayout sectionInset];
return inset;
}
CGFloat rightInset = leftInset;
UIEdgeInsets sectionInset = UIEdgeInsetsMake(0, leftInset, 0, rightInset);
return sectionInset;
}
Swift version (converted from ObjC)
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
// Centering if there are fever pages
let itemSize: CGSize? = (collectionViewLayout as? UICollectionViewFlowLayout)?.itemSize
let spacing: CGFloat? = (collectionViewLayout as? UICollectionViewFlowLayout)?.minimumLineSpacing
let count: Int = self.collectionView(self, numberOfItemsInSection: section)
let totalCellWidth = (itemSize?.width ?? 0.0) * CGFloat(count)
let totalSpacingWidth = (spacing ?? 0.0) * CGFloat(((count - 1) < 0 ? 0 : count - 1))
let leftInset: CGFloat = (bounds.size.width - (totalCellWidth + totalSpacingWidth)) / 2
if leftInset < 0 {
let inset: UIEdgeInsets? = (collectionViewLayout as? UICollectionViewFlowLayout)?.sectionInset
return inset!
}
let rightInset: CGFloat = leftInset
let sectionInset = UIEdgeInsets(top: 0, left: Float(leftInset), bottom: 0, right: Float(rightInset))
return sectionInset
}
i have tried many solutions from here, but at the end of the day the simpliest solution works best
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView.frame.width, height: YOUR HEIGHT)
}
p.s. with no insets in interface builder
I think you need to centre cell , so instead of using collectionView I'ld like UITableView will be of great use. Just use a UIViewController and place two UIViews in front and back and place a UITableView
in middle Hope this helps
참고 URL : https://stackoverflow.com/questions/34267662/how-to-center-horizontally-uicollectionview-cells
'Programing' 카테고리의 다른 글
프래그먼트간에 값을 전달하는 방법 (0) | 2020.08.15 |
---|---|
목록에서 중복 식별 (0) | 2020.08.15 |
간단한 설명 PHP OOP 대 절차? (0) | 2020.08.15 |
index.php가 기본적으로로드되지 않음 (0) | 2020.08.15 |
csv에 c # 데이터 테이블 (0) | 2020.08.15 |