- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试为圆形的自定义单元格实现 UICollectionView
。现在默认情况下,圆圈的对齐方式与普通方形单元格相同:顶部圆圈和底部圆圈位于同一垂直线上。我怎样才能改变对齐方式:顶部圆和它下面的两个圆形成一个等边三角形(顶部圆和底部圆的位置按半径长度移动)?如下:
from OOO
OOO
OOO
to O O O
O O O (no spacing among the circles)
O O O
最佳答案
基本思想是创建一个自定义的 UICollectionViewLayout
来实现:
collectionViewContentSize
,即 Collection View 的完整可滚动 contentSize
的大小;
layoutAttributesForItem(at indexPath:)
,即特定的关键属性(即 center
和 size
)是什么细胞;和
layoutAttributesForElements(in rect:)
,即属于这个特定 rect
的单元格的关键属性是什么......这将用于识别在任何给定时间点哪些单元格是可见的,以及这些单元格的属性;这基本上是前一个方法中单元格属性的数组,过滤后仅包含 rect
中的单元格。
因此,在 Swift 3 中你可以这样做:
class AlternatingGridLayout: UICollectionViewLayout {
private var itemSize: CGSize!
private var numberOfItems: Int!
private var itemsPerRow: Int!
private var rows: Int!
private var circleViewCenterOffset: CGPoint!
private var radiusOfCircleViews: CGFloat!
private var insets: UIEdgeInsets!
override func prepare() {
super.prepare()
guard let collectionView = collectionView else { return }
radiusOfCircleViews = CGFloat(40.0)
itemSize = CGSize(width: radiusOfCircleViews * 2, height: radiusOfCircleViews * 2)
circleViewCenterOffset = CGPoint(x: 2 * radiusOfCircleViews * cos(.pi / 3),
y: 2 * radiusOfCircleViews * sin(.pi / 3))
numberOfItems = collectionView.numberOfItems(inSection: 0)
itemsPerRow = Int(floor((collectionView.bounds.width - radiusOfCircleViews) / CGFloat(2 * radiusOfCircleViews)) + 0.5)
rows = (numberOfItems - 1) / itemsPerRow + 1
let excess = collectionView.bounds.width - (CGFloat(itemsPerRow) * radiusOfCircleViews * 2 + circleViewCenterOffset.x)
insets = UIEdgeInsets(top: 10, left: excess / 2, bottom: 10, right: excess / 2)
}
override var collectionViewContentSize: CGSize {
return CGSize(width: collectionView!.bounds.width,
height: 2 * radiusOfCircleViews + CGFloat(rows - 1) * circleViewCenterOffset.y + insets.top + insets.bottom)
}
override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
attributes.center = centerForItem(at: indexPath)
attributes.size = itemSize
return attributes
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
return (0 ..< collectionView!.numberOfItems(inSection: 0)).map { IndexPath(item: $0, section: 0) }
.filter { rect.intersects(rectForItem(at: $0)) }
.compactMap { self.layoutAttributesForItem(at: $0) } // `flatMap` in Xcode versions before 9.3
}
private func centerForItem(at indexPath: IndexPath) -> CGPoint {
let row = indexPath.item / itemsPerRow
let col = indexPath.item - row * itemsPerRow
var x: CGFloat = radiusOfCircleViews + CGFloat(col) * (radiusOfCircleViews * 2)
let y: CGFloat = radiusOfCircleViews + CGFloat(row) * (circleViewCenterOffset.y)
if row % 2 == 0 {
x += circleViewCenterOffset.x
}
return CGPoint(x: x + insets.left, y: y + insets.top)
}
private func rectForItem(at indexPath: IndexPath) -> CGRect {
let center = centerForItem(at: indexPath)
return CGRect(x: center.x - radiusOfCircleViews, y: center.y - radiusOfCircleViews, width: radiusOfCircleViews * 2, height: radiusOfCircleViews * 2)
}
}
产生:
很明显,您可以根据需要自定义它,但它说明了基本思想。
在下面我的原始回答中,我假设您希望看到这些单元格呈圆形,如 WWDC 2012 视频 Advanced Collection Views and Building Custom Layouts 中所示。 (视频大约 40 多分钟)。见下文。
例如,在 Swift 3 中:
class CircleLayout: UICollectionViewLayout {
private var center: CGPoint!
private var itemSize: CGSize!
private var radius: CGFloat!
private var numberOfItems: Int!
override func prepare() {
super.prepare()
guard let collectionView = collectionView else { return }
center = CGPoint(x: collectionView.bounds.midX, y: collectionView.bounds.midY)
let shortestAxisLength = min(collectionView.bounds.width, collectionView.bounds.height)
itemSize = CGSize(width: shortestAxisLength * 0.1, height: shortestAxisLength * 0.1)
radius = shortestAxisLength * 0.4
numberOfItems = collectionView.numberOfItems(inSection: 0)
}
override var collectionViewContentSize: CGSize {
return collectionView!.bounds.size
}
override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
let angle = 2 * .pi * CGFloat(indexPath.item) / CGFloat(numberOfItems)
attributes.center = CGPoint(x: center.x + radius * cos(angle), y: center.y + radius * sin(angle))
attributes.size = itemSize
return attributes
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
return (0 ..< collectionView!.numberOfItems(inSection: 0))
.compactMap { item -> UICollectionViewLayoutAttributes? in // `flatMap` in Xcode versions prior to 9.3
self.layoutAttributesForItem(at: IndexPath(item: item, section: 0))
}
}
}
然后您可以简单地设置collectionViewLayout
,然后实现标准的UICollectionViewDataSource
方法。
class ViewController: UICollectionViewController {
var numberOfCells = 10
override func viewDidLoad() {
super.viewDidLoad()
collectionView?.collectionViewLayout = CircleLayout()
// just for giggles and grins, let's show the insertion of a cell
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
self.collectionView?.performBatchUpdates({
self.numberOfCells += 1
self.collectionView?.insertItems(at: [IndexPath(item: 0, section: 0)])
}, completion: nil)
}
}
}
// MARK: UICollectionViewDataSource
extension ViewController {
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return numberOfCells
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CircleCell", for: indexPath)
return cell
}
}
产生:
参见 https://github.com/robertmryan/CircularCollectionView sample 。
请注意,您提到您想要“圆圈之间没有间距”,因此只需相应地调整 radius
和/或 itemSize
以获得您想要的布局。
关于iOS UICollectionView : Cells with circular view in alternating grid alignment,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41837170/
我试图找出在表格单元格上放置对齐属性与使用 text-align css 属性之间的区别。下面的代码显示了 IE 与其他浏览器中的不同结果。在 IE 中,对齐最终会对齐每个子子项,因此文本“test”
我正在 summernote HTML 编辑器上做一些 POC,我正在使用自定义工具栏,但我不知道如何添加对齐(左对齐、居中对齐、右对齐)工具栏,所以有人可以帮助我实现这一目标。 还有人可以帮我找到更
以下是从节对齐转换为文件对齐的步骤: 找到数据的 RVA 从 RVA 导出引用的数据所属的部分。这是微不足道的,因为部分不重叠。文件头中提供了各个部分的起始地址。 找出RVA和section的起始地址
align-self 在以下代码中, align-self 与 flex-wrap: nowrap 一起使用。 flex-container { display: flex; flex-wra
这是CSS: .divPhoto { border:1px solid #999; width:140px; height:140px; border-radius:3
我正在为 Windows Phone 8 开发,我已经设计了我的应用程序,我注意到有一个“分配网格”代码,默认情况下可以在新项目中取消注释。 看看下面的文件中的描述: --> 这是取
我们有浏览器前缀或黑客 (for Google and Safari) text-align: -webkit-right; (for Firefox) text-align:
最近我观察到,在 Clang 9.0 上 alignof 和 __alignof 为 unsigned long long 返回不同的值,并且在 https://reviews.llvm.org/D5
我已经一年多没有为 Android 开发了,我对它有点生疏了。我正在尝试设置一个有点简单的 UI:屏幕底部的底部栏和它上面的 fragment (但没有填充整个高度)。像这样: 我认为这会很简单,但经
你好,我正在尝试找到一种使用“讨厌的”align=center 技巧的方法.. 嗯,当我查看一些代码时,我注意到两个非常相似的片段呈现的并不相同。我找不到让他们表现相同的方法。这包括用 div 替换顶
抱歉这个愚蠢的问题。我只想知道我们什么时候讨论内存中的数据应该如何对齐之类的。这个主题是叫“内存对齐”还是“数据对齐”,还是我可以随便叫它什么? 最佳答案 在编程的上下文中,它被称为 data str
所以我只是想制作一个简单的导航栏,并且我刚开始使用 flexbox。为什么 align-content 在这里不起作用?我可以让 justify-content 工作,但我就是无法垂直对齐。这是代码。
我从这个 SO 开始答案,我试图使用提供的纯 flexbox 答案。 然而,当我尝试这个时,我看到了以下结果。 我不确定为什么 Button 4 在行中出现的位置高于其余元素。 HTML
我已通读 A complete guide to Grid ,但仍然对两组容器属性之间的差异感到困惑,即“justify/align-items”与“justify/align-content”。 我
我有一个simple plunker here. .container { display:flex; flex-flow: row nowrap; justify-content: sp
从 http://code.google.com/p/berkeleyaligner/ 下载主干代码后,我将该项目添加到 Eclipse 上的构建路径中。然后,使用下面的代码,我可以提取从 sourc
这个问题在这里已经有了答案: What's the difference between align-content and align-items? (15 个答案) 关闭 7 年前。 我发现 C
[short text][image1][image2]____________________________________ [this is a reallyyyyyyy............
我有一个很小的菜单列表,当鼠标靠近时它应该会增长。在其原始状态下,菜单是右对齐的,悬停时每第二个元素向右移动并左对齐以为增加的高度腾出空间(参见 JSFiddle )。 ul { font-siz
这个问题在这里已经有了答案: Align child elements of different blocks (3 个答案) 关闭 3 年前。
我是一名优秀的程序员,十分优秀!