如何将对象放置在中心图像周围的数组中? [英] How do I place the objects in the array around the center image?

查看:71
本文介绍了如何将对象放置在中心图像周围的数组中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一系列按钮,当我将它们附加到视图时,我希望将它放置在中心的图像视图周围。根据数组中有多少个对象,我希望它们围绕整个圆均匀分布。以下是我的尝试。我做错了什么,应该如何解决?驼鹿后面有一个以上的按钮。

I have an array of buttons and when I append them to a view I want the to be positioned around a image view which is in the center. Based on how many objects there are in the array, I want them to be evenly spaced around the whole circle. Below is my attempt to do so. What am I doing wrong and how should I fix it? There is more than one button behind the moose.

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)")


    }


}


推荐答案

我将如何做到这一点:

创建一个扩展到UIView以获得对角线和半径。这些都很方便,因为即使行星不是正方形,我们也希望我们的卫星具有可预测的位置。

Create an extension to UIView to get the diagonal and radius. These are handy because we want our "satellites" to have predictable placing even when the "planet" isn't square.

extension UIView {

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

    var radius : CGFloat {
        return diagonal / 2
    }
}






这将返回一个点基于与原点的角度和距离。
它使用了可怕的三角函数。


This will return a point based on an angle and a distance from an origin. It uses dreadful trigonometry.

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))
}






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


Now the real function. Generate a bunch of points in a circle pattern. I used a running sum for the angle instead of multiplying each time by the index. This just returns the centre points for the views.

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
}






现在你可以创建一个简单的获取视图,边距和卫星视图数组的函数。它将设置它们的中心并将它们添加到我们以前输入的视图的超视图中。有意义的是不要将它们添加到视图本身,因为它们可能不会放在它里面。


Now you can create a simple function that takes a view, a margin and an array of "satellite" views. It will set their centre and add them to the superview of the view we used to input. It makes sense not to add them to the view itself since they might not be placed inside it.

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 }
}






注意除了这些函数中的中心计算外我什么也没做。设计它们的另一个功能。这使得维护和调试变得非常容易。


Notice how I did nothing except for the centre calculations in these functions. Styling them goes in another function. This makes it super easy to maintain and debug.

我甚至可以让最后一个函数返回带有更新帧的子视图,然后再添加它们。

I might even let the last function just return the subviews with updated frames and add them later.

或负利润率:)

Gist

这篇关于如何将对象放置在中心图像周围的数组中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆