美文网首页
38 SwiftUI

38 SwiftUI

作者: 为了自由的白菜 | 来源:发表于2023-06-20 12:23 被阅读0次

SwiftUI

image-20230312113352480.png
  • SwiftUI 是一种基于Swift的强大能力,简单创新的构建用户界面的方法,并且可以运行在苹果所有的平台上
image-20230312113624800.png

SwiftUI - 声明式语法

  • SwiftUI采用声明式语法,因为你可以简单声明你的用户界面
image-20230312113734752.png
  • Xcode11提供了强大的设计工具,可以通过简单的拖拽用SwiftUI生成用户界面
image-20230312114050160.png
  • 只需要描述一次的布局-为你的视图声明任何状态的内容和布局,一旦状态发生改变,SwiftUI会自动更新视图的渲染
  • 构建可复用的组件-将小型、独立视图组合到更大,更复杂的界面中。在任何为Apple平台所设计的应用之间,共享您的自定义视图
  • 精简动画-创建平滑的动画就像调用单个方法一样简单。SwiftUI会在必要时自动计算并过渡动画

SwiftUI设计工具使用指南

创建项目

image-20230312212430872.png

Stacks

image-20230312212509459.png

如何使用SwiftUI构建可复用的组件

地标页例子

image-20230312214019068.png

Image组件

image-20230312214151969.png image-20230312214348729.png image-20230312214400782.png image-20230312214452467.png
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 {
    
    //创建地图组件
    func makeUIView(context: Context) -> MKMapView {
        return MKMapView(frame: .zero)
    }
    
    //对地图组件进行设置
    func updateUIView(_ uiView: MKMapView, context: Context) {
        //圆明园的经纬度
        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实现动画

SwiftUI - 动画

  • 在SwiftUI中,你可以将任意的改变过程封装进一个withAnimation块中。默认,SwiftUI会对这种改变采用fade in/out 的方式进行动画
struct AnimationView: View {
    
    //状态 当属性改变时, 会进行重写渲染
    @State private var showDetail = false
    
    var body: some View {
        Button(action: {
            withAnimation {
                self.showDetail = !self.showDetail
            }
        }) {
            Image(systemName: "chevron.right.circle")//使用了一张系统图片
                .imageScale(.large)//尺寸
                .rotationEffect(.degrees(showDetail ? 90 : 0))//旋转90度或0度
                .scaleEffect(showDeatil ? 1.5 : 1)//放大倍数
            .padding()
        }
    }
}

在这里更改显示入口

image-20230312224524873.png

深入理解SwiftUI:实现原理探秘

@propertyWrapper

  • 通过property Wrapper机制,对一些类似的属性的实现代码做同一封装
  • 通过@propertyWrapper可以移除掉一些重复或者类似的代码

@state

  • 通过@State SwiftUI 实现了值的绑定、动态查找和View的自动重现绘制
image-20230312225028447.png image-20230312225141503.png
  • 课后题:查看源码,了解@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 ? "已经展示" : "没有展示过"
    
    var body: some View {
        Button(action: {
            if (!UserDefaults.standard.hasShownUserGuide) {
                UserDefaults.standard.hasShownUserGuide = true
                self.showText = "已经展示"
            }
        }) {
            Text(self.showText)
        }
    }
}
  • 使用propertyWrapper进行统一扩展
@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 ? "已经展示" : "没有展示过"
    
    var body: some View {
        Button(action: {
            if (!PropertyWrapperView.hasShownUserGuide) {
                PropertyWrapperView.hasShownUserGuide = true
                self.showText = "已经展示"
            }
        }) {
            Text(self.showText)
        }
    }
}

相关文章

网友评论

      本文标题:38 SwiftUI

      本文链接:https://www.haomeiwen.com/subject/fwmyydtx.html