前言:
Swift知识点,大至看完了,公司项目是Swift语言写的,后续苹果新出的SwiftUI,也需要学习一下
不知觉间,SwiftUI是19年出的,现在24年,5年前的东西了
学习的几个原因:
- 项目工程里面有一部分SwiftUI的代码;
- 跟上脚步,学习新知识,给自己加分;
- Vision AR的开发语言是SwiftUI,以后想开发或者接触这些新东西,语言需要提前准备
这次学习,参考的是:B站SwiftUI Bootcamp (Beginner Level),一个歪果仁的课,讲的很不错~
struct ContentView: View {//xxx
}
定义一个ContentView,继承View?
不对,联想swift,struct没有继承,难道swiftUI的结构体可以继承???
点击进去,看到View的定义:
public protocol View {associatedtype Body : View@ViewBuilder @MainActor var body: Self.Body { get }
}
原来,View被定义为了protocol协议
struct可以遵守协议,因此,上述写法不是继承,而是遵守协议。
UI介绍
Text介绍
import SwiftUI
import SwiftDatastruct ContentView: View {@Environment(\.modelContext) private var modelContext@Query private var items: [Item]var body: some View {VStack {Image("dinner").resizable().aspectRatio(contentMode: .fit)Text("今天吃什么?").font(.largeTitle)//字体大小.fontWeight(.semibold)//字体样式.bold()//粗体.underline(true, color: Color.red)//下划线.italic()//斜线.strikethrough(true, color: Color.green)//穿过线.foregroundStyle(.purple)//颜色//原来那一套,size设置字体大小,weight设置是bold还是什么样式,design设置自己的字体Text("告诉我!").font(.system(size: 40, weight: .bold, design: .default))Text("NSOperation 需要配合 NSOperationQueue 来实现多线程。因为默认情况下,NSOperation 单独使用时系统同步执行操作,配合 NSOperationQueue 我们能更好的实现异步执行。").multilineTextAlignment(.trailing).kerning(1)//左右间距调大
// .baselineOffset(20)//行间距调大:每一行,下面留20间距.baselineOffset(-20)//行间距调大:每一行,上面留20间距.frame(width: 200, height: 200, alignment: .center)//frame大小.background(.gray)//背景颜色}}
}#Preview {ContentView().modelContainer(for: Item.self, inMemory: true)
}
形状UI介绍
Color介绍
var body: some View {RoundedRectangle(cornerRadius: 25.0)//填充颜色//.fill(Color.red).fill(//Color(UIColor.blue)Color("CustomColor")//自定义颜色).frame(width: 250, height: 100)//阴影.shadow(color: .gray, radius: 20, x: 0, y: 1)}
渐变色
Frame
Background 和 OverLay
//
// BackgroundAndOverlayView.swift
// SwiftUI_Bootcamp_Learn_Code
//
// Created by SYZ on 2024/5/30.
//import SwiftUIstruct BackgroundAndOverlayView: View {var body: some View {VStack{Text("Hello, World!-1").background(.red)Text("Hello, World!-2").background(LinearGradient(gradient: Gradient(colors: [Color.red, Color.blue]), startPoint: .leading, endPoint: .trailing))Text("Hello, World!-3").background(Circle().fill(Color.blue))Text("Hello, World!-4").frame(width: 120, height: 120).background(Circle().fill(Color.blue)).frame(width: 130, height: 130).background(){Circle().fill(Color.red)}.padding(EdgeInsets(top: 0, leading: 0, bottom: 50, trailing: 0))Text("Hello, World!-5").background(Circle().fill(Color.blue).frame(width: 120, height: 120, alignment: .bottom)).background(){Circle().fill(Color.red).frame(width: 130, height: 130, alignment: .bottom)}.padding(EdgeInsets(top: 0, leading: 0, bottom: 105, trailing: 0))Text("Hello, World!-6").background(Circle().fill(LinearGradient(gradient: Gradient(colors: [Color.red, Color.blue]), startPoint: .leading, endPoint: .trailing)).frame(width: 120, height: 120)).background(){Circle().fill(Color.red).frame(width: 130, height: 130)}.padding(EdgeInsets(top: 0, leading: 0, bottom: 60, trailing: 0))Circle().fill(.pink).frame(width: 100, height: 100).overlay(Text("1").font(.largeTitle).foregroundColor(.white))//可以看出,添加的背景色,在后面,而使用overlay的Text在前面.background(Circle().fill(.purple).frame(width: 120, height: 120)).padding(EdgeInsets(top: 0, leading: 0, bottom: 40, trailing: 0))Image(systemName: "heart.fill").font(.system(size: 40)).foregroundColor(.white).background(Circle().fill(LinearGradient(gradient: Gradient(colors: [Color.red, Color.blue]), startPoint: .leading, endPoint: .trailing)).frame(width: 100, height: 100).shadow(color: Color.gray, radius: 10, x: 0.0, y: 10).overlay(Circle().fill(.blue).frame(width: 35, height: 35).overlay(Text("5").font(.headline).foregroundStyle(.white).shadow(color: .gray, radius: 10, x: 5.0, y: 5.0)), alignment: .bottomTrailing))}}
}#Preview {BackgroundAndOverlayView()
}
Stack
VStack有两种创建方式:
VStack{}
VStack(alignment: .center, spacing: nil, content:{ })
第一种创建的时候,spacing是nil,有个8的大小,如果想不要间距,改为0即可
VStack:垂直方向
HStack:水平方向
ZStack:bottom-top方向
Padding And Spacer
Padding解决两两之间的间隔,或者本身自己预留 的间隔
Spacer主要解决平分等问题
ScrollView
Grid
struct LearnGridView: View {let columns: [GridItem] = [//.fixed:固定大小GridItem(.fixed(50), spacing: nil, alignment: nil),//代表一列GridItem(.fixed(150), spacing: nil, alignment: nil),//.flexible:灵活的//整分屏幕:如果只有一个,则整屏;如果有两个,则半屏;依次类推//spacing:左右间距,即列间距GridItem(.flexible(), spacing: nil, alignment: nil),GridItem(.flexible(), spacing: nil, alignment: nil),GridItem(.flexible(), spacing: nil, alignment: nil),//.adaptive:自适应,以最小值为准,尽量多放GridItem(.adaptive(minimum: 50, maximum: 120), spacing: nil, alignment: nil),GridItem(.adaptive(minimum: 150, maximum: 120), spacing: nil, alignment: nil),]var body: some View {ScrollView{//LazyVGrid没有滚动属性,需要滚动的话,外面要包一个ScrollViewLazyVGrid(columns: columns,//居中alignment: .center,//上下间距,即行间距,默认是6spacing: 1,//.sectionHeaders:头,划过去不消失,还在前面显示pinnedViews: [.sectionHeaders],content: {ForEach(0..<70) { index inRectangle().frame(height: 50).foregroundColor(.red)}}).background(.gray)}}
}
SafeArea
struct SafeView: View {var body: some View {Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/).background(.red).frame(width: .infinity, height: .infinity)Rectangle().frame(width: .infinity, height: .infinity).foregroundColor(.red)//忽略安全区,本来不到顶,现在忽略顶部的安全区,则直接到顶.ignoresSafeArea(.all, edges: .bottom)//忽略所有的安全区.ignoresSafeArea()ScrollView{VStack{Text("This is title").font(.largeTitle).frame(maxWidth: .infinity, alignment: .leading)ForEach(0..<10){ index inRoundedRectangle(cornerRadius: 25).fill(.white).frame(height: 150).shadow(radius: 10).padding()}}}.background(.red)}
}
Button
state
只需要在监听的var变量前,加上@state即可。告诉这个属性是可观察的,后面有地方改变,则所有用到的地方,都会被改变
太6了
extractSubView
import SwiftUIstruct LearnExtractSubView2: View {var body: some View {ZStack{Color.blue.ignoresSafeArea()contentLay}}var contentLay: some View {HStack{MyItem(count: 1, title: "apple", myColor: .red)MyItem(count: 19, title: "orange", myColor: .orange)MyItem(count: 33, title: "banana", myColor: .yellow)}}
}struct LearnExtractSubView2_Previews: PreviewProvider {static var previews: some View {LearnExtractSubView2()}
}struct MyItem: View {let count: Intlet title: Stringlet myColor: Colorvar body: some View {VStack{Text("\(count)")Text(title)}.padding()//增加间距.background(myColor).cornerRadius(10)//加圆角}
}