SwiftUI
- SwiftUI 是一種基于Swift的強大能力遣铝,簡單創(chuàng)新的構建用戶界面的方法酿炸,并且可以運行在蘋果所有的平臺上
SwiftUI - 聲明式語法
- SwiftUI采用聲明式語法填硕,因為你可以簡單聲明你的用戶界面
- Xcode11提供了強大的設計工具,可以通過簡單的拖拽用SwiftUI生成用戶界面
- 只需要描述一次的布局-為你的視圖聲明任何狀態(tài)的內(nèi)容和布局翅帜,一旦狀態(tài)發(fā)生改變涝滴,SwiftUI會自動更新視圖的渲染
- 構建可復用的組件-將小型歼疮、獨立視圖組合到更大,更復雜的界面中韩脏。在任何為Apple平臺所設計的應用之間,共享您的自定義視圖
- 精簡動畫-創(chuàng)建平滑的動畫就像調(diào)用單個方法一樣簡單杭朱。SwiftUI會在必要時自動計算并過渡動畫
SwiftUI設計工具使用指南
創(chuàng)建項目
Stacks
如何使用SwiftUI構建可復用的組件
地標頁例子
Image組件
struct ContentView: View {
var body: some View {
VStack {
//設置安全距離
MapView().edgesIgnoringSafeArea(.all)
.frame(height: 300)
CircleImage().offset(y: -130).padding(.bottom, -130)
//左對齊
VStack (alignment: .leading) {
Text("圓明園").font(.title)
HStack {
Text("皇家園林").font(.subheadline)
Spacer()
Text("北京").font(.subheadline)
}
}.padding()//邊界留白
Spacer()//留白
}
}
}
圖片組件
struct CircleImage: View {
var body: some View {
//將圖片剪切出一個圓
Image("ymy").clipShape(Circle())
//加一個邊框線
.overlay(Circle().stroke(Color.black, lineWidth: 4))
.shadow(radius: 10)//陰影
}
}
地圖組件
import SwiftUI
import MapKit
struct MapView; UIViewRepresentable {
//創(chuàng)建地圖組件
func makeUIView(context: Context) -> MKMapView {
return MKMapView(frame: .zero)
}
//對地圖組件進行設置
func updateUIView(_ uiView: MKMapView, context: Context) {
//圓明園的經(jīng)緯度
let location = CLLocationCoordinate2D(latitude: 40.00491139888854, longitude: 116.2896180152893)
//展示范圍
let span = MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)
let region = MKCoordinateRegion(center: location, span: span)
uiView.setRegion(region, animated: true)
}
}
如何使用SwiftUI實現(xiàn)動畫
SwiftUI - 動畫
- 在SwiftUI中,你可以將任意的改變過程封裝進一個withAnimation塊中袭景。默認唁桩,SwiftUI會對這種改變采用fade in/out 的方式進行動畫
struct AnimationView: View {
//狀態(tài) 當屬性改變時, 會進行重寫渲染
@State private var showDetail = false
var body: some View {
Button(action: {
withAnimation {
self.showDetail = !self.showDetail
}
}) {
Image(systemName: "chevron.right.circle")//使用了一張系統(tǒng)圖片
.imageScale(.large)//尺寸
.rotationEffect(.degrees(showDetail ? 90 : 0))//旋轉(zhuǎn)90度或0度
.scaleEffect(showDeatil ? 1.5 : 1)//放大倍數(shù)
.padding()
}
}
}
在這里更改顯示入口
深入理解SwiftUI:實現(xiàn)原理探秘
@propertyWrapper
- 通過property Wrapper機制耸棒,對一些類似的屬性的實現(xiàn)代碼做同一封裝
- 通過@propertyWrapper可以移除掉一些重復或者類似的代碼
@state
- 通過@State SwiftUI 實現(xiàn)了值的綁定荒澡、動態(tài)查找和View的自動重現(xiàn)繪制
- 課后題:查看源碼,了解@Binding与殃,@ObservedObject单山,@EnvironmentObject等裝飾器的作用
extension UserDefaults {
public enum Keys {
static let hadShownUserGuide = "hadShownUserGuide"
}
var hadShownUserGuide: Bool {
set {
set(newValue, forKey: Keys.hadShownUserGuide)
}
get {
bool(forKey: Keys.hadShownUserGuide)
}
}
}
struct PropertyWrapperView: View {
@State private var showText = UserDefaults.standard.hasShownUserGuide ? "已經(jīng)展示" : "沒有展示過"
var body: some View {
Button(action: {
if (!UserDefaults.standard.hasShownUserGuide) {
UserDefaults.standard.hasShownUserGuide = true
self.showText = "已經(jīng)展示"
}
}) {
Text(self.showText)
}
}
}
- 使用propertyWrapper進行統(tǒng)一擴展
@propertyWrapper
struct UserDefaultsWrapper<T> {
var key: String
var defaultValue : T
init(_ key: String, defaultValue: T) {
self.key = key
self.defaultValue = defaultValue
}
var wrappedValue: T {
get {
return UserDefaults.standard.value(forKey: key) as? T ?? defaultValue
}
set {
UserDefaults.standard.set(newValue, forKey: key)
}
}
}
struct PropertyWrapperView: View {
@UserDefaultsWrapper("hadShownUserGuide", defaultValue: false)
static var hadShownUserGuide : Bool
@State private var showText = PropertyWrapperView.hasShownUserGuide ? "已經(jīng)展示" : "沒有展示過"
var body: some View {
Button(action: {
if (!PropertyWrapperView.hasShownUserGuide) {
PropertyWrapperView.hasShownUserGuide = true
self.showText = "已經(jīng)展示"
}
}) {
Text(self.showText)
}
}
}