多语言
1.先创建多语言文件
Localizable.strings
默认寻找的 tableName, 否则, 使用的时候, 需要添加table name, 如果在 framework 等不同的bundle中, 还要添加 bundle
// en
"hungry_title" = "stay foolish, stay hungry";
// zh_sm
"hungry_title" = "求知若饥, 虚心若愚";
2.枚举类型, 添加Key
enum LocalizedKey {
static let kHungryTitle: LocalizedStringKey = "hungry_title"
}
3.在 View 中实现
struct ContentView: View {
var body: some View {
VStack {
Text(LocalizedKey.kHungryTitle)
}
}
}
富文本
Text 实现了操作符重载
1. + 号来拼接不同样式的文本
struct RichTextView: View {
private let text: Text =
Text("Stay ")
.foregroundColor(.blue)
.font(.title)
.italic()
+ Text("Hungry, ")
.font(.headline)
+ Text("Stay ")
.foregroundColor(.red)
.font(.title)
+ Text("Foolish!")
.font(.headline)
.underline()
var body: some View {
text
}
}
2. 用字符串插值实现图文混排
struct RichTextView: View {
private let text: Text =
Text("Hello ")
.foregroundColor(.blue)
+ Text("Swift \(Image(systemName: "swift")) ")
.foregroundColor(.orange)
var body: some View {
text
}
}
Markdown 支持
struct MarkDownView: View {
var body: some View {
Text("**This** ~~is~~ an *example* of **Markdown** `Text`, [More info](https://developer.apple.com/documentation/swiftui/text)")
}
}
渐变文字
1. foregroundStyle
struct GradientTextView: View {
var body: some View {
Text("Stay Hungry, Stay Foolish!")
.font(.title2)
.bold()
.textSelection(.enabled) //长按可复制
.foregroundStyle(
LinearGradient(
colors: [
.orange,
.yellow,
.blue,
.purple
],
startPoint: .topLeading,
endPoint: .bottomTrailing
)
)
}
}
2.给定样式自动减弱
struct AutoHierarchicalStyleView: View {
var body: some View {
VStack(alignment: .leading) {
Label("Apple", systemImage: "applelogo")
.foregroundStyle(.primary)
Label("iPhone", systemImage: "iphone")
.foregroundStyle(.secondary)
Label("iMac", systemImage: "desktopcomputer")
.foregroundStyle(.tertiary)
Label("AirPods", systemImage: "airpods")
.foregroundStyle(.quaternary)
}
}
}
AutoHierarchicalStyleView()
.foregroundStyle(.blue)
iOS 15 新增协议 HierarchicalShapleStyle 有四个等级的属性可以选择
.primary .secondary .tertiary .quaternary
我们可以提供多个样式,查看不同效果
AutoHierarchicalStyleView()
.foregroundStyle(.blue, .purple, .orange)
日期
Text 可以直接展示日期, 有如下初始化方法
public init(_ date: Date, style: Text.DateStyle)
public init(_ dates: ClosedRange<Date>)
public init(_ interval: DateInterval)
DateStyle 可以指定的样式
extension Text {
public struct DateStyle {
/// 11:23PM
public static let time: Text.DateStyle
/// June 3, 2019
public static let date: Text.DateStyle
/// 2 hours, 23 minutes
/// 1 year, 1 month
public static let relative: Text.DateStyle
/// Text(event.startDate, style: .offset)
/// +2 hours
/// -3 months
public static let offset: Text.DateStyle
/// 2:32
/// 36:59:01
public static let timer: Text.DateStyle
}
}
example 代码如下:
struct DateView: View {
var now: Date {
Date()
}
var future: Date {
now.addingTimeInterval(3600)
}
var body: some View {
VStack(alignment: .leading, spacing: 10) {
row(style: ".date") {
Text(now, style: .date)
}
row(style: ".offset") {
Text(future, style: .offset)
}
row(style: ".relative") {
Text(future, style: .relative)
}
row(style: ".time") {
Text(future, style: .time)
}
row(style: ".timer") {
Text(future, style: .timer)
}
row(style: "Range") {
Text(now ... future)
}
row(style: "Interval") {
Text(DateInterval(start: now, end: future))
}
}
}
func row<Content: View>(style: String, @ViewBuilder content: () -> Content) -> some View {
VStack {
HStack {
content()
Spacer()
Text(style)
.foregroundColor(.secondary)
}
Divider()
}
}
}
@ViewBuilder 可以修饰参数, 并从中构建视图
Label
可以快速生成图片和文字的组合, 默认左图右文
1. 改变位置 (左文右图)
Label {
Image(systemName: "swift")
} icon: {
Text("Swift")
}
2.LabelStyle
Label("Swift", systemImage: "swift")
// .labelStyle(.titleOnly)
// .labelStyle(.iconOnly)
.labelStyle(.titleAndIcon)
3.自定义样式
struct ShadowLabelStyle: LabelStyle {
func makeBody(configuration: Self.Configuration) -> some View {
Label(configuration)
.shadow(color: .black.opacity(0.5), radius: 5, x: 0, y: 5)
}
}
extension LabelStyle where Self == ShadowLabelStyle {
static var shadowLabel: Self {
Self()
}
}
上面的样式有一定的局限性,如果我们需要一个垂直布局或是左右对齐的样式呢?]
struct VerticalLabel: LabelStyle {
func makeBody(configuration: Configuration) -> some View {
VStack(alignment: .center, spacing: 10) {
configuration.icon
configuration.title
}
}
}
extension LabelStyle where Self == VerticalLabel {
static var verticalLabel: Self {
Self()
}
}
struct LeftTitleRightIconLabel: LabelStyle {
func makeBody(configuration: Configuration) -> some View {
HStack(alignment: .center, spacing: 10) {
configuration.title
Spacer()
configuration.icon
}
}
}
extension LabelStyle where Self == LeftTitleRightIconLabel {
static var leftTitleRightIconLabel: Self {
Self()
}
}
VStack {
Label("Apple", systemImage: "applelogo")
.labelStyle(.verticalLabel)
Label("Apple", systemImage: "applelogo")
.labelStyle(.leftTitleRightIconLabel)
}
TextField
TextField 有如下的三种构建方式:
1. Return 键的按下动作
@State var s1: String = ""
@State var s2: String = ""
@State var s3: String = ""
@State var pwd: String = ""
GroupBox(label: Text(s1)) {
TextField("TextField", text: $s1)
.onSubmit {
print("click Return")
}
}
2.监听编辑状态
GroupBox(label: Text(s2)) {
TextField("Observe textField", text: $s2) { isEdting in
print(isEdting)
} onCommit: {
print("Click return")
}
}
3. Formatter
GroupBox(label: Text(s3)) {
TextField("Formatter TextField", value: $s3, formatter: NumberFormatter()) { isEditing in
print(isEditing)
} onCommit: {
print("click Return")
}
.textFieldStyle(.roundedBorder)
.keyboardType(.numbersAndPunctuation)
}
4.密码输入框
GroupBox(label: Text("密码输入: \(pwd)")) {
SecureField("Password", text: $pwd)
}
TextEditor
@State var text1: String = ""
TextEditor(text: $s1)
.frame(height: 150)
.lineSpacing(10)
.multilineTextAlignment(.center)
.overlay(RoundedRectangle(cornerRadius: 5).stroke(.blue, lineWidth: 1))
.padding()
创建带有placeHolder 的editor
@State var text2: String = ""
ZStack(alignment: .topLeading) {
TextEditor(text: $text2)
.frame(height: 150)
.border(.blue, width: 1)
.padding()
if text2.isEmpty {
Text("Type someting") .foregroundColor(Color(UIColor.placeholderText))
.padding(20)
}
}