SwiftUI - 如何获得点击按钮的坐标/位置 [英] SwiftUI - how to get coordinate/position of clicked Button

查看:97
本文介绍了SwiftUI - 如何获得点击按钮的坐标/位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简短版本:如何在 SwiftUI 中获取点击的 Button 的坐标?

Short version: How do I get the coordinates of a clicked Button in SwiftUI?

我正在寻找这样的东西(伪代码),其中 geometry.x 是当前视图中点击按钮的位置:

I'm looking for something like this (pseudo code) where geometry.x is the position of the clicked button in the current view:

GeometryReader { geometry in      
     return Button(action: { self.xPos = geometry.x}) {  
          HStack {               
               Text("Sausages")  
          }  
     }  
}

长版:我正在开始使用 SwiftUI 和 Swift,所以想知道如何最好地从概念上实现这一点.

Long version: I'm beginning SwiftUI and Swift so wondering how best to achieve this conceptually.

举一个我正在玩的具体例子:

To give the concrete example I am playing with:

想象一个标签系统,我想将下划线指示器移动到点击按钮的位置.

Imagine a tab system where I want to move an underline indicator to the position of a clicked button.

[旁白]这篇文章中有一个答案在视觉上做了我想要的,但看起来相当复杂:如何在 SwiftUI 中设置另一个视图的大小[/旁白]

[aside] There is a answer in this post that visually does what I am going for but it seems rather complicated: How to make view the size of another view in SwiftUI [/aside]

这是我的外部结构,它构建了标签栏和矩形(当前指示器)我正在尝试调整大小和位置:

Here is my outer struct which builds the tab bar and the rectangle (the current indicator) I am trying to size and position:


import SwiftUI
import UIKit

struct TabBar: View {

    var tabs:ITabGroup
    @State private var selected = "Popular"
    @State private var indicatorX: CGFloat = 0
    @State private var indicatorWidth: CGFloat = 10
    @State private var selectedIndex: Int = 0

    var body: some View {
        ScrollView(.horizontal) {
            HStack(spacing: 0) {
                ForEach(tabs.tabs) { tab in
                    EachTab(tab: tab, choice: self.$selected, tabs: self.tabs, x: self.$indicatorX, wid: self.$indicatorWidth)
                }
            }.frame(minWidth: 0, maxWidth: .infinity, minHeight: 40, maxHeight: 40).padding(.leading, 10)
                .background(Color(UIColor(hex: "#333333")!))
            Rectangle()
                .frame(width: indicatorWidth, height: 3 )
                .foregroundColor(Color(UIColor(hex: "#1fcf9a")!))
            .animation(Animation.spring())
        }.frame(height: 43, alignment: .leading)
    }
}

这是我的结构,它创建每个选项卡项并包含一个嵌套的 func 以获取单击项的宽度:

Here is my struct that creates each tab item and includes a nested func to get the width of the clicked item:

struct EachTab: View {
    // INCOMING!
    var tab: ITab
    @Binding var choice: String
    var tabs: ITabGroup
    @Binding var x: CGFloat
    @Binding var wid: CGFloat
    @State private var labelWidth: CGRect = CGRect()

    private func tabWidth(labelText: String, size: CGFloat) -> CGFloat {
        let label = UILabel()
        label.text = labelText
        label.font = label.font.withSize(size)
        let labelWidth = label.intrinsicContentSize.width
        return labelWidth
    }

    var body: some View {
        Button(action: { self.choice = self.tab.title; self.x = HERE; self.wid = self.tabWidth(labelText: self.choice, size: 13)}) {
            HStack {
                // Determine Tab colour based on whether selected or default within black or green rab set
                if self.choice == self.tab.title {
                    Text(self.tab.title).foregroundColor(Color(UIColor(hex: "#FFFFFF")!)).font(.system(size: 13)).padding(.trailing, 10).animation(nil)
                } else {
                    Text(self.tab.title).foregroundColor(Color(UIColor(hex: "#dddddd")!)).font(.system(size: 13)).padding(.trailing, 10).animation(nil)
                }
            }
        }
        // TODO: remove default transition fade on button click
    }
}

创建一个非 SwiftUI UILabel 来获取 Button 的宽度似乎有点奇怪.有没有更好的办法?

Creating a non SwiftUI UILabel to get the width of the Button seems a bit wonky. Is there a better way?

是否有一种简单的方法可以获取被点击的 SwiftUI Button 的坐标?

Is there a simple way to get the coordinates of the clicked SwiftUI Button?

推荐答案

原来我通过调整 https://swiftui-lab.com/communicating-with-the-view-tree-part-2/

该技术的本质是使用 anchorPreference,它是一种将有关一个视图的数据发送到链上祖先视图的方法.我在 Apple 世界中找不到任何关于此的文档,但我可以证明它有效.

The essence of the technique is using anchorPreference which is a means of sending data about one view back up the chain to ancestral views. I couldn't find any docs on this in the Apple world but I can attest that it works.

我没有在这里添加代码,因为参考链接还包括我觉得没有资格在这里重复的解释!

I'm not adding code here as the reference link also includes explanation that I don't feel qualified to re-iterate here!

这篇关于SwiftUI - 如何获得点击按钮的坐标/位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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