打通SwiftUI任督二脉

这篇具有很好参考价值的文章主要介绍了打通SwiftUI任督二脉。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

打通SwiftUI任督二脉

序言

开年的第一篇文章,今天分享的是SwiftUI,SwiftUI出来好几年,之前一直没学习,所以现在才开始;如果大家还留在 iOS 开发,这们语言也是一个趋势; 目前待业中.... 不得不说已逝的2023年,大家开始都抱着一解封,经济都会向上转好,可是现实不是我们想象那样;目前我也在学习 SwiftUI,并且努力找工作中....;至于 2024 年经济如何,咱们作为老百姓在大环境和全球经济影响下;坦然面对,提升自己。 这里不得不说国人坚韧不拔的精神。“卷” -- 努力吧Coding人

SwiftUI体验

Xcode创建项目之后出现工程默认创建的UI界面;如下

打通SwiftUI任督二脉

一开始心里对自己说:"SwiftUI作为iOS开发新的UI体系,为啥初创的项目这么多代码,给初学者看到,一种压迫感,心想这语法好复杂,不想学了";不管你是不是这样心里,我刚开始看见,这么一坨代码,没什么心思,于是索性删掉;按自己能理解学习的方式来操作;于是做了简化:

import SwiftUI
import SwiftData

struct ContentView: View {
   
    var body: some View {
        Text("hello,word")
    }
}

#Preview {
    ContentView()
        .modelContainer(for: Item.self, inMemory: true)
}

关键字 some

关键字some啥玩意儿,完全陌生;先看看View;点击进入源码结构查看:

@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
public protocol View {

    /// The type of view representing the body of this view.
    ///
    /// When you create a custom view, Swift infers this type from your
    /// implementation of the required ``View/body-swift.property`` property.
    associatedtype Body : View

    @ViewBuilder @MainActor var body: Self.Body { get }
}

一堆英文注解估计大家不喜欢看,我就没贴出来了;简单来说:
View 是一个泛型协议,它定义了所有视图类型需要遵循的接口,通过some修饰;表示 "我返回一个满足View 协议的某种类型"。some关键字告诉 Swift,虽然我们知道body必须返回一个View,但我们不确定具体是哪种 View(例如,TextImageVStack 等)。

协议里有一个associatedtypebody,其实这种协议就是当作约束形式使用;只要遵守这种协议编译器每次闭包中返回的一定是一个确定,遵守View协议的类型。

那么苹果工程师利用Swift5.1 Opaque return types特性,开发者提供了一个灵活的开发模式,抹掉了具体的类型,不需要修改公共API来确定每次闭包的返回类型,也降低了代码书写难度。(学学苹果那些大神思想,不错)

在来看看Preview

struct ContentView_Previews:PreviewProvider{
    static var previews: some View{
        ContentView()
        
    }
}

PreviewProvider就一个协议类,它的额作用提供swiftUI不用运行,就能直接看到UI渲染变化,我觉得这个挺好,减少开发人员对UI运行测试次数和时间,而previews就是一个静态属性,返回一个 View 对象,用于在预览面板中展示。

@State属性包装器

@State属性包装器解决UI界面上,数据同步以及及时刷新的功能。一般来说数据更新完,界面 UI 同时更新。在 SwiftUI里面,视图中声明的任何状态、内容和布局,源头一旦发生改变,会自动更新视图,因此,只需要一次布局,这个时候出现了@State,它来解决与UI之间数据状态问题。

它的概念就是:@State 是一个属性包装器(property wrapper),用于声明状态属性(state property)
当状态属性发生变化时,SwiftUI 会自动更新视图以反映最新的状态。

属性的值被存储在特殊的内存区域中,这个区域与 View struct 是隔离的 至于被它修饰的属性内存存储与分布现在无从得知,还没学习到那么深入,这事儿慢慢来,不是一天两天的,先上个代码看看它怎么使用的:

import SwiftUI

struct StateBootcamp: View {
    
    @State var bgkColor:Color = Color.blue
    @State var cut:Int = 0
    
    var body: some View {
        
        ZStack{
            
            bgkColor
                .ignoresSafeArea(.all)
            
            VStack(spacing: 20){
                
                Text("Hello, World!")
                    .font(.title)
                
                Text("count:\(cut)")
                    .font(.largeTitle)
                
                HStack(spacing: 20){
                    Button("Button01") {
                        cut+=1
                        bgkColor = Color.red
                    }
                    .font(.title)
                    .foregroundColor(.white)
                    
                    Button("Button02") {
                        cut-=1
                        bgkColor = .purple
                    }
                    .font(.title)
                    .foregroundColor(.white)
                }
                Button("默认"){
                    cut=0
                    bgkColor = .blue
                }
                .font(.title)
                .foregroundColor(.white)
            }
        }
    }
}

#Preview {
    StateBootcamp()
}

其实一看代码,就一幕了然,知道它的使用与作用;如果你写过swift代码,这些东西很好理解,但是只会OC,那么我建议你学习下swift;在来看swiftUI语法糖才更好理解。

在看看源码:

@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
@frozen @propertyWrapper public struct State<Value> : DynamicProperty {
    public init(wrappedValue value: Value)
    public init(initialValue value: Value)
    public var wrappedValue: Value { get nonmutating set }
    public var projectedValue: Binding<Value> { get }
}


@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
extension State where Value : ExpressibleByNilLiteral {

    /// Creates a state property without an initial value.
    ///
    /// This initializer behaves like the ``init(wrappedValue:)`` initializer
    /// with an input of `nil`. See that initializer for more information.
    @inlinable public init()
}


可以看到State是一个结构体,由@propertyWrapper包装的。@propertyWrapper是属性包装器。property wrapper 做的事情大体如下:

-   为底层的存储变量`State<Int>`自动提供一组 **getter** 和 **setter** 方法,结构体内保存了`Int`的具体数值;

-   在 body 首次求值前,将`State<Int>`关联到当前`View`上,为它在堆中对应当前`View`分配一个存储位置。

-   为`@State`修饰的变量设置观察,当值改变时,触发新一次的`body`求值,并刷新 UI。

SwiftUI基础组件

Spacer垫片:先贴贴代码

import SwiftUI

struct SpacerBootcampDemo: View {
    var body: some View {
        Text("Spacer UP")
            .font(.largeTitle)
        
        Spacer()
            .frame(width: 37)
            .background(.blue)
        
        Text("Spacer Down")
            .font(.largeTitle)
        
    }
}

#Preview {
    SpacerBootcampDemo()
}

在看看效果图:

打通SwiftUI任督二脉

总结:Spacer 是一个灵活的空间视图,它的主要作用是在布局中自动调整自身的高度和宽度,以填满特定的空间;简单来说,它就是一个垫片,调整自身视图的高度,如果它周围有其他视图,也会受到Spacer影响。

ScrollView 如果你之前使用UIkit框架开发,在用SwiftUI,一下有点不适应,代码和之前的 UIkit 开发模式不太一样,但是大大缩短UI编写时间;先上代码:


import SwiftUI

struct ScollViewBootcamp: View {
    
    var body: some View {
        
        ScrollView{
            LazyVStack{
                ForEach(0..<20){
                    (idx) in
                    
                    VStack {
                        
                        Text("Hello, World!")
                            .font(.title)
                            .foregroundStyle(.white)
                            .frame(width: UIScreen.main.bounds.width-20,height: 350)
                            .background(Color.init(cgColor: CGColor(red: CGFloat.random(in: 0..<215)/255.0, green: CGFloat.random(in: 0..<235)/255.0, blue: CGFloat.random(in: 0...247)/255.0, alpha: 0.9)))
                            .clipShape(RoundedRectangle(cornerRadius: 10))
                        
                        Rectangle()
                            .fill(Color.init(cgColor: CGColor(red: CGFloat.random(in: 0...187)/255.0, green: CGFloat.random(in: 0..<210)/255.0, blue: CGFloat.random(in: 0...237)/255.0, alpha: 0.9)))
                            .frame(width: UIScreen.main.bounds.width-20,height: 530)
                            .clipShape(RoundedRectangle(cornerRadius: 10))
                        
                        
                        ScrollView(.horizontal,showsIndicators: false,content: {
                            LazyHStack{
                                ForEach(0..<10){
                                    idx in
                                    Rectangle()
                                        .fill(Color.init(cgColor: CGColor(red: CGFloat.random(in: 0...167)/255.0, green: CGFloat.random(in: 0...131)/255.0, blue: CGFloat.random(in: 0...89)/255.0, alpha: 0.9)))
                                        .frame(width: 200, height: 300)
                                        .clipShape(RoundedRectangle(cornerRadius: 10))
                                    
                                }
                            }
                        })
                        .padding(.leading,10)
                        .padding(.trailing,10)
                        
                        
                    }
                }
            }
            .frame(width:UIScreen.main.bounds.width)
            
        }
    }
}


#Preview {
    ScollViewBootcamp()
}

上图看看效果:

打通SwiftUI任督二脉

简单几句就能实现**ScrollView**的滑动效果;非常方便。

LazyVGrid 网格布局,先上代码:

import SwiftUI

struct GridViewBootcamp: View {
    
    let columns=[
        GridItem(.flexible(),spacing: 6   ,alignment: .center),
        GridItem(.flexible(),spacing: 6    ,alignment: .center),
        GridItem(.flexible(),spacing: 6  ,alignment: .center),
    ]
    
    var body: some View {
        
        ScrollView{
            LazyVGrid(columns: columns,
                      alignment: .center,
                      spacing: 6,
                      pinnedViews: [.sectionHeaders],content:
                        {
                Section(content: {}, header: {
                    Text("section header 一")
                        .font(.largeTitle)
                        .foregroundStyle(.blue)
                        .frame(width: UIScreen.main.bounds.width,height: 100,alignment: .leading)
                })
                
                ForEach(0..<41){
                    index in
                    Rectangle()
                        .fill(Color.init(cgColor: CGColor(red: CGFloat.random(in: 0..<255)/255.0, green: CGFloat.random(in: 0..<255)/255.0, blue: CGFloat.random(in: 0...255)/255.0, alpha: 0.9)))
                        .frame(height: 50)
                }
                
                //-------
                Section {
                    
                } header: {
                    Text("section header 二")
                        .font(.largeTitle)
                        .foregroundStyle(.blue)
                        .frame(width: UIScreen.main.bounds.width,alignment: .leading)
                    
                }
                
                ForEach(0..<41){
                    index in
                    Rectangle()
                        .fill(Color.init(cgColor: CGColor(red: CGFloat.random(in: 0..<255)/255.0, green: CGFloat.random(in: 0..<255)/255.0, blue: CGFloat.random(in: 0...255)/255.0, alpha: 0.9)))
                        .frame(height: 50)
                }
                
            })
            .padding(.leading,6)
            .padding(.trailing,6)
            .background(.gray)
        }.background(.blue)
    }
}

#Preview {
    GridViewBootcamp()
}

效果图:

打通SwiftUI任督二脉

总结:LazyVGrid大家看到这个单词有个Lazy懒加载的意思,它的内部加载item简单来说,就是当视图需要时,才会执行item内容渲染功能,展示UI上。也就这点注意。

SafeArea安全区域:

import SwiftUI

struct SafeAreaBootcamp: View {
    var body: some View {
        GeometryReader{
            src in
            Rectangle()
                .fill(.blue)
                .frame(maxWidth: .infinity,
                       maxHeight: .infinity)
        }
    }
}

#Preview {
    SafeAreaBootcamp()
}

效果图:

打通SwiftUI任督二脉

可以看到上下边距存在安全区域的,如果禁用安全区域,使用 ignoresSafeArea(.all) 可以去掉。

代码如下:

打通SwiftUI任督二脉

最后说说SwiftUI函数表达

上上代码:


import SwiftUI

struct ExtractFunctionsBootcamp: View {
    
    @State var bgc:Color = .red
    
    var body: some View {
        normolView
    }
    
    var normolView : some View {
        setUI()
    }
    
    func chageColor() -> Void {
        self.bgc = .red
    }
    
    func setUI()->some View {
        return ZStack{
            
            bgc
                .ignoresSafeArea(.all)
            
            VStack(spacing: 20, content: {
                
                Text("Hello, World!")
                    .font(.largeTitle)
                
                Button(action: {
                    bgc = .brown
                }, label: {
                    Text("Button")
                        .font(.largeTitle)
                        .foregroundStyle(.white)
                })
                
                Button {
                    self.chageColor()
                } label: {
                    Image(systemName: "button.horizontal.top.press")
                        .resizable()
                        .foregroundColor(.white)
                        .aspectRatio(contentMode: .fill)
                        .frame(width: 50,height: 50)
                }
            })
        }
    }
}


#Preview {
    ExtractFunctionsBootcamp()
}

其实函数表达跟我们swift语法糖一样;func 命名;这点和swift语法糖没什么区别。

总结(说说我的感想)

优点:

简洁性:Swift,SwiftUI语法简洁,编写代码变得更加容易和快速。

安全性:是一种类型安全的编程语言,可以在编译时检测类型错误,这帮助我们避免许多常见的错误,提高代码的质量和可靠性。

互操作性:它与Objective-C语言无缝互衔接,是的OC与swift代码混编变的更加便捷。

说完优点在说缺点

功能限制:虽然SwiftUI提供了许多常见的UI组件,但与UIKit相比,功能仍然相对有限。在某些复杂的界面需求下,可能需要使用UIKit来实现。

错误提示不明确:有时SwiftUI, SwiftUI的错误提示可能不够明确,导致难以定位问题。

UIkit与SwiftUI缺乏无缝兼容:两者兼容性不够理想,这在业务开发中,你可能才能发现。

目前苹果与市面大量应用也在使用Swift,SwiftUI开发应用,这们语言在应用中占有读也是成倍增长。文章来源地址https://www.toymoban.com/news/detail-837800.html

路漫漫其修远兮,吾将上下而求索

后续更新中..........

到了这里,关于打通SwiftUI任督二脉的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 接口自动化测试-Requests模块实战详解,一篇打通...

    什么是requests? requests是一个很实用的Python HTTP客户端库,编写爬虫和测试服务器响应数据时经常会用到, Requests是Python语言的第三方的库,专门用于发送HTTP请求 下载 请求方式 1、get请求 2、post请求 3、响应的内容 4、超时设置 5、添加请求头信息

    2024年02月13日
    浏览(40)
  • 一篇打通,性能测试与性能测试瓶颈评估,测试之道...

    什么是性能测试? 性能测试是验证软件系统是否能够达到用户提出的性能指标,同时发现软件系统中存在的性能瓶颈,优化软件,最后起到优化系统的目的。 概括为三个方面: 应用在客户端性能的测试; 应用在网络上性能的测试; 应用在服务器端性能的测试; 通常情况下

    2024年02月10日
    浏览(37)
  • 【性能测试】资深老鸟带你,一篇打通负载与压力测试的区别...

    负载测试 是通过逐步增加系统负载,测试系统性能的变化,并最终确定在满足性能指标的情况下,系统所能承受的最大负载量的测试; 压力测试 是通过逐步增加系统负载,测试系统性能的变化,并最终确定在什么负载条件下系统性能处于失效状态,并以此来获得系统能提供

    2024年02月03日
    浏览(51)
  • Postman接口自动化测试实战,从0到1一篇彻底打通...

    postman中的测试 在postman中,可以通过添加脚本到请求当中,来使用动态变量、在请求之间传递数据以及编写测试。写在Pre-request Scripttab中的代码会在请求发送之前执行,而写在Teststab中的代码会在响应到达之后执行。 postman测试用的语言是JavaScript。 所以对于前端开发者来说几

    2024年02月04日
    浏览(32)
  • 【软件测试】Git详细-获取Git仓库,全网最全一篇打通...

    官方提供了两种获取Git仓库的方法。 第一种是在本地现有项目目录下导入所有文件到Git中; 第二种就是从Git仓库中clone项目到本地; 在现有目录中初始化仓库 如果是window的话,进入本地项目目录后,右键即可看到 git-bash ,打开git操作界面,输入命令 然后会看到目录下多了

    2024年02月07日
    浏览(31)
  • 爆肝整理,Python自动化测试-Pytest参数化实战封装,一篇打通...

    参数化? 通俗点理解就是,定义一个测试类或测试函数,可以传入不同测试用例对应的参数,从而执行多个测试用例。 例如: 对登录接口进行测试,假设有3条用例,正确账号正确密码登录、正确账号错误密码登录、错误账号正确密码登录,那么我们只需要定义一个登陆测试

    2024年02月13日
    浏览(55)
  • 一篇关于计算机网络原理的文章

    计算机网络原理是指计算机网络的基本概念、协议以及通信技术等方面的知识。 了解计算机网络原理对于我们使用互联网、编程开发以及网络安全等方面都极为重要。 在本文中,将介绍计算机网络原理的基本内容。 一、计算机网络的基本概念 计算机网络是指将分布在不同地

    2023年04月23日
    浏览(90)
  • AI辅写疑似度怎么查看:一篇自媒体文章

    大家好,今天来聊聊AI辅写疑似度怎么查看:一篇自媒体文章,希望能给大家提供一点参考。 以下是针对论文AI辅写率高的情况,提供一些修改建议和技巧,可以借助此类工具: 还有: AI辅写疑似度怎么查看:一篇自媒体文章 随着人工智能技术的不断发展,AI辅写已经成为写

    2024年02月20日
    浏览(49)
  • 【科普向】LaTeX简介(一篇极简的 LaTeX 介绍文章)

    我们平时在word里新建一个doc(x)文件后,输入内容,调整页边距、字体大小、行间距等待,然后交给打印机打印就可以了。 如果你写了一篇关于新疆棉花的文章,2000字,在word里调整很快就可以得到你想要的效果。 但如果你想把自己记下的关于矩阵乘法的笔记打印下来,因为

    2024年02月04日
    浏览(41)
  • R语言复现一篇6分的孟德尔随机化文章

    上一期我们对孟德尔随机化做了一个简单的介绍,今天我们来复现一篇6分左右的使用了孟德尔随机化方法的文章,文章的题目是:Mendelian randomization analysis does not reveal a causal influence of mental diseases on osteoporosis(孟德尔随机分析没有揭示精神疾病对骨质疏松症的因果影响) 这

    2024年02月13日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包