我正在构建一个要在其中显示个人资料的应用程序。人们以六角形蜂巢样式“靠近你”的图片。
完整的蜂箱应该可以拖动,例如Google地图。
我的问题是,是否可以仅使用UIKit来完成此操作,或者一起使用UIKit和SpriteKit会更容易。
我希望有人能指出正确的方向,或者对如何实现有一些想法。谢谢您的时间!
更新: 只是为了让我的问题更加清楚。
This is how my view looks like atm
And this is what I want to achieve
在第一张图像中,我只是将UIImage中心的X和Y位置设置了。
我想创建某种函数,该函数可以获取不同profilePics的数组,然后以这种模式进行输出。
答案 0 :(得分:1)
UIKit
就可以完成这项工作:例如,您应该尝试在CALayer
上使用UIImageView
设置掩码。
可拖动行为可以通过在UIScrollView
中添加并排列所有图像子视图来实现,也可以通过具有自定义流程的UICollectionView
来实现,但是可能很难设置上。
对于六边形视图,您会在这里找到一个有趣的示例,可以根据自己的需要进行调整:http://sapandiwakar.in/make-hexagonal-view-on-ios/
这是Swift 4.2中Sapan Diwakar解决方案的改编,并使用扩展名:
extension UIBezierPath {
convenience init(roundedPolygonPathInRect rect: CGRect, lineWidth: CGFloat, sides: NSInteger, cornerRadius: CGFloat = 0, rotationOffset: CGFloat = 0) {
self.init()
let theta: CGFloat = 2.0 * CGFloat.pi / CGFloat(sides) // How much to turn at every corner
let width = min(rect.size.width, rect.size.height) // Width of the square
let center = CGPoint(x: rect.origin.x + width / 2.0, y: rect.origin.y + width / 2.0)
// Radius of the circle that encircles the polygon
// Notice that the radius is adjusted for the corners, that way the largest outer
// dimension of the resulting shape is always exactly the width - linewidth
let radius = (width - lineWidth + cornerRadius - (cos(theta) * cornerRadius)) / 2.0
// Start drawing at a point, which by default is at the right hand edge
// but can be offset
var angle = CGFloat(rotationOffset)
let corner = CGPoint(x: center.x + (radius - cornerRadius) * cos(angle), y: center.y + (radius - cornerRadius) * sin(angle))
move(to: CGPoint(x: corner.x + cornerRadius * cos(angle + theta), y: corner.y + cornerRadius * sin(angle + theta)))
for _ in 0 ..< sides {
angle += theta
let corner = CGPoint(x: center.x + (radius - cornerRadius) * cos(angle), y: center.y + (radius - cornerRadius) * sin(angle))
let tip = CGPoint(x: center.x + radius * cos(angle), y: center.y + radius * sin(angle))
let start = CGPoint(x: corner.x + cornerRadius * cos(angle - theta), y: corner.y + cornerRadius * sin(angle - theta))
let end = CGPoint(x: corner.x + cornerRadius * cos(angle + theta), y: corner.y + cornerRadius * sin(angle + theta))
addLine(to: start)
addQuadCurve(to: end, controlPoint: tip)
}
close()
}
}
extension UIImageView {
func setupHexagonMask(lineWidth: CGFloat, color: UIColor, cornerRadius: CGFloat) {
let path = UIBezierPath(roundedPolygonPathInRect: bounds, lineWidth: lineWidth, sides: 6, cornerRadius: cornerRadius, rotationOffset: CGFloat.pi / 2.0).cgPath
let mask = CAShapeLayer()
mask.path = path
mask.lineWidth = lineWidth
mask.strokeColor = UIColor.clear.cgColor
mask.fillColor = UIColor.white.cgColor
layer.mask = mask
let border = CAShapeLayer()
border.path = path
border.lineWidth = lineWidth
border.strokeColor = color.cgColor
border.fillColor = UIColor.clear.cgColor
layer.addSublayer(border)
}
}
然后您可以像这样使用它:
let image = UIImageView(frame: CGRect(x: 30, y: 30, width: 300, height: 300))
image.contentMode = .scaleAspectFill
image.image = UIImage(named: "lenna.png")
image.setupHexagonMask(lineWidth: 5.0, color: .white, cornerRadius: 20.0)
view.addSubview(image)
编辑:正如我告诉您的,最简单的方法是使用UIScrollView
来显示地图,并通过简单的数学运算就可以按所需的方式显示六边形。>
这里是一个小示例,您必须调整以适应您的要求。例如,您应该格外小心性能。此示例不应按原样使用,如果您有很多图像,则应即时加载它们,并在不显示时将其删除。您甚至可以考虑使用背景渲染,如果帧/帧的帧数过多...
假设view
是UIScrollView
:
let hexaDiameter : CGFloat = 150
let hexaWidth = hexaDiameter * sqrt(3) * 0.5
let hexaWidthDelta = (hexaDiameter - hexaWidth) * 0.5
let hexaHeightDelta = hexaDiameter * 0.25
let spacing : CGFloat = 5
let rows = 10
let firstRowColumns = 6
view.contentSize = CGSize(width: spacing + CGFloat(firstRowColumns) * (hexaWidth + spacing),
height: spacing + CGFloat(rows) * (hexaDiameter - hexaHeightDelta + spacing) + hexaHeightDelta)
for y in 0..<rows {
let cellsInRow = y % 2 == 0 ? firstRowColumns : firstRowColumns - 1
let rowXDelta = y % 2 == 0 ? 0.0 : (hexaWidth + spacing) * 0.5
for x in 0..<cellsInRow {
let image = UIImageView(frame: CGRect(x: rowXDelta + CGFloat(x) * (hexaWidth + spacing) + spacing - hexaWidthDelta,
y: CGFloat(y) * (hexaDiameter - hexaHeightDelta + spacing) + spacing,
width: hexaDiameter,
height: hexaDiameter))
image.contentMode = .scaleAspectFill
image.image = UIImage(named: "lenna.png")
image.setupHexagonMask(lineWidth: 5.0, color: .white, cornerRadius: 10.0)
view.addSubview(image)
}
}