swift - 状态更改后 AnyView 不重新渲染
问题描述
我有下面的函数,它返回 AnyView 并且应该根据设备方向给出不同的结果。当方向改变时,它会被检测并打印,但不会重新渲染视图。知道如何解决这个问题吗?
func getView() -> AnyView {
@State var isPortrait = UIDevice.current.orientation.isPortrait
let a =
HStack {
if isPortrait {
VStack {
Text("text inside VStack")
}
} else {
HStack {
Text("text inside HStack")
}
}
}
.onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)) { _ in
print("notification isPortrait: \(UIDevice.current.orientation.isPortrait)")
isPortrait = UIDevice.current.orientation.isPortrait
}
.onAppear() {
isPortrait = UIDevice.current.orientation.isPortrait
}
return AnyView(a)
}
解决方案
这是我的测试代码,显示了方向的变化。在 ios 15、iPhone 设备上测试。
import SwiftUI
@main
struct TestApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct ContentView: View {
@State var isPortrait = UIDevice.current.orientation.isPortrait // <--- here
var body: some View {
VStack (spacing: 40) {
Text("testing orientations")
// getView() // works just as well
myView // alternative without AnyView
}
}
var myView: some View {
Text(isPortrait ? "should be Portrait" : "should be Landscape")
.onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)) { _ in
isPortrait = UIDevice.current.orientation.isPortrait
}
.onAppear() {
isPortrait = UIDevice.current.orientation.isPortrait
}
}
func getView() -> AnyView {
let a =
HStack {
if isPortrait {
VStack {
Text("should be Portrait")
}
} else {
HStack {
Text("should be Landscape")
}
}
}
.onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)) { _ in
print("notification isPortrait: \(UIDevice.current.orientation.isPortrait)")
isPortrait = UIDevice.current.orientation.isPortrait
}
.onAppear() {
isPortrait = UIDevice.current.orientation.isPortrait
}
return AnyView(a)
}
}
编辑1:
正如@Rob所说,最好的方法是制作一个单独的自定义视图,例如:
struct GetView: View {
@State var isPortrait = UIDevice.current.orientation.isPortrait
var body: some View {
VStack {
HStack {
if isPortrait {
VStack {
Text("should be Portrait")
}
} else {
HStack {
Text("should be Landscape")
}
}
}
.onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)) { _ in
print("notification isPortrait: \(UIDevice.current.orientation.isPortrait)")
isPortrait = UIDevice.current.orientation.isPortrait
}
.onAppear() {
isPortrait = UIDevice.current.orientation.isPortrait
}
}
}
}
推荐阅读
- ios - IOS。当应用程序处于前台时,推送通知自定义声音不会完整播放
- c++ - 在 C++ 中使用 getline、array 以相反的方式转换所有字符
- kubernetes - Kubernetes 中 PersistentVolume 和 PersistentVolumeClaim 之间的概念区别是什么?
- python - 从尚未采用树格式的数据中自动识别父/子连接
- jquery - 根据在nodejs ajax jquery上登录的用户过滤数据
- android - Kotlin 中的包级保护
- azure-data-factory-2 - 检查存储过程已返回一个值
- java - 在 application.yml 中设置 bean 优先级
- react-native - Redux 操作返回未定义?
- python - 在其各自的 one-hot 编码列中填充分类数据的值