1、NavigationLink方式跳转
import SwiftUI
struct InfoModel : Hashable
{
var description : String
var pictureName : String
}
struct DetailView : View
{
var imageName : String
var body: some View
{
Image(imageName)
}
}
struct ContentView : View
{
var messages : [InfoModel]
var body: some View
{
NavigationView
{
List
{
ForEach(messages, id: \.self)
{ message in
NavigationLink(destination:
DetailView(imageName: message.pictureName))
{
Text(message.description)
}
}
}
.navigationBarTitle("Pictures List")
}
}
}
#if DEBUG
struct ContentView_Previews : PreviewProvider
{
static var previews: some View
{
let model1 = InfoModel(description: "A lady with a horse", pictureName: "Picture1")
let model2 = InfoModel(description: "An African animal with a very long neck", pictureName: "Picture2")
return ContentView(messages: [model1, model2])
}
}
#endif
2、导航栏设置
1. displayMode -- .inline 和 .large
2.navigationBarHidden(true) -- 隐藏导航栏
import SwiftUI
struct ContentView : View
{
init() {
//Use this if NavigationBarTitle is with Large Font
UINavigationBar.appearance().largeTitleTextAttributes = [.foregroundColor: UIColor.red]
UINavigationBar.appearance().backgroundColor = .purple
//Use this if NavigationBarTitle is with displayMode = .inline
UINavigationBar.appearance().titleTextAttributes = [.foregroundColor: UIColor.red]
}
var body: some View
{
NavigationView
{
Text("SwiftUI's NavigationView")
// .navigationBarTitle(Text("SwiftUI"))
// .navigationBarTitle(Text("SwiftUI"), displayMode: .inline)
.navigationBarTitle(Text("SwiftUI"), displayMode: .large)
// .navigationBarHidden(true)
}
}
}
3、导航栏按钮设置 -- navigationBarItems(leading:,trailing:)
import SwiftUI
struct TrailingButtons : View
{
var body: some View
{
HStack
{
Button(action: {
print("Download the data")
}) {
Image(systemName: "icloud.and.arrow.down.fill")
}
Button(action: {
print("Edit the data")
}) {
Image(systemName: "pencil.tip.crop.circle")
}
}
}
}
struct ContentView : View
{
var body: some View
{
NavigationView
{
Text("SwiftUI's NavigationView")
.navigationBarTitle(Text("SwiftUI"))
.navigationBarItems(leading: Button(action: {
print("Go to index page")
}) {
Text("Index")
}, trailing: TrailingButtons())
}
}
}
4、导航页面添加工具栏 -- ToolbarItem(placement: ToolbarItemPlacement.bottomBar)
import SwiftUI
struct ToolbarButtons : View
{
@State var isPresented = false
var body: some View
{
HStack(spacing:50)
{
Button(action: {
self.isPresented.toggle()
}, label: {
Image(systemName: "plus.circle")
})
.alert(isPresented: $isPresented, content: {
Alert(title: Text("Operation"),
message: Text("Create a new file."))
})
Button(action: {}, label: {
Image(systemName: "square.and.pencil")
})
Button(action: {}, label: {
Image(systemName:"trash")
})
}
}
}
struct ContentView : View
{
var body: some View
{
NavigationView
{
Text("SwiftUI's NavigationView")
.navigationTitle(Text("SwiftUI"))
.toolbar(content:
{
ToolbarItem(placement: ToolbarItemPlacement.bottomBar)
{
ToolbarButtons()
}
})
}
}
}
4、PresentationMode实现导航的后退
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
5、模态窗口的开关控制 -- @Binding
import SwiftUI
struct ContentView : View
{
@State var isPresented = false
var body: some View
{
PopView(show: $isPresented)
.sheet(isPresented: $isPresented, content:
{
Button(action:
{
self.isPresented.toggle()
}){
Text("Dismiss").font(.largeTitle)
}
})
}
}
struct PopView: View
{
@Binding var show : Bool
var body: some View
{
Button(action:
{
self.show.toggle()
}) {
Image(systemName: "person.crop.circle")
.font(.system(size: 32))
.frame(width: 64, height: 64)
.foregroundColor(.black)
.background(Color.white)
.cornerRadius(30)
.shadow(color: .orange, radius: 10, x: 0, y: 10)
}
}
}
6、@ObservableObject 监听实例对象
示例代码一:
import SwiftUI
class UserModel: ObservableObject
{
@Published var nickName: String = ""
}
struct ContentView : View
{
@ObservedObject var model = UserModel()
@State var isPresented = false
let dismiss = Alert.Button.default(Text("OK")) {}
var alert: Alert
{
Alert(title: Text("Your nickname"),
message: Text("\(self.model.nickName)"),
dismissButton: dismiss)
}
var body: some View
{
VStack
{
TextField("Your nickname", text: $model.nickName)
.padding()
Button(action:
{
self.isPresented = true
}) {
Text("Show")
}
.alert(isPresented: $isPresented)
{ () -> Alert in
alert
}
}
}
}
示例代码二:
import SwiftUI
struct ContentView : View
{
@ObservedObject var timer = MyTimer()
var body: some View
{
Text("Coin number: \(self.timer.coinNumber)")
.font(.largeTitle)
}
}
7、@ObservedObject 和 @StateObject 的区别
a. model属性被@ObservedObject修饰时,它使model和视图之间处于订阅关系,当视图的状态发生变化时,会重新生成视图中所有的子视图,蛋挞数量从2->0。 b. 被@StateObject修饰时,会保持新的数据,蛋挞数量不会变化。
import SwiftUI
class EggTartModel: ObservableObject
{
@Published var score: Int = 0
init()
{
print("EggTartModel Created.")
}
}
struct FoodPicker: View
{
@StateObject var model = EggTartModel()
var body: some View
{
HStack
{
Text("Egg tart: \(model.score)")
Button(" + ")
{
model.score += 1
}
}
.padding()
}
}
struct ContentView: View
{
@State private var withCoupon = false
var body: some View
{
VStack
{
FoodPicker()
HStack
{
Text("Using Coupon: \(withCoupon ? "Yes" : "No")")
Button("Coupon")
{
withCoupon.toggle()
}
}
}
}
}
8、@EnvironmentObject
使用@EnvironmentObject,你可以在整个程序的任意页面设置和读取对象。
import SwiftUI
@main
struct DemoProjectApp: App
{
var model : UserModel{
let model = UserModel()
model.nickName = "Super man"
return model
}
var body: some Scene
{
WindowGroup
{
ContentView().environmentObject(model)
}
}
}
import SwiftUI
class UserModel: ObservableObject
{
@Published var nickName: String = ""
}
struct DetailView: View
{
@EnvironmentObject var model : UserModel
var body: some View
{
Text("Your nickname: \(model.nickName)")
}
init()
{
print(model.nickName)
}
}
struct ContentView : View
{
@EnvironmentObject var model : UserModel
@State var isPresented = false
var body: some View
{
NavigationView
{
VStack
{
TextField("Your nickname", text: $model.nickName)
.padding()
NavigationLink(destination: DetailView())
{
Text("Show Detail")
}
}
}
}
}
9、@Environment
@Environment需要根据预定的键,获取对应的值。
- 要使用@Environment,首先要定于一个遵循EnvironmentKey的Struct,并实现协议中的defaultValue属性,给它指定一个默认值。
- 如果需要添加更多的key,需要对EnvironmentValues进行扩展。添加新的键,如代码中的myCustomValue,实现myCustomValue的get和set方法。
- @Environment(.myCustomValue) var customValue: String 这句代码表示往myCustomValue中存储、读取数据,读取的结果放在customValue属性中。
- 可以在 ContentView_Previews 中通过 .environment(.myCustomValue, "You get another value from environment.") 给指定的键设置值。
import SwiftUI
private struct MyEnvironmentKey: EnvironmentKey
{
static let defaultValue: String = "Default value"
}
extension EnvironmentValues
{
var myCustomValue: String
{
get { self[MyEnvironmentKey.self] }
set { self[MyEnvironmentKey.self] = newValue }
}
}
struct ContentView: View
{
@Environment(\.myCustomValue) var customValue: String
var body: some View
{
VStack
{
Text(customValue)
}
}
}
#if DEBUG
struct ContentView_Previews : PreviewProvider
{
static var previews: some View
{
ContentView()
.environment(\.myCustomValue, "You get another value from environment.")
}
}
#endif
10、@AppStorage -- 将属性值同步到UserDefaults中
import SwiftUI
struct ContentView : View
{
@AppStorage("nickname") var nickname: String = "Fate"
var body: some View
{
VStack(spacing:20)
{
Text(nickname)
Button(action: {
self.nickname = "Finney"
print(UserDefaults.standard.value(forKey: "nickname") as! String)
}, label: {
Text("Change nickname")
})
}
.padding()
}
}
11、SwiftUI生命周期管理 -- @Environment(.scenePhase) var swiftUIScenePhase
import SwiftUI
@main
struct DemoProjectApp: App
{
@Environment(\.scenePhase) var swiftUIScenePhase
var body: some Scene
{
WindowGroup
{
ContentView()
}
.onChange(of: swiftUIScenePhase) { scenePhase in
print("Scene phase: \(scenePhase)")
}
}
}
12、AppDelegate
import UIKit
class AppDelegate: NSObject, UIApplicationDelegate, ObservableObject
{
@Published var globalVariable: String = ""
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool
{
self.globalVariable = "twitter api key"
return true
}
}
import SwiftUI
struct ContentView: View
{
@EnvironmentObject var appDelegate: AppDelegate
var body: some View
{
Text("Value: \(appDelegate.globalVariable)")
}
}
struct ContentView_Previews: PreviewProvider
{
static var previews: some View
{
ContentView()
}
}