Может быть, этот учебник поможет: https://www.raywenderlich.com/1702-uicollectionview-custom-layout-tutorial-a-spinning-wheel
Ваша первая проблема заключается в том, что вы поворачиваете представление всей коллекции.Думайте об этом, как будто вы помещаете эти круги на лист бумаги, а затем вращаете этот лист бумаги.Вы не хотите вращать представление всей коллекции.Возможно, вы не захотите вращать окружности вокруг точки, потому что тогда вращение влияет на изображение и текст в окружности.Вы просто хотите изменить положение круга в круговом движении.
Если UICollectionView не работает, вы можете отказаться от него и использовать обычные UIViews и расположить их по кругу (эти функции должны помочь: https://gist.github.com/akhilcb/8d03f1f88f87e996aec24748bdf0ce78). После того, как у вас есть представления, расположенные по кругу, вам просто нужно обновить угол для каждого вида, когда пользователь перетаскивает палец. Сохраните предыдущий угол на виде и добавьте к нему все, что вы хотите, когда пользователь перетаскиваетНемного проб и ошибок, и это не должно быть слишком плохо.
Обновление
Основная причина использования представлений коллекции - если у вас многоэлементов, и вам нужно повторно использовать представления в виде списка. Если вам не нужно повторно использовать представления, то использование UICollectionView может быть затруднительно для понимания, настройки и изменения вещей. Вот простой пример использования обычных представлений, которые вращаются вокруг кругаиспользуя вход UIPanGestureRecognizer.
Пример :
import UIKit
class ViewController: UIViewController {
var rotatingViews = [RotatingView]()
let numberOfViews = 8
var circle = Circle(center: CGPoint(x: 200, y: 200), radius: 100)
var prevLocation = CGPoint.zero
override func viewDidLoad() {
super.viewDidLoad()
for i in 0...numberOfViews {
let angleBetweenViews = (2 * Double.pi) / Double(numberOfViews)
let viewOnCircle = RotatingView(circle: circle, angle: CGFloat(Double(i) * angleBetweenViews))
rotatingViews.append(viewOnCircle)
view.addSubview(viewOnCircle)
}
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(didPan(panGesture:)))
view.addGestureRecognizer(panGesture)
}
@objc func didPan(panGesture: UIPanGestureRecognizer){
switch panGesture.state {
case .began:
prevLocation = panGesture.location(in: view)
case .changed, .ended:
let nextLocation = panGesture.location(in: view)
let angle = circle.angleBetween(firstPoint: prevLocation, secondPoint: nextLocation)
rotatingViews.forEach({ $0.updatePosition(angle: angle)})
prevLocation = nextLocation
default: break
}
}
}
struct Circle {
let center: CGPoint
let radius: CGFloat
func pointOnCircle(angle: CGFloat) -> CGPoint {
let x = center.x + radius * cos(angle)
let y = center.y + radius * sin(angle)
return CGPoint(x: x, y: y)
}
func angleBetween(firstPoint: CGPoint, secondPoint: CGPoint) -> CGFloat {
let firstAngle = atan2(firstPoint.y - center.y, firstPoint.x - center.x)
let secondAnlge = atan2(secondPoint.y - center.y, secondPoint.x - center.x)
let angleDiff = (firstAngle - secondAnlge) * -1
return angleDiff
}
}
class RotatingView: UIView {
var currentAngle: CGFloat
let circle: Circle
init(circle: Circle, angle: CGFloat) {
self.currentAngle = angle
self.circle = circle
super.init(frame: CGRect(x: 0, y: 0, width: 60, height: 60))
center = circle.pointOnCircle(angle: currentAngle)
backgroundColor = .blue
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func updatePosition(angle: CGFloat) {
currentAngle += angle
center = circle.pointOnCircle(angle: currentAngle)
}
}
Круг - это структура that просто держит центр всех видов, насколько далеко вы хотите их (радиус), и вспомогательные функции для вычисления углов, найденных в ссылке GitHub выше.
Вращающиеся виды - это виды, вращающиеся вокруг середины.