美文网首页
第二十五篇:SwiftUI使用

第二十五篇:SwiftUI使用

作者: 坚持才会看到希望 | 来源:发表于2022-11-29 23:07 被阅读0次

    swiftUI是声明式,可夸平台(macOs,tvOs,watchOS,iOS)。传统的UIKit是指令式。

    UIKit和swifitUI可以互相通讯 。

    为什么要推出swiftUI:


    9211669780399_.pic.jpg 9221669780685_.pic.jpg 9231669780940_.pic.jpg 9241669781059_.pic.jpg 9251669781091_.pic.jpg

    swiftUI用struct结构体来表示UI,占用大小小比Class(oc里面的)。没有任何继承下来的东西。Modifies Library许多拖拽的UI。其中其还有markdown语法。

    下面是一些SwiftUI里的一些控件

    timelineview可以按计划刷新view,asyncImage加载图片等,canvas绘制,textEditor,picker地址选择器,progressview进度条,gradient颜色的渐变,badge,Tabview(类似oc里的tabbar),onopenurl,DatePicker,contextMenu,Mapview(地图),List列表(类似oc里的tableview),Form(表单)(数据少可以用Form,列表内就用List),scrollview,Grid(类似oc里的UIcolllectionview),Videoplayer,NavigationView(可以进行点击(navigationLink)),Alert弹框,toolbar,fullScreenCover(类似oc里的莫态势图),controlGroup,alignment(对其),positon(是指中心点位置)

    @state进行特定的刷新(和flutter里的provider很像)

    VStack里最多有10个view

    UIkit进行布局,坐标系原点在左上角。swiftUI是弹性布局,没有坐标系概念

    HStack和VStack进行弹性布局的一些容器

    lazyVStack(可以使用懒加载)也是容器

    苹果官方说了两种时候其不起作用:
    1)lazyview的内容,超出了这个frame的任何边界
    2)包含lazyview的视图,显式的设置他的frame

    下面的lazyVStack需要配合foreach,scrollview使用才会起到一个懒加载的效果,不会重复的去创建


    7471669805469_.pic.jpg

    viewBuilder实现一个闭包,返回一个范型(可以是view,label等等)

    swiftUI里的状态改变

    1)@State属性包装器
    将@State用于属于单个视图的简单属性。通常应将其标记为私有。
    @State不适合在对象之间进行传递

    7481669808457_.pic.jpg

    2)@ObservedObject
    对于更复杂的属性-当您要使用的自定义类型可能具有多个属性和方法,或者可能在多个视图之间共享时,通常会使用@ObservedObject。

    这与@State非常相似,不同之处在于,我们现在使用的是外部引用类型,而不是简单的本地属性(例如字符串或整数),与@ObservedObject一起使用的任何类型都应符合ObservableObject协议

    3)@EnvironmentObject
    还有另一种可以使用的属性包装器,即@EnvironmentObject。这个值可通过应用程序本身提供给视图,它是每个视图都可以读取的共享数据。因此,如果您的应用程序具有一些重要的模型数据,所有视图都需要读取这些数据,则可以将其从一个视图到另一个视图,或者只是将其置于每个视图都可以即时访问它的环境中。

    当您需要在应用程序中传递大量数据时,可以将@EnvironmentObject视为一种极大的便利。由于所有视图都指向同一个模型,因此,如果一个视图更改了模型,则所有视图都会立即更新-这样就不会冒着使应用程序的不同部分不同步的风险

    4)@Binding

    但是与@State区别在于@Binding用于不同视图之间的参数传递,@Binding 和@ObservedObbjecg一样都是传递引用。

    struct和class区别

    struct是值类型,值类型的变量包含数据,会进行值copy,存储在栈中

    class是引用类型,引用类型的变量,存储对他们的数据引用

    \.self的使用

      当一个对象遵从于Identifiable时,SwiftUI会自动使用它的id来进行“唯一化“(可以理解为一种“ForEach”一样的遍历);但是当我们没让对象遵从于Identifiable时,我们也可以用一个我们知道是唯一的的key path进行排序(如书籍的ISBN号);当所有值都不一定是唯一的时,我们就会使用\\.self。
    
    在Swift中被称为“关键路径”(key path),可以用于在另一个对象上指定VAR。
    

    首先,\.self可以用来遍历一些简单的结构:

      当我们把\.self作为一个标识符(identifier)——一个struct就是一个struct,它其中只存着内容,并没有一个识别码一样的identification information,所以\.self其实给struct中的每一组值都设立了一个哈希值,并用这个独一无二的哈希值进行识别以及遍历(ForEach)。
    
    7491669812631_.pic.jpg

    @Appstorage使用

    其是一个全局的存储

    @Appstorage类似oc里的nsuserdefault,数据存储。使用方法和state一样
    当值改变时候其会自动存储,轻量级的存储

    7511669813238_.pic.jpg

    @Scenestorage使用

    只能用到view上面 (和@Appstorage的区别)
    @Scenestorage也是数据的存储,其是swiftUI接管的

    7521669813345_.pic.jpg

    ObservableObject的使用

    下面首先是定义一个ObservableObject的协议,然后用@Published进行一个修饰,然后运行后模拟器上的值会自加

    7531669813811_.pic.jpg

    willset的使用

    其是进行将要变化的时候处理


    7541669814053_.pic.jpg

    @environmentObject的使用

    可以通过多个界面进行传值使用,可以进过跳页面传数据

    7561669814607_.pic.jpg

    @UIViewcontroller的使用
    在使用的时候,因为swiftUI没有controller的概念,其都是view,所以我们需要通过UIViewControllerRepresentable这个协议把controller变成view,通过这个协议也可以使得swiftUI界面跳转到controller界面

    7571669815010_.pic.jpg

    ViewModifier的使用

    ViewModifier就是属性修饰器,其可以把许多相同的属性写在viewModifier里,然后供view使用。

    7581669816344_.pic.jpg

    响应式编程Conbine框架的使用

    7601669818130_.pic.jpg 7611669818207_.pic.jpg

    Future的使用和Promise的使用

    Future遵守Publisher协议
    下面是官方Future源码

    final public class Future<Output, Failure> : Publisher where Failure : Error {

    /// A type that represents a closure to invoke in the future, when an element or error is available.
    ///
    /// The promise closure receives one parameter: a `Result` that contains either a single element published by a ``Future``, or an error.
    public typealias Promise = (Result<Output, Failure>) -> Void
    
    /// Creates a publisher that invokes a promise closure when the publisher emits an element.
    ///
    

    /// - Parameter attemptToFulfill: A Future/Promise that the publisher invokes when the publisher emits an element or terminates with an error.
    public init(_ attemptToFulfill: @escaping (@escaping Future<Output, Failure>.Promise) -> Void)

    /// Attaches the specified subscriber to this publisher.
    ///
    /// Implementations of ``Publisher`` must implement this method.
    ///
    /// The provided implementation of ``Publisher/subscribe(_:)-4u8kn``calls this method.
    ///
    /// - Parameter subscriber: The subscriber to attach to this ``Publisher``, after which it can receive values.
    final public func receive<S>(subscriber: S) where Output == S.Input, Failure == S.Failure, S : Subscriber
    

    }
    它包含一个Promise类型和一个带有@escaping闭包的初始化函数。

    Future和PassthroughSubject、CurrentValueSubject一样,是一个类,不同的是Future实现的是Publiser协议,而PassthroughtSubject和CurrentValueSubject实现的是Subject协议,所以后两个可以使用send方法,而Future不能。

    promise使用

    Promise是Future的最终结果。就像英文名所表现的那样,一个是承诺,一个是未来。我们要用承诺来初始化一个未来。Future和Promise需要配套使用。

    从Future源码可以看到,Future的初始化Init函数中需要实现一个@escaping闭包,闭包类型就是Promise。Promise的本质可以理解为是一个接收单个Result类型参数的闭包。

    let future = Future<Int, Never> { promise in
    // 1
    promise(.success(1))
    }

    上面的代码是Future的初始化及发布的简单过程,注释为1的行,表示的动作就是,我承诺给你一个数据为Int(1),可以是现在就给予,也可以是在未来给予,比如使用DispatchQueue.main.async 包裹 promise

    PropertyWrapper的使用

    7621669819364_.pic.jpg 7631669819870_.pic.jpg

    never是一个无实例类型

    backpressure的使用

    7641669820662_.pic.jpg

    相关文章

      网友评论

          本文标题:第二十五篇:SwiftUI使用

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