简体   繁体   中英

how do I rotate a group of buttons programmatically in Swift?

I am trying to arrange numbered buttons programmatically in a circle. NSLayoutConstraint anchors the view while a subClass of UIView creates the circle of buttons. The frame rotates about the centre but buttons rotate inconsistently. Text orientation is the same on all but one rotation.

  for example

在此输入图像描述

My Swift code for arranging buttons improves on an earlier effort in Objective C . I have also followed up a few helpful suggestions for rotating a view about the screen centre including this one .

I'd be grateful if anyone can show me how to improve my code so the UI is consistent for every screen size and orientation.

Here is the Viewcontroller

import UIKit

class ViewController: UIViewController {

var circle: CircleView?

override func viewDidLoad() {
    super.viewDidLoad()

    let circle = CircleView()
    circle.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(circle)

    let horizontalConstraint    = circle.centerXAnchor.constraint(equalTo: view.centerXAnchor)
    let verticalConstraint      = circle.centerYAnchor.constraint(equalTo: view.centerYAnchor)
    NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint])
    }
}

... and the subclass of UIView

import UIKit

class CircleView: UIView {

// MARK: Initialization

let points: Int             = 10    // 80 25 16 10 5
let dotSize: CGFloat        = 60    // 12 35 50 60 100
let radius: CGFloat         = 48    // 72 70 64 48 45

var arcPoint                = CGFloat(M_PI * -0.5)  // clockwise from 12+ (not 3+)!

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

override init(frame: CGRect) {
    super.init(frame: frame)

    drawUberCircle()
    drawBoundaryCircles()
}

... the second last function draws the coloured circular background

    func drawUberCircle() {

    // Create a CAShapeLayer

    let shapeLayer = CAShapeLayer()

    // give Bezier path layer properties
    shapeLayer.path = createBezierPath().cgPath

    shapeLayer.strokeColor      = UIColor.cyan.cgColor
    shapeLayer.fillColor        = UIColor.cyan.cgColor
    shapeLayer.lineWidth        = 1.0        
    self.layer.addSublayer(shapeLayer)
}
    func createBezierPath() -> UIBezierPath {

    let path  = UIBezierPath(arcCenter: CGPoint(x: 0, y: 0),
                                radius: radius * 2,
                            startAngle: CGFloat(M_PI * -0.5),
                              endAngle: CGFloat(M_PI * 1.5),
                             clockwise: true)
    return path
}

... while the last function draws buttons in a circular arc

    func drawBoundaryCircles() {

    for index in 1...points {
    let point: CGPoint  = makeBoundaryPoint()
    drawButton(point: point, index: index)
    }
}


func makeBoundaryPoint() -> (CGPoint) {
    arcPoint += arcAngle()
    print(arcPoint)
    let point   = CGPoint(x: 0 + (radius * 2 * cos(arcPoint)), y: 0 + (radius * 2 * sin(arcPoint)))
    return (point)
}


func arcAngle() -> CGFloat {
    return CGFloat(2.0 * M_PI) / CGFloat(points)
}


func drawButton(point: CGPoint, index: Int) {
     let myButton = UIButton(type: .custom) as UIButton
     myButton.frame              = CGRect(x: point.x - (dotSize/2), y: point.y - (dotSize/2), width: dotSize, height: dotSize)
     myButton.backgroundColor    = UIColor.white
     myButton.layer.cornerRadius = dotSize / 2
     myButton.layer.borderWidth  = 1
     myButton.layer.borderColor  = UIColor.black.cgColor
     myButton.clipsToBounds      = true
     myButton.titleLabel!.font   = UIFont(name: "HelveticaNeue-Thin", size: dotSize/2)
     myButton.setTitleColor(UIColor.red, for: .normal)
     myButton.setTitle(String(index), for: .normal)
     myButton.tag                = index;
     myButton.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
     addSubview(myButton)
}


 func buttonAction(myButton: UIButton) {
    let sender:UIButton = myButton
    print("Button \(sender.tag) was tapped")
    }
}

EDIT

Rotation 4 ( shown above ) appears when the iPhone is held upside down and is irrelevant for reasons explained in the accepted answer ( see below ). This becomes more obvious if the code runs on an actual device rather than the simulator.

A SOLUTION WITH WORKING BUTTONS

For a solution with buttons that remain on-centre and work, refer to this

For an iphone, this behavior is correct. You usually do not support rotation for upside down because it makes it confusing if the user has to answer a call; its in the apple HIG guidelines. Look at your project settings on the general tab under device orientation. By default Upside Down is disabled. Check it if you want to support Upside Down rotation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM