如何将对象放置在中心图像周围的数组中?

我有一个buttonarrays,当我把它们追加到一个视图,我想要定位在中心的图像视图。 根据arrays中有多less物体,我希望它们在整个圆周上均匀分布。 以下是我的尝试。 我做错了什么,我该如何解决? 驼鹿后面有不止一个button。

在这里输入图像说明

var userbutton = [UIButton]() var upimage = [UIImage]() var locationpic = [AnyObject]() func locationsSet(){ for (index, users) in upimage.enumerate() { let userbutton = UIButton() userbutton.addTarget(self, action: "buttonAction:", forControlEvents: .TouchUpInside) userbutton.frame = CGRectMake(100, 100, 50, 50) userbutton.layer.cornerRadius = userbutton.frame.size.width/2 userbutton.clipsToBounds = true userbutton.setImage(users, forState: .Normal) let radians = CGFloat(M_PI) * 2.0 / CGFloat(upimage.count) * CGFloat(index) let centerx = self.view.bounds.width / 2.0 let radius = currentuserpic.frame.size.width / 2.0 let centery = self.view.bounds.height / 2.0 let pointx = centerx + cos(radians) * (radius + 40) let pointy = (centery) + (sin(radians)) * (radius + 40) userbutton.center.x = pointx userbutton.center.y = pointy self.userbutton.append(userbutton) self.view.addSubview(userbutton) print("x\(pointx)") print("y\(pointy)") } } 

我将如何做到这一点:

创build一个扩展到UIView获取对angular线和半径。 这些都很方便,因为我们希望我们的“卫星”即使在“星球”不是正方形的时候也有可预测的位置。

 extension UIView { var diagonal : CGFloat { return sqrt(pow(self.frame.width, 2) + pow(self.frame.height, 2)) } var radius : CGFloat { return diagonal / 2 } } 

这将返回一个基于angular度和距离原点的距离。 它使用可怕的三angular。

 func getPoint(fromPoint point: CGPoint, atDistance distance: CGFloat, withAngleRadians angle:CGFloat) -> CGPoint { let x = point.x let y = point.y let dx = (distance * cos(angle)) let dy = (distance * sin(angle)) return CGPoint(x: (dx + x), y: (dy + y)) } 

现在是真正的function。 以圆圈图案生成一堆点。 我使用了angular度的运行总和,而不是每次乘以索引。 这只是返回视图的中心点。

 func encirclePoint(point : CGPoint, distance:CGFloat, inParts parts: Int) -> [CGPoint] { let angle = 2 * CGFloat(M_PI) / CGFloat(parts) // critical part, you need radians for trigonometry var runningAngle : CGFloat = -(CGFloat(M_PI) / 2) // start at the top var points : [CGPoint] = [] for _ in 0..<parts { let circlePoint = getPoint(fromPoint: point, atDistance: distance, withAngleRadians: runningAngle) points.append(circlePoint) runningAngle += angle } return points } 

现在您可以创build一个简单的函数,该函数需要一个视图,一个边界和一系列“卫星”视图。 它将设置它们的中心并将它们添加到我们用来input的视图的超视图。 这样做是有道理的,不要把它们添加到视图本身,因为它们可能不会放在视图中。

 func encircleView(view : UIView, withSubViews subViews : [UIView], withMargin margin : CGFloat) { guard !(subViews.isEmpty) else { // if there are no subviews : abort return } let distance = view.radius + margin let points = encirclePoint(view.center, distance: distance, inParts: subViews.count) guard subViews.count == points.count, let uberView = view.superview else { // if the count is not the same or there is no superview: abort return } for (point, subView) in zip(points, subViews) { subView.center = point } } 

请注意,除了这些函数中的中心计算以外,我什么也没做。 造型他们在另一个function。 这使得维护和debugging变得非常容易。

我甚至可能会让最后一个函数返回带更新框架的子视图,并在稍后添加它们。


在这里输入图像说明


或者负的余地:)

在这里输入图像说明

要旨

一个完整的圆是2 * pi弧度。 您需要将其除以您所拥有的物品数量,然后将其乘以当前正在处理的物品的索引。 使用trig来find圆上的位置:

 for (index, users) in upimage.enumerate() { let radians = CGFloat(M_PI) * 2.0 / CGFloat(upimage.count) * CGFloat(index) ...... let centerx = self.view.bounds.width / 2.0 let radius = currentuserpic.frame.size.width / 2.0 let centery = self.view.bounds.height / 2.0 let pointx = centerx + cos(radians) * radius let pointy = centery + sin(radians) * radius ...... }