区块链技术博客
www.b2bchain.cn

关于 SwiftUI 通过 Preference 获取视图 Frame 的隐藏 BUG 探索求职学习资料

本文介绍了关于 SwiftUI 通过 Preference 获取视图 Frame 的隐藏 BUG 探索求职学习资料,有助于帮助完成毕业设计以及求职,是一篇很好的资料。

对技术面试,学习经验等有一些体会,在此分享。

关于 SwiftUI 通过 Preference 获取视图 Frame 的隐藏 BUG 探索

image-20211216085709340

上述界面是一个最简单的界面,他的代码也是很简单。

@main struct ExampleApp: App {     var body: some Scene {         WindowGroup {             Text("Hello World!")         }     } }

我现在突然有一个想法,在App运行之后打印出此时 Text("Hello World!")的所在整个屏幕Frame,经过之前一段探索的经验,我觉得这很简单。原理就是通过GeometryProxy中的frame方法获取到。

通过 GeometryProxy 获取 Frame

可能很多同学已经知道怎么获取,我这里简单说一下,照顾不明白的同学。

1 新建一个 PreferenceKey 用来保存我们获取到的 Frame

struct FrameKey: PreferenceKey {     static var defaultValue: CGRect = .zero     static func reduce(value: inout CGRect, nextValue: () -> CGRect) {         value = nextValue()     } }

2 给 Text("Hello World!") 实现 background 或者 overlay 获取 Frame

background 实现

@main struct ExampleApp: App {     var body: some Scene {         WindowGroup {             Text("Hello World!")                 .background {                     GeometryReader { geometry in                         Color.clear                             .preference(key: FrameKey.self, value: geometry.frame(in: .global))                     }                 }         }     } }

overlay实现

@main struct ExampleApp: App {     var body: some Scene {         WindowGroup {             Text("Hello World!")                 .overlay {                     GeometryReader { geometry in                         Color.clear                             .preference(key: FrameKey.self, value: geometry.frame(in: .global))                     }                 }         }     } }

不管用background还是overlay的方式,我们内部的核心代码没有变,值得注意的是,我们需要用到Color.clear为了不污染我们的视图。

3 通过onPreferenceChange获取刚才保存在preference中的frame

@main struct ExampleApp: App {     var body: some Scene {         WindowGroup {             Text("Hello World!")                 .background {                     ...                 }                 .onPreferenceChange(FrameKey.self) { frame in                     print(frame.debugDescription)                 }          }     } }

此时我们运行,之后发现下面的输出。

(148.5, 418.3333333333333, 93.0, 20.333333333333314)

哇唔!我们做到了,我们真的获取到了,就当我们沾沾自喜,将上述的代码移植我们项目稍微复杂的视图中的时候,我们刚才的代码竟然不生效了。

模拟复杂视图测试

ExampleApp

“`swift
@main
struct ExampleApp: App {

关于 SwiftUI 通过 Preference 获取视图 Frame 的隐藏 BUG 探索

image-20211216085709340

上述界面是一个最简单的界面,他的代码也是很简单。

@main struct ExampleApp: App {     var body: some Scene {         WindowGroup {             Text("Hello World!")         }     } }

我现在突然有一个想法,在App运行之后打印出此时 Text("Hello World!")的所在整个屏幕Frame,经过之前一段探索的经验,我觉得这很简单。原理就是通过GeometryProxy中的frame方法获取到。

通过 GeometryProxy 获取 Frame

可能很多同学已经知道怎么获取,我这里简单说一下,照顾不明白的同学。

1 新建一个 PreferenceKey 用来保存我们获取到的 Frame

struct FrameKey: PreferenceKey {     static var defaultValue: CGRect = .zero     static func reduce(value: inout CGRect, nextValue: () -> CGRect) {         value = nextValue()     } }

2 给 Text("Hello World!") 实现 background 或者 overlay 获取 Frame

background 实现

@main struct ExampleApp: App {     var body: some Scene {         WindowGroup {             Text("Hello World!")                 .background {                     GeometryReader { geometry in                         Color.clear                             .preference(key: FrameKey.self, value: geometry.frame(in: .global))                     }                 }         }     } }

overlay实现

@main struct ExampleApp: App {     var body: some Scene {         WindowGroup {             Text("Hello World!")                 .overlay {                     GeometryReader { geometry in                         Color.clear                             .preference(key: FrameKey.self, value: geometry.frame(in: .global))                     }                 }         }     } }

不管用background还是overlay的方式,我们内部的核心代码没有变,值得注意的是,我们需要用到Color.clear为了不污染我们的视图。

3 通过onPreferenceChange获取刚才保存在preference中的frame

@main struct ExampleApp: App {     var body: some Scene {         WindowGroup {             Text("Hello World!")                 .background {                     ...                 }                 .onPreferenceChange(FrameKey.self) { frame in                     print(frame.debugDescription)                 }          }     } }

此时我们运行,之后发现下面的输出。

(148.5, 418.3333333333333, 93.0, 20.333333333333314)

哇唔!我们做到了,我们真的获取到了,就当我们沾沾自喜,将上述的代码移植我们项目稍微复杂的视图中的时候,我们刚才的代码竟然不生效了。

模拟复杂视图测试

ExampleApp

“`swift
@main
struct ExampleApp: App {

关于 SwiftUI 通过 Preference 获取视图 Frame 的隐藏 BUG 探索

image-20211216085709340

上述界面是一个最简单的界面,他的代码也是很简单。

@main struct ExampleApp: App {     var body: some Scene {         WindowGroup {             Text("Hello World!")         }     } }

我现在突然有一个想法,在App运行之后打印出此时 Text("Hello World!")的所在整个屏幕Frame,经过之前一段探索的经验,我觉得这很简单。原理就是通过GeometryProxy中的frame方法获取到。

通过 GeometryProxy 获取 Frame

可能很多同学已经知道怎么获取,我这里简单说一下,照顾不明白的同学。

1 新建一个 PreferenceKey 用来保存我们获取到的 Frame

struct FrameKey: PreferenceKey {     static var defaultValue: CGRect = .zero     static func reduce(value: inout CGRect, nextValue: () -> CGRect) {         value = nextValue()     } }

2 给 Text("Hello World!") 实现 background 或者 overlay 获取 Frame

background 实现

@main struct ExampleApp: App {     var body: some Scene {         WindowGroup {             Text("Hello World!")                 .background {                     GeometryReader { geometry in                         Color.clear                             .preference(key: FrameKey.self, value: geometry.frame(in: .global))                     }                 }         }     } }

overlay实现

@main struct ExampleApp: App {     var body: some Scene {         WindowGroup {             Text("Hello World!")                 .overlay {                     GeometryReader { geometry in                         Color.clear                             .preference(key: FrameKey.self, value: geometry.frame(in: .global))                     }                 }         }     } }

不管用background还是overlay的方式,我们内部的核心代码没有变,值得注意的是,我们需要用到Color.clear为了不污染我们的视图。

3 通过onPreferenceChange获取刚才保存在preference中的frame

@main struct ExampleApp: App {     var body: some Scene {         WindowGroup {             Text("Hello World!")                 .background {                     ...                 }                 .onPreferenceChange(FrameKey.self) { frame in                     print(frame.debugDescription)                 }          }     } }

此时我们运行,之后发现下面的输出。

(148.5, 418.3333333333333, 93.0, 20.333333333333314)

哇唔!我们做到了,我们真的获取到了,就当我们沾沾自喜,将上述的代码移植我们项目稍微复杂的视图中的时候,我们刚才的代码竟然不生效了。

模拟复杂视图测试

ExampleApp

“`swift
@main
struct ExampleApp: App {

部分转自互联网,侵权删除联系

赞(0) 打赏
部分文章转自网络,侵权联系删除b2bchain区块链学习技术社区 » 关于 SwiftUI 通过 Preference 获取视图 Frame 的隐藏 BUG 探索求职学习资料
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

b2b链

联系我们联系我们