微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

有没有办法根据swift中的中心点放置按钮? 偏移量(x:y:)位置(x:y:)

如何解决有没有办法根据swift中的中心点放置按钮? 偏移量(x:y:)位置(x:y:)

这就是我想要做的:

enter image description here

有谁知道我如何快速做到这一点? 我知道有一些图书馆可以做类似的事情,但我正在尝试自己做

解决方法

您可以使用 UICollectionView 和自定义 UICollectionViewLayout

一些例子:

,

当然。使用距中心点的偏移量设置约束,并使用三角函数计算偏移量。代码可能如下所示:

let steps = 16     // The number of buttons you want
let radius = 75.0. // Your desired circle radius,in points
let angleStep = Double.pi * 2.0 / Double(steps)
for index in 0 ..< steps {
    let angle = Double(index) * angleStep
    let xOffset = CGFloat(radius * cos(angle))
    let yOffset = CGFloat(radius * sin(angle))
    // add button to superview with center anchored to center of superview 
    // offset by xOffset and yOffset
}

编辑:

我主要使用故事板创建视图和控件,因此这是练习在代码中创建它们的好借口。我在 github 上做了一个演示项目,创建了一圈按钮。你可以在这里下载:

https://github.com/DuncanMC/ButtonsInCircle.git

所有逻辑都在视图控制器的源文件中:

//
//  ViewController.swift
//  ButtonsInCircle
//
//  Created by Duncan Champney on 2/28/21.
//

import UIKit

class ViewController: UIViewController {


    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var buttonContainerView: UIView!

    let buttonCount = 12 //The number of buttons to create
    var angleStep: Double = 0 //The change in angle between buttons

    var radius: CGFloat = 75.0  // The radius to use (will be updated at runtime based on the size of the container view.)

    //A type to hold a layout anchor for a button,it's index,and whether it's a horizontal or veritical anchor
    typealias ConstraintTuple = (index: Int,anchor: NSLayoutConstraint,axis: NSLayoutConstraint.Axis)

    //An array of the layout anchors for our buttons.
    var constraints = [ConstraintTuple]()

    //Our layout has changed. Update the array of layout anchors
    func updateButtonConstraints() {

            for (index,constraint,axis) in self.constraints {
                let angle = Double(index) * self.angleStep
                let xOffset = self.radius * CGFloat(cos(angle))
                let yOffset = self.radius * CGFloat(sin(angle))
                if axis == .horizontal {
                    constraint.constant = xOffset
                } else {
                    constraint.constant = yOffset
                }
            }
    }

    override func viewDidLayoutSubviews() {
        //Pick a radius that's a little less than 1/2 the shortest side of our bounding rectangle
        radius = min(buttonContainerView.bounds.width,buttonContainerView.bounds.height) / 2 - 30
        print("Radius = \(radius)")
        updateButtonConstraints()
    }

    func createButtons() {
        for index in 0 ..< buttonCount {

            //Create a button
            let button = UIButton(primaryAction:
                                    //Define the button title,and the action to trigger when it's tapped.
                                    UIAction(title: "Button \(index+1)") { action in
                                        print("Button \(index + 1) tapped")
                                    }
            )
            button.translatesAutoresizingMaskIntoConstraints = false //Remember to do this for UIViews you create in code
            button.layer.borderWidth = 1.0  // Draw a rounded rect around the button so you can see it
            button.layer.cornerRadius = 5

            button.setTitle("\(index+1)",for: .normal)
            button.setTitleColor(.blue,for: .normal)

            //Add it to the container view
            buttonContainerView.addSubview(button)
            button.sizeToFit()

            //Create center x & y layout anchors (with no offset to start)
            let buttonXAnchor = button.centerXAnchor.constraint(equalTo: buttonContainerView.centerXAnchor,constant: 0)
            buttonXAnchor.isActive = true

            //Add a tuple for this layout anchor to our array
            constraints.append(ConstraintTuple(index: index,anchor: buttonXAnchor,axis: .horizontal))

            let buttonYAnchor =  button.centerYAnchor.constraint(equalTo: buttonContainerView.centerYAnchor,constant: 0)
            buttonYAnchor.isActive = true

            //Add a tuple for this layout anchor to our array
            constraints.append(ConstraintTuple(index: index,anchor: buttonYAnchor,axis: .vertical))
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        angleStep = Double.pi * 2.0 / Double(buttonCount)
        createButtons()
    }


}

运行时是这样的:
enter image description here

(在 iOS 上,就指南针而言,起始角度 (0°) 是“东”。如果您希望第一个按钮从顶部开始,则必须为起始角度添加偏移量。)

,

SwiftUI

您可以使用 offset(x: y)position(x:y) 将任何视图定位到任何位置。

偏移量(x:y:)

按指定的水平和垂直距离偏移此视图。 - https://developer.apple.com

位置(x:y:)

将此视图的中心定位在其指定坐标处 父母的坐标空间。https://developer.apple.com

例如:

    ZStack {
        Text("A")
            .background(Color.red)
            .position(x: 10,y: 20)
        
        Text("b")
            .background(Color.red)
            .position(x: 50,y: 30)
        
        Text("c")
            .background(Color.red)
            .position(x: 100,y: 40)
        Text("d")
            .background(Color.red)
            .position(x: 150,y: 200)
    }

自己找出确切的 x 和 y 位置


欲了解更多信息,请阅读这篇文章 https://www.hackingwithswift.com/books/ios-swiftui/absolute-positioning-for-swiftui-views

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。