ios - 如何将对象放置在中心图像周围的阵列中?

标签 ios swift layout

我有一个按钮数组,当我将它们附加到一个 View 时,我希望将它们定位在位于中心的 ImageView 周围。根据数组中有多少个对象,我希望它们均匀分布在整个圆圈周围。以下是我这样做的尝试。我做错了什么,我应该如何解决?驼鹿背后有不止一个按钮。

enter image description here

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 的扩展以获取对角线和半径。这些很方便,因为我们希望我们的“卫星”即使在“行星”不是正方形时也能有可预测的位置。

extension UIView {

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

    var radius : CGFloat {
        return diagonal / 2
    }
}

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

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

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

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
}

现在您可以创建一个简单的函数,它接受一个 View 、一个边距和一个“卫星” View 数组。它将设置它们的中心并将它们添加到我们用来输入的 View 的父 View 中。不将它们添加到 View 本身是有意义的,因为它们可能不会放置在其中。

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

请注意,除了这些函数中的中心计算外,我什么也没做。对它们进行样式化是另一个功能。这使得它非常容易维护和调试。

我什至可以让最后一个函数只返回带有更新帧的 subview ,然后再添加它们。


enter image description here


或者负边距 :)

enter image description here

Gist

关于ios - 如何将对象放置在中心图像周围的阵列中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34246386/

相关文章:

ios - 在 UIAlertView 上添加 UISlider

ios - iOS 8.3 和 8.4 中的第二屏显示旋转 90 度

iphone - 在另一个 View Controller 中调用方法导致循环

ios - Swift - Locksmith loadDataForUserAccount 有时会失败?

swift - 获取超过 24 小时的 iCloudKit 记录

java - 带 Java 的系统托盘

ios - 删除项目 RxSwift MVVM 模式

ios - 单击按钮增加和减少值

android - 此 TableLayout 布局或其 LinearLayout 父级无用如何解决此警告

java - 小程序未显示完整