原文:Fucking Swift UI - Cheat Sheet
译者的话:翻译过程中,发现了原文中的几个错误,我向作者@sarunw提出意见后,直接在译文中改掉了,如果您发现文中内容有误,欢迎与我联系。
关于 SwiftUI,您在下文中看到的所有答案并不是完整详细的,它只能充当一份备忘单,或是检索表。
常见问题
关于 SwiftUI 的常见问题:
是否需要学 SwiftUI?
是
是否有必要现在就学 SwiftUI?
看情况,因为 SwiftUI 目前只能在 iOS 13、macOS 10.15、tvOS 13和 watchOS 6 上运行。如果您要开发的新应用计划仅针对前面提到的 OS 系统,我会说是。 但是,如果您打算找工作或是无法确保会在此 OS 版本的客户端项目上工作,则可能要等一两年,再考虑迁移成 SwiftUI,毕竟大多数客户端工作都希望支持尽可能多的用户,这意味着您的应用必须兼容多个 OS 系统。 因此,一年后再去体验优雅的 SwiftUI 也许是最好的时机。
是否需要学 UIKit/AppKit/WatchKit?
是的,就长时间来看,UIKit 仍将是 iOS 架构的重要组成部分。现在的 SwiftUI 并不成熟完善,我认为即使您打算用 SwiftUI 来开发,仍然不时需要用到 UIKit。
SwiftUI 能代替 UIKit/AppKit/WatchKit 吗?
现在不行,但将来也许会。SwiftUI 虽然是刚刚推出的,它看起来已经很不错。我希望两者能长期共存,SwiftUI 还很年轻,它还需要几年的打磨成长才能去代替 UIKit/AppKit/WatchKit。
如果我现在只能学习一种,那么应该选择 UIKit/AppKit/WatchKit 还是 SwiftUI?
UIKit。 您始终可以依赖 UIKit,它用起来一直不错,且未来一段时间仍然可用。如果您直接从 SwiftUI 开始学习,可能会遗漏了解一些功能。
SwiftUI 的控制器在哪里?
没有了。 如今页面间直接通过响应式编程框架 Combine 交互。Combine 也作为新的通信方式替代了 UIViewController。
要求
- Xcode 11 Beta(从 Apple 官网下载)
- iOS 13 / macOS 10.15 / tvOS 13 / watchOS 6
- macOS Catalina,以便在画布上呈现 SwiftUI(从 Apple 官网下载)
想要体验 SwiftUI 画布,但不想在您的电脑上安装 macOS Catalina beta 系统
您可以与当前的 macOS 版本并行安装 Catalina。这里介绍了如何在单独的 APFS 卷上安装 macOS
SwiftUI 中等效的 UIKit
视图控制器
UIKit | SwiftUI | 备注 |
---|---|---|
UIViewController | View | - |
UITableViewController | List | - |
UICollectionViewController | - | 目前,还没有 SwiftUI 的替代品,但是您可以像Composing Complex Interfaces’s tutorial里那样,使用 List 的组成来模拟布局 |
UISplitViewController | NavigationView | Beta 5中有部分支持,但仍然无法使用。 |
UINavigationController | NavigationView | - |
UIPageViewController | - | - |
UITabBarController | TabView | - |
UISearchController | - | - |
UIImagePickerController | - | - |
UIVideoEditorController | - | - |
UIActivityViewController | - | - |
UIAlertController | Alert | - |
视图和控件
UIKit | SwiftUI | 备注 |
---|---|---|
UILabel | Text | - |
UITabBar | TabView | - |
UITabBarItem | TabView | TabView 里的 .tabItem |
UITextField | TextField | Beta 5中有部分支持,但仍然无法使用。 |
UITableView | List | VStack 和 Form 也可以 |
UINavigationBar | NavigationView | NavigationView 的一部分 |
UIBarButtonItem | NavigationView | NavigationView 里的 .navigationBarItems |
UICollectionView | - | - |
UIStackView | HStack | .axis == .Horizontal |
UIStackView | VStack | .axis == .Vertical |
UIScrollView | ScrollView | - |
UIActivityIndicatorView | - | - |
UIImageView | Image | - |
UIPickerView | Picker | - |
UIButton | Button | - |
UIDatePicker | DatePicker | - |
UIPageControl | - | - |
UISegmentedControl | Picker | Picker 中的一种样式 SegmentedPickerStyle |
UISlider | Slider | - |
UIStepper | Stepper | - |
UISwitch | Toggle | - |
UIToolBar | - | - |
框架集成 - SwiftUI 中的 UIKit
将 SwiftUI 视图集成到现有应用程序中,并将 UIKit 视图和控制器嵌入 SwiftUI 视图层次结构中。
UIKit | SwiftUI | 备注 |
---|---|---|
UIView | UIViewRepresentable | - |
UIViewController | UIViewControllerRepresentable | - |
框架集成 - UIKit 中的 SwiftUI
将 SwiftUI 视图集成到现有应用程序中,并将 UIKit 视图和控制器嵌入 SwiftUI 视图层次结构中。
UIKit | SwiftUI | 备注 |
---|---|---|
UIView (UIHostingController) | View | 没有直接转换为 UIView 的方法,但是您可以使用容器视图将 UIViewController 中的视图添加到视图层次结构中 |
UIViewController (UIHostingController) | View | - |
SwiftUI - 视图和控件
Text
显示一行或多行只读文本的视图。
Text("Hello World")
样式:
Text("Hello World")
.bold()
.italic()
.underline()
.lineLimit(2)
Text
中填入的字符串也用作 LocalizedStringKey
,因此也会直接获得 NSLocalizedString
的特性。
Text("This text used as localized key")
直接在文本视图里格式化文本。 实际上,这不是 SwiftUI 的功能,而是 Swift 5的字符串插入特性。
static let dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .long
return formatter
}()
var now = Date()
var body: some View {
Text("What time is it?: \(now, formatter: Self.dateFormatter)")
}
可以直接用 +
拼接 Text
文本:
Text("Hello ") + Text("World!").bold()
文字对齐方式:
Text("Hello\nWorld!").multilineTextAlignment(.center)
TextField
显示可编辑文本界面的控件。
@State var name: String = "John"
var body: some View {
TextField("Name's placeholder", text: $name)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
}
SecureField
用户安全地输入私人文本的控件。
@State var password: String = "1234"
var body: some View {
SecureField($password)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
}
Image
显示图像的视图。
Image("foo") //图像名字为 foo
我们可以使用新的 SF Symbols:
Image(systemName: "clock.fill")
您可以通过为系统图标添加样式,来匹配您使用的字体:
Image(systemName: "cloud.heavyrain.fill")
.foregroundColor(.red)
.font(.title)
Image(systemName: "clock")
.foregroundColor(.red)
.font(Font.system(.largeTitle).bold())
为图片增加样式:
Image("foo")
.resizable() // 调整大小,以便填充所有可用空间
.aspectRatio(contentMode: .fit)
在触发时执行操作的控件。
Button(
action: {
// 点击事件
},
label: {
Text("Click Me") }
)
如果按钮的标签只有 Text
,则可以通过下面这种简单的方式进行初始化:
Button("Click Me") {
// 点击事件
}
您可以像这样给按钮添加属性:
Button(action: {
}, label: {
Image(systemName: "clock")
Text("Click Me")
Text("Subtitle")
})
.foregroundColor(Color.white)
.padding()
.background(Color.blue)
.cornerRadius(5)
按下时会触发导航演示的按钮。它用作代替 pushViewController
。
NavigationView {
NavigationLink(destination:
Text("Detail")
.navigationBarTitle(Text("Detail"))