我试图找出正确的方法,有条件地包括一个视图与swiftui。我不能直接在视图中使用if
,必须使用堆栈视图才能做到这一点。
这是可行的,但似乎会有更干净的方法。
var body: some View {
HStack() {
if keychain.get("api-key") != nil {
TabView()
} else {
LoginView()
}
}
}
你没有把它包括在你的问题中,但我猜你在没有堆栈的情况下得到的错误如下?
函数声明了一个不透明的返回类型,但其正文中没有返回语句来推断基础类型
这个错误为您提供了一个很好的提示,但是为了理解它,您需要理解不透明返回类型的概念。这就是如何调用前缀为some
关键字的类型。我在WWDC没有看到任何苹果工程师深入研究这个问题(也许我错过了各自的演讲?),这就是为什么我自己做了很多研究,并写了一篇关于这些类型如何工作以及为什么它们在SwiftUI中用作返回类型的文章。
另外还有一个详细的技术说明
如果你想完全理解正在发生的事情,我建议你读这两本书。
这里有一个简单的解释:
具有不透明结果类型(某些Type
)
的函数或属性必须始终返回相同的具体类型。
在您的示例中,body
属性根据条件返回不同的类型:
var body: some View {
if someConditionIsTrue {
TabView()
} else {
LoginView()
}
}
如果someConditionIsTrue
,它将返回一个TabView
,否则返回一个LoginView
。这违反了规则,这就是编译器抱怨的原因。
如果将条件包装在堆栈视图中,堆栈视图将在其自身的泛型类型中包含两个条件分支的具体类型:
HStack<ConditionalContent<TabView, LoginView>>
因此,无论实际返回哪个视图,堆栈的结果类型始终相同,因此编译器不会抱怨。
实际上,SwiftUI专门为这个用例提供了一个视图组件,正如您在上面的示例中所看到的,它实际上是堆栈内部使用的组件:
它具有以下泛型类型,泛型占位符将从您的实现中自动推断:
ConditionalContent<TrueContent, FalseContent>
我建议使用该视图容器而不是堆栈,因为它使其他html" target="_blank">开发人员在语义上明确了它的用途。
我需要有条件地将一个视图嵌入到另一个视图中,因此我最终创建了一个方便的if
函数:
extension View {
@ViewBuilder
func `if`<Content: View>(_ conditional: Bool, content: (Self) -> Content) -> some View {
if conditional {
content(self)
} else {
self
}
}
}
这确实会返回一个AnyView,这并不理想,但感觉它在技术上是正确的,因为您在编译时并不真正知道它的结果。
在我的例子中,我需要将视图嵌入到ScrollView中,因此它看起来像这样:
var body: some View {
VStack() {
Text("Line 1")
Text("Line 2")
}
.if(someCondition) { content in
ScrollView(.vertical) { content }
}
}
但您也可以使用它有条件地应用修饰符:
var body: some View {
Text("Some text")
.if(someCondition) { content in
content.foregroundColor(.red)
}
}
更新:在使用此选项之前,请阅读使用条件修饰符的缺点:https://www.objc.io/blog/2021/08/24/conditional-view-modifiers/
避免使用额外容器(如HStack
)的最简单方法是将body
属性注释为@ViewBuilder
,如下所示:
@ViewBuilder
var body: some View {
if user.isLoggedIn {
MainView()
} else {
LoginView()
}
}
问题内容: 我需要使用’forumChild’类更改标签的CSS 类。它必须每隔foreach循环的3个循环进行一次更改。 有没有一种方法可以从控件内部执行此操作? 提前致谢 问题答案: 凡和是CSS类
我试图翻译这个(简化)代码使用Java-8流: 以下是我尝试过的: 但以上给出了所有
问题内容: 是否可以通过SwiftUI与现有UIKit应用程序并排构建视图? 我有一个用Objective-C编写的现有应用程序。我已经开始迁移到Swift5。我想知道是否可以将SwiftUI与现有的UIKit .xib视图一起使用。 也就是说,我希望在同一应用程序中使用SwiftUI构建一些视图,并使用UIKit构建一些其他视图。当然不要混合两者。 彼此一起工作 问题答案: 编辑05/06/19
我们为应用程序设计了一些自定义控件,如CustomButton、CustomTexView等。这些控件定义应用程序的主题并具有标准大小。现在我们正计划在我们的项目中使用SwiftUI。如何在SwiftUI结构中使用这些自定义控件? 即。 }
问题内容: 我可以做一个静态列表 但是,如何从数组中动态生成元素列表?我尝试了以下操作,但出现错误: 包含控制流语句的闭包不能与函数生成器“ ViewBuilder”一起使用 有什么解决办法吗?我要完成的工作是一个列表,其中包含不是静态输入的动态元素集。 问题答案: 看起来答案与将我的视图包装在其中有关 这样,我现在可以从服务器获取视图数据并进行组合。而且,仅在需要时才实例化它们。
问题内容: 我有大型CSV,我只对这些行的子集感兴趣。特别是,我想读取在满足特定条件之前发生的所有行。 例如,如果将产生数据框: 有什么方法可以读取csv中的所有行,直到col B超过10。在上面的示例中,我想读入: 我知道在读入数据帧后如何将这些行扔掉,但是到现在为止,我已经花了所有的计算来读入它们。在读取csv之前,我无法访问最后一行的索引请不要跳过脚) 问题答案: 您可以分批读取csv。由于