简体   繁体   English

如何在Swift中以编程方式旋转一组按钮?

[英]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. 当UIView的子类创建按钮圈时,NSLayoutConstraint锚定视图。 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 . 我安装按钮的Swift代码改进了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. 如果有人能告诉我如何改进我的代码,那么UI对于每个屏幕尺寸和方向都是一致的,我将不胜感激。

Here is the Viewcontroller 这是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 ......和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 ). 当iPhone被颠倒时出现旋转4( 如上所示 ),并且与接受的答案中解释的原因无关( 见下文 )。 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. 对于iPhone,这种行为是正确的。 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. 它在苹果HIG指南中。 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. 如果要支持倒置旋转,请检查它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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