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)
Label
标签是 一种方便的视图,可以将图像和文本并排显示。 这个适用于菜单项或设置。
您可以使用自己的图像或 SF Symbol。
Label("Swift", image: "swift")
Label("Website", systemImage: "globe")
我找不到调整图像大小的方法,并且 SF Symbols 与文本未对齐 在第一个测试版中。
TextField
显示可编辑文本界面的控件。
@State var name: String = "John"
var body: some View {
TextField("Name's placeholder", text: $name)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
}
TextEditor
一个可以显示和编辑长文本的视图。
@State private var fullText: String = "This is some editable text..."
var body: some View {
TextEditor(text: $fullText)
}
SecureField
用户可以安全地输入密码或者私有文本的控件。
@State var password: String = "1234"
var body: some View {
SecureField($password)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
}
Image
显示环境相关图像的视图。
Image("foo") //image name is foo
我们可以使用新的 SF 符号
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() // it will sized so that it fills all the available space
.aspectRatio(contentMode: .fit)
Button
触发时执行操作的控件。
Button(
action: {
// did tap
},
label: { Text("Click Me") }
)
如果你的 Button
的标签只是 Text
你可以用初始化 这个更简单的声明。
Button("Click Me") {
// did tap
}
你可以用这个按钮变 得有点漂亮
Button(action: {
}, label: {
Image(systemName: "clock")
Text("Click Me")
Text("Subtitle")
})
.foregroundColor(Color.white)
.padding()
.background(Color.blue)
.cornerRadius(5)
Link
创建一个链接样式的按钮,它将在关联的应用程序(如果可能),否则在用户的默认网络浏览器打开。
Link("View Our destination: URL(string: "https://www.example.com/TOS.html")!)
NavigationLink
按下时触发导航演示的按钮。 可替换 pushViewController
NavigationView
{
NavigationLink(destination:
Text("Detail")
.navigationBarTitle(Text("Detail"))
) {
Text("Push")
}.navigationBarTitle(Text("Master"))
}
或者通过在自己的视图 DetailView
中使用组目标来使其更具可读性
NavigationView {
NavigationLink(destination: DetailView()) {
Text("Push")
}.navigationBarTitle(Text("Master"))
}
不确定这是错误还是如此设计,在 Beta 5 中,上述代码将无法工作。 尝试换行像这样在 List
中的 NavigationLink
来测试此功能。
NavigationView {
List {
NavigationLink(destination: Text("Detail")) {
Text("Push")
}.navigationBarTitle(Text("Master"))
}
}
如果你的 NavigationLink
的标签只有 Text
你可以 使用这个更简单的声明进行初始化。
NavigationLink("Detail", destination: Text("Detail").navigationBarTitle(Text("Detail")))
ToolbarItem
表示可以放置在工具栏或导航栏中的项目的模型。 这代表了 UINavigationItem
中的大多数属性
添加titleView
。
NavigationView {
Text("SwiftUI").padding()
.toolbar {
ToolbarItem(placement: .principal) {
VStack {
Text("Title")
Button("Clickable Subtitle") { print("principle") }
}
}
}
}
添加 LeftBarButtonItem
或 LeftBarButtonItems
NavigationView {
Text("SwiftUI").padding()
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button {
} label: {
Image(systemName: "square.and.pencil")
}
}
}
}
添加 rightBarButtonItem
或 rightBarButtonItems
。
NavigationView {
Text("SwiftUI").padding()
.toolbar {
ToolbarItem(placement: .primaryAction) {
Button {
} label: {
Image(systemName: "square.and.pencil")
}
}
ToolbarItem(placement: .navigationBarTrailing) {
Button {
} label: {
Image(systemName: "square.and.pencil")
}
}
}
}
Toggle
在开启和关闭状态之间切换的控件。
@State var isShowing = true // toggle state
Toggle(isOn: $isShowing) {
Text("Hello World")
}
如果你的 Toggle
的标签只是 Text
你可以用 这个更简单的声明。
Toggle("Hello World", isOn: $isShowing)
Map
显示嵌入式地图界面的视图。
显示指定区域的地图
import MapKit
@State var region = MKCoordinateRegion(center: .init(latitude: 37.334722, longitude: -122.008889), latitudinalMeters: 300, longitudinalMeters: 300)
Map(coordinateRegion: $region)
您可以通过指定 interactionModes
来控制地图交互(使用 []
禁用所有交互)。
struct PinItem: Identifiable {
let id = UUID()
let coordinate: CLLocationCoordinate2D
}
Map(coordinateRegion: $region,
interactionModes: [],
showsUserLocation: true,
userTrackingMode: nil,
annotationItems: [PinItem(coordinate: .init(latitude: 37.334722, longitude: -122.008889))]) { item in
MapMarker(coordinate: item.coordinate)
}
Picker
用于从一组互斥值中进行选择的控件。
选择器样式根据其祖先进行更改,在 Form
或 List
下,它显示为单个列表行,您可以点击它以进入一个显示所有可能选项的新屏幕。
NavigationView {
Form {
Section {
Picker(selection: $selection, label:
Text("Picker Name")
, content: {
Text("Value 1").tag(0)
Text("Value 2").tag(1)
Text("Value 3").tag(2)
Text("Value 4").tag(3)
})
}
}
}
您可以使用 .pickerStyle(WheelPickerStyle())
覆盖样式。
在 SwiftUI 中,UISegmentedControl
是另一种风格选择器
。
@State var mapChoioce = 0
var settings = ["Map", "Transit", "Satellite"]
Picker("Options", selection: $mapChoioce) {
ForEach(0 ..< settings.count) { index in
Text(self.settings[index])
.tag(index)
}
}.pickerStyle(SegmentedPickerStyle())
分段控制在 iOS 13 中也焕然一新
DatePicker
用于选择日期的控件。
日期选择器样式也会根据其祖先而改变。 在 Form
下或List
,它显示为单个列表行,您可以点击以展开日期选择器(就像日历应用程序 一样)。
@State var selectedDate = Date()
var dateClosedRange: ClosedRange<Date> {
let min = Calendar.current.date(byAdding: .day, value: -1, to: Date())!
let max = Calendar.current.date(byAdding: .day, value: 1, to: Date())!
return min...max
}
NavigationView {
Form {
Section {
DatePicker(
selection: $selectedDate,
in: dateClosedRange,
displayedComponents: .date,
label: { Text("Due Date") }
)
}
}
}
在Form
和List
之外,它显示为普通的滑动选择器
@State var selectedDate = Date()
var dateClosedRange: ClosedRange<Date> {
let min = Calendar.current.date(byAdding: .day, value: -1, to: Date())!
let max = Calendar.current.date(byAdding: .day, value: 1, to: Date())!
return min...max
}
DatePicker(
selection: $selectedDate,
in: dateClosedRange,
displayedComponents: [.hourAndMinute, .date],
label: { Text("Due Date") }
)
如果你的 DatePicker
的标签只是纯 Text
你可以使用这个更简单的声明进行初始化。
DatePicker("Due Date",
selection: $selectedDate,
in: dateClosedRange,
displayedComponents: [.hourAndMinute, .date])
minimumDate
和 maximumDate
可以使用 ClosedRange
, PartialRangeThrough
, 和 PartialRangeFrom
.
DatePicker("Minimum Date",
selection: $selectedDate,
in: Date()...,
displayedComponents: [.date])
DatePicker("Maximum Date",
selection: $selectedDate,
in: ...Date(),
displayedComponents: [.date])
ProgressView
显示任务完成进度的视图。
@State private var progress = 0.5
VStack {
ProgressView(value: progress)
Button("More", action: { progress += 0.05 })
}
通过应用 CircularProgressViewStyle
可以将其用作 UIActivityIndicatorView
。
ProgressView(value: progress)
.progressViewStyle(CircularProgressViewStyle())
Slider
在取值范围内滑动选择值的控件。
@State var progress: Float = 0
Slider(value: $progress, from: 0.0, through: 100.0, by: 5.0)
滑块缺少 minimumValueImage
和 maximumValueImage
,但是 我们可以通过 `HStack
轻松复制
@State var progress: Float = 0
HStack {
Image(systemName: "sun.min")
Slider(value: $progress, from: 0.0, through: 100.0, by: 5.0)
Image(systemName: "sun.max.fill")
}.padding()
Stepper
用于执行语义递增和递减动作的控件。
@State var quantity: Int = 0
Stepper(value: $quantity, in: 0...10, label: { Text("Quantity \(quantity)")})
如果你的 Stepper
的标签只有 Text
你可以初始化使用这个更简单的声明。
Stepper("Quantity \(quantity)", value: $quantity, in: 0...10)
如果您想要完全控制,他们会提供简单的 Stepper
供您管理您自己的数据源。
@State var quantity: Int = 0
Stepper(onIncrement: {
self.quantity += 1
}, onDecrement: {
self.quantity -= 1
}, label: { Text("Quantity \(quantity)") })
如果您还使用初始化器为每个步骤指定一个值的数量step
。
Stepper(value: $quantity, in: 0...10, step: 2) {
Text("Quantity \(quantity)")
}