View SwiftUI:如何检测两个视图是否相交?
一个视图与另一个视图相交。我们如何在SwiftUI中检测这个十字路口 在Swift中,我将通过几行代码实现这一点:View SwiftUI:如何检测两个视图是否相交?,view,swiftui,frame,intersection,View,Swiftui,Frame,Intersection,一个视图与另一个视图相交。我们如何在SwiftUI中检测这个十字路口 在Swift中,我将通过几行代码实现这一点: import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let a = UIView(frame: CGRect(x: 100, y: 100, width: 150, height: 150)) a.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let a = UIView(frame: CGRect(x: 100, y: 100, width: 150, height: 150))
a.backgroundColor = .purple
view.addSubview(a)
let b = UIView(frame: CGRect(x: 150, y: 150, width: 150, height: 150))
b.backgroundColor = .orange
view.addSubview(b)
if a.frame.intersects(b.frame) {
print("yes!")
} else {
print("no intersection!")
}
}
}
显然,它与SwiftUI无关:我们这里有另一个框架概念。什么可以替代?有人有主意吗
更新:
非常感谢他们的帮助和建议!
以下是我尝试使用矩形数组解决问题的方法:
import SwiftUI
struct ContentView: View {
@State var rect = CGRect()
@State var aRects = [CGRect]()
var body: some View {
VStack {
ZStack {
Rectangle()
.frame(width: 150, height: 300)
.foregroundColor(.purple)
.background(self.rectReader(self.$rect))
HStack {
Spacer()
Spacer()
Spacer()
Rectangle()
.frame(width: 150, height: 180)
.foregroundColor(.pink)
.background(self.rectReader(self.$rect))
Spacer()
}
}
Button(action: {
//print("aRects: \(self.aRects)")
self.checkIntersection()
}){
Text("Check Intersection!")
}
}
}
// fill array of rects here
func rectReader(_ binding: Binding<CGRect>) -> some View {
return GeometryReader { (geometry) -> AnyView in
let rect = geometry.frame(in: .global)
DispatchQueue.main.async {
binding.wrappedValue = rect
print("rect: \(self.rect)")
self.aRects.append(self.rect)
}
return AnyView(Rectangle().fill(Color.clear))
}
}
func checkIntersection() {
if aRects.count == 2 {
if self.aRects[0].intersects(self.aRects[1]) {
print("yes!")
} else {
print("no!")
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
导入快捷界面
结构ContentView:View{
@状态变量rect=CGRect()
@状态变量aRects=[CGRect]()
var body:一些观点{
VStack{
ZStack{
矩形()
.框架(宽度:150,高度:300)
.foregroundColor(.紫色)
.background(self.rectReader(self.$rect))
HStack{
垫片()
垫片()
垫片()
矩形()
.框架(宽度:150,高度:180)
.foregroundColor(.粉色)
.background(self.rectReader(self.$rect))
垫片()
}
}
按钮(操作:{
//打印(“aRects:\(self.aRects)”)
self.checkIntersection()
}){
文本(“检查交点!”)
}
}
}
//在这里填充矩形数组
func rectReader(u-binding:binding)->一些视图{
返回GeometryReader{(几何)->中的任意视图
设rect=geometry.frame(in:.全局)
DispatchQueue.main.async{
binding.wrappedValue=rect
打印(“rect:\(self.rect)”)
self.aRects.append(self.rect)
}
返回任意视图(矩形().fill(Color.clear))
}
}
func checkIntersection(){
如果aRects.count==2{
如果self.aRects[0]相交(self.aRects[1]){
打印(“是!”)
}否则{
打印(“否!”)
}
}
}
}
结构内容视图\u预览:PreviewProvider{
静态var预览:一些视图{
ContentView()
}
}
你的问题一点也不愚蠢强> 这似乎很容易
struct SizeReader: View {
var body: some View {
GeometryReader { proxy in
Color.clear
.preference(key: Sizes.self, value: [proxy.frame(in: .global)])
}
}
}
现在,我们可以使用它来保存我们的尺寸偏好键中的帧矩形
RectView(color: .pink).background(SizeReader())
那我们的观点呢?为了演示我们的“简单解决方案”是如何工作的,想象一下有人用随机大小和随机对齐创建它
struct RectView: View {
let color: Color
let size = CGFloat(Int.random(in: 50 ... 200))
var body: some View {
color.frame(width: size, height: size)
.alignmentGuide(HorizontalAlignment.center) {
CGFloat.random(in: 0 ..< $0.width)
}
.alignmentGuide(VerticalAlignment.center) {
CGFloat.random(in: 0 ..< $0.width)
}
}
}
运行它,每次单击屏幕的黑色部分时,您都会看到两个随机大小和位置的矩形,并在调试窗口中打印输出值我们感兴趣
警告检查打印输出,您会发现错误
代码是一个错误示例,我把它放在这里是为了证明,您的问题一点也不愚蠢!关于SwiftUI布局及其幕后工作原理,有很多想法需要理解。
我希望,聪明的人会尝试解释错误,并指导我们如何使其发挥功能,欢迎所有专家!请不要更改RectView,认为它是一些内置的SwiftUI组件。你试过什么吗?至少?我读了很多关于几何读取器等的东西,但还没有找到一个简单的方法。很抱歉如果我的问题看起来很愚蠢。@Asperi请看我的答案:-)尤其是最后一部分。user3441734,谢谢你的建议和解释!对我来说,从这一点出发,走得更远是一个真正的帮助。你能看看我在帖子里的更新吗?我尝试使用矩形数组而不是首选项。它似乎可以工作,代码也比较少,但我很乐意听取您的意见。@Roman preferenceKey方法是正确的方法,一旦您了解了它的工作原理,它就很容易使用。请参阅和下一部分。我的例子表明,边界框和视觉外观可能完全不同。是的,我看到了这种差异,谢谢。但是你也接受数组的用法吗?@Roman:-)你必须喜欢它!代码的异步部分工作正常,我经常使用类似的解决方案。你必须明白它非常脆弱,将来可能会停止工作。使用首选项是有很好的文档记录和解决方案,这与SwiftUI布局所有UI组件的方式非常相似。@Roman我有一个提示,让您解决我示例中的错误。它是在RectView中构建的,它还演示了异步方法脆弱的原因:-)(可能很难找到)
struct RectView: View {
let color: Color
let size = CGFloat(Int.random(in: 50 ... 200))
var body: some View {
color.frame(width: size, height: size)
.alignmentGuide(HorizontalAlignment.center) {
CGFloat.random(in: 0 ..< $0.width)
}
.alignmentGuide(VerticalAlignment.center) {
CGFloat.random(in: 0 ..< $0.width)
}
}
}
struct ContentView: View {
@State var id = UUID()
var body: some View {
VStack {
ZStack {
Color.black
RectView(color: .pink)
.background(SizeReader())
RectView(color: .yellow)
.background(SizeReader())
.blendMode(.difference)
}
.onPreferenceChange(Sizes.self) { (value) in
let intersection = value[0].intersection(value[1])
print(value[0])
print(value[1])
print(intersection)
print()
}
.onTapGesture {
self.id = UUID()
}
Text("paceholder").id(id)
}
}
}