SwiftUI教程系列文章汇总
本文紧张陈诉常见的View和Modifiers的熟悉和利用
紧张内容:
1. 先容
SwiftUI通过View视图搭建界面,利用Modifiers修饰器来修饰视图。体系提供了大量的视图和修饰器,而且还可以让我们自定义修饰器。
既可以手动写,也可以直接拖出到代码区大概预览区。这三种方式的效果都是一样的。
表现图:
2、Text
体现一行或多行的只读文本视图,可以类似于OC中的label
//1、TextText("我是一个Text,**Markdown语法加粗了**").foregroundColor(.red)
- 可以利用modifiers举行修饰视图。
- 也可以利用Markdown语法举行修饰
3、Label
Label用户界面项的尺度标签,包罗图片和标题
//2、LabelVStack { //用户界面项的尺度标签,由带有标题的图标构成。 //labelStyle设置label样式 Label("Lightning", systemImage: "bolt.fill") Label("Lightning", systemImage: "bolt.fill") .labelStyle(.iconOnly) Label("Lightning", systemImage: "bolt.fill") .labelStyle(.titleOnly) //自定义label样式 Label("Lightning", systemImage: "bolt.fill")// .labelStyle(.makeBody(RedBorderedLabelStyle)) //多label同一样式 VStack { Label("Rain", systemImage: "cloud.rain") Label("Snow", systemImage: "snow") Label("Sun", systemImage: "sun.max") } .labelStyle(.iconOnly) //组合标签 Label { Text("wenyi") .font(.body) .foregroundColor(.primary) Text("ya") .font(.subheadline) .foregroundColor(.secondary) } icon: { Circle() .fill(.orange) .frame(width: 44, height: 44, alignment: .center) .overlay(Text("圆")).foregroundColor(.white) }}说明:
- 正常情况包罗了图标和标题
- 也可以设置labelStyle,设置为只体现图标或标题
- labelStyle也可以直接设置到外部视图上,可以作用到内部全部的label上
- 我们还可以给一个label自由组合文本和图标。
- 上文中自定义一个Label,包罗两个文本和一个图标
- 还可以自定义labelStyle
4、Button
//Button,笔墨和相应Button { print("button点击相应")} label: { Text("我是按钮")}说明:
- 按钮可以添加action举行相应,举行打印。
- 尚有设置label,label上设置图标和Text。
- 这里仅设置了Text。
5、Link
通过提供目标URL和标题来创建链接
//LinkLink(destination: URL(string:"https://www.baidu.com/")!) { Text("Link")} Link("View Our Terms of Service", destination: URL(string: "https://www.example.com/TOS.html")!) //设置OpenURLActionLink("Visit Our Site", destination: URL(string: "https://www.example.com")!) .environment(\.openURL, OpenURLAction { url in print("Open \(url)") return .handled })说明:
- destination参数用来设置URL
- 还必要设置标题用来形貌URL
- 通过设置OpenURLAction覆盖默认的URL打开的方式
6、Image
//直接拿Assets中图片Image("wy") .resizable() .aspectRatio(contentMode: .fit)// UIImage.init(named: "wy.png") //加载网络图片// AsyncImage.说明:
- 直接利用Image就可以拿到图片了,这里只能利用Assets中的图片
- 如果想要利用文件路径下的图片,必要利用UIImage
- 网络图片利用AsyncImage,注意要设置占位图片或占位笔墨,网络图片有大概会失败
7、TimelineView
根据时间表更新的视图
//定义struct TimelineView<Schedule, Content> where Schedule : TimelineSchedule//TimelineViewTimelineView(.periodic(from: Date.now, by: 1.0)) { context in Text(context.date.description).font(.title)}说明:
- 两个参数,一个是筹划表,一个是实行的内容
- 在这里时间表是从当前时间,每1秒开始实行一次
- 实行的内容就是打印当前时间
- 因此知道个视图可以做定时器利用
- 可以传入三种参数
- .everyMinute 每分钟
- .periodic(from: , by: )从开始时间开始,多久开始更新
- .explicit(更新次数)
8、Canvas
绘制图形
//CanvasCanvas { context, size in context.stroke(Path(ellipseIn: CGRect(origin: .zero, size: size)),with: .color(.blue), lineWidth: 3)}.frame(width: 100, height: 50, alignment: .center).border(.red,width: 2)说明:
- Canvas就是一个画布。我们可以对画布举行绘制丰富和动态的2D图形
- Canvas将GraphicsContext转达给用于实行即时模式绘图操纵的闭包
- 通过闭包举行绘制,传入两个参数,一个是绘制的内容,一个是绘制的巨细
- Canvas还转达一个CGSize值,您可以利用它来定制您绘制的内容
利用画布在SwiftUI视图中绘制丰富和动态的2D图形。画布将GraphicsContext转达给用于实行即时模式绘图操纵的闭包。画布还转达一个CGSize值,您可以利用它来定制您绘制的内容。比方,你可以利用上下文的stroke(_:with:lineWidth下令来绘制一个Path实例:
9、TextEditor
体现可编辑文本界面的控件。相当于UITextView
//TextEditorTextEditor(text: .constant("laceholder")) .frame(width: 100, height: 30, alignment: .center)说明:
- constant可以设置默认值
- frame可以设置TextEditor的宽高,以及对齐方式。
10、TextField
文本输入框
//TextField,预览无法操纵TextField("首字母默认大写", text: $str).frame(width: 100, height: 56, alignment: .center) .textInputAutocapitalization(.never) //主动纠错 .disableAutocorrection(true)// .border(.red, width: 1)// .cornerRadius(20) .overlay{ RoundedRectangle(cornerRadius: 20) .stroke(.red, lineWidth: 10) .padding(-10) } .onSubmit { print("我点击了!") } ....contentShape(Rectangle())//追加热区设置 .onTapGesture { print("tap") //热区 UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) }说明:
- 可以添加.onSubmit来捕捉提交事故
- 点击空缺区域收起键盘
- 设置主动巨细写的场景,好比首字母大写,全部大写,全不大写等等
- 主动纠错默以为false就是会主动纠错
- 直接设置.border设置圆角,只会设置外部的,不会设置内部的,因此必要手动绘制一个图像举行覆盖
- 注意“热区”,只要有内容的区域都属于热区(纵然这里是空缺的),热区在这里不属于空缺区域
- 因此必要追加热区设置.contentShape(Rectangle())
11、ColorPicker
颜色选择器(UIKit没有)
@State var textColor = Color.red//ColorPicker//supportsOpacity是否设置透明度ColorPicker("picker", selection: $textColor, supportsOpacity: false).font(.largeTitle).foregroundColor(textColor)说明:
- 设置Picker的标题,尚有设置一个选取器selection
- 这里拿到的$textColor就是不停革新的颜色
- supportsOpacity是设置是否设置透明度,实在还可以设置Pciker的许多东西
12、Picker
选择器
@State var selectedCity = city.xian//PickerPicker(selection: $selectedCity, label: Text("icker").frame(width: 50, height: 10, alignment: .center)) { Text("taiyuan").tag(city.taiyuan) Text("xian").tag(city.xian) Text("datong").tag(city.datong)}.border(.orange)Text("this city is : \(selectedCity.rawValue)")说明:
- $selectedCity就是获取的值
- 设置多种选择项
13、toolbar
//设置工具栏NavigationView { Text("Hello World!").navigationTitle("navigation") .toolbar { ToolbarItem(placement: .navigationBarLeading) { Button("Edit") {} } ToolbarItem(placement: .navigationBarTrailing) { Button("back") {} } }}说明:
- 设置TollbarItem项是每个按钮
- 有许多样式可以选择
- 不但可以用于导航栏,可以用在恣意的工具栏中
14、ProgressView
进度条视图
//ProgressView// ProgressView(value: /*@START_MENU_TOKEN@*/0.5/*@END_MENU_TOKEN@*/)ProgressView(value: progress, total: 10, label: { Text("WY")}, currentValueLabel: { Text("start")}).progressViewStyle(.circular)Button("加1") { progress += 1}ProgressView().progressViewStyle(.linear)}说明:
- 进度条颜色的设置.tint(.red)
- view的颜色的设置.background(.green)
- 进度条值的设置,默认是0-1,我们可以也可以设置总数
- 空进度条的样式,可以直接设置成ProgressView(),此时是加载图,如果必要设置空进度条,就.progressViewStyle(.linear)
- .progressViewStyle()就可以设置进度条的样式
15、Slider
滑动块
@State private var isEditing = falseSlider( value: $speed, in: 0...100, step: 5 ) { Text("Speed") } minimumValueLabel: { Text("0") } maximumValueLabel: { Text("100") } onEditingChanged: { editing in isEditing = editing }Text("\(speed)") .foregroundColor(isEditing ? .red : .blue)说明:
- 滑动时动态获取到的值是value
- in是设置滑动范围
- step是可以设置整个范围多少中分(可以设置自己的正确度)
- onEidtingChanged是滑动时的相应操纵
- 还可以设置最大范围和最小范围体现
16、Togle
切换按钮,相当于UISwitch
Toggle(isOn: $vibrateOnRing) { Text("Vibrate on Ring")}Toggle("Vibrate on Ring", isOn: $vibrateOnRing)
- Toggle就是切换按钮
- 这两种写法都可以,很简单,末了拿到vibrateOnRing就可以
17、Stepper
当您盼望用户在增长或淘汰值时举行粒度控制时,请利用Stepper控件
//StepperStepper { //左侧文本 Text("Value: \(value) Color: \(colors[value].description)") } onIncrement: {//加操纵 incrementStep() } onDecrement: {//减操纵 decrementStep() } .padding(5) .background(colors[value])//设置颜色//设置范围,且默认加减Stepper(value: $value, in: range, step: step) { Text("Current: \(value) in \(range.description) " + "stepping by \(step)") } .padding(10)
- 可以给Stepper设置点击的效果:
- 默认效果就是举行数值的加减盘算,此时必要设置数值的总数和步长
- 如果自定义效果,就必要设置onIncrement和onDecrement来自定义相应
18、Gradient
图形渐变
代码:
//图形渐变//角渐变AngularGradient(gradient: Gradient(colors: [Color.red, Color.blue,.purple,.red]), center: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/) //椭圆EllipticalGradient(colors:/*@START_MENU_TOKEN@*/[Color.blue, Color.green]/*@END_MENU_TOKEN@*/, center: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/, startRadiusFraction: /*@START_MENU_TOKEN@*/0.0/*@END_MENU_TOKEN@*/, endRadiusFraction: /*@START_MENU_TOKEN@*/0.5/*@END_MENU_TOKEN@*/)//线性LinearGradient(gradient: /*@START_MENU_TOKEN@*/Gradient(colors: [Color.red, Color.blue])/*@END_MENU_TOKEN@*/, startPoint: /*@START_MENU_TOKEN@*/.leading/*@END_MENU_TOKEN@*/, endPoint: /*@START_MENU_TOKEN@*/.trailing/*@END_MENU_TOKEN@*/) //辐射渐变RadialGradient(gradient: /*@START_MENU_TOKEN@*/Gradient(colors: [Color.red, Color.blue])/*@END_MENU_TOKEN@*/, center: .bottomLeading, startRadius: 100, endRadius: 120)19、searchable
//创建一个model项struct ItemModel: Identifiable { var id = UUID() var name: String var detailView: DetailView}//创建一个详情Viewstruct DetailView: View, Identifiable { var id = UUID() var detail: String @State var text = "" var body: some View { VStack (alignment: .leading){ Text(detail).font(.largeTitle).foregroundColor(.gray).bold() .searchable(text: $text){ Text("大同").searchCompletion("大同") Text("太原").searchCompletion("太原") Text("太原").searchCompletion("太原") Text("太原").searchCompletion("太原") Text("太原").searchCompletion("太原") } Spacer() } }}//定义一个数组let datas: [ItemModel] = [ ItemModel(name: "太原", detailView: DetailView(detail: "山西省会")), ItemModel(name: "西安", detailView: DetailView(detail: "陕西省会")), ItemModel(name: "银川", detailView: DetailView(detail: "宁夏省会")), ItemModel(name: "西宁", detailView: DetailView(detail: "青海省会")), ItemModel(name: "呼和浩特", detailView: DetailView(detail: "内蒙省会")), ItemModel(name: "郑州", detailView: DetailView(detail: "河南省会"))]//创建一个viewModel,提供了数组项//而且尚有一个filtedItems用来过滤每一项class ViewModel: ObservableObject { @Published var allItems: [ItemModel] = datas @Published var searchedItem: String = "" var filtedItems: [ItemModel] { searchedItem.isEmpty ? allItems : allItems.filter({ str in str.name.lowercased().contains(searchedItem.lowercased()) }) }}struct ContentView: View { @ObservedObject var vm = ViewModel() var body: some View { NavigationView { List { ForEach(vm.filtedItems) {item in NavigationLink(item.name, destination: item.detailView) } } .navigationTitle(Text("搜刮页面")) .searchable(text: $vm.searchedItem, prompt: "输入您想要搜刮的省会名称") } }}说明:
- 如果给List添加.searchable,必须共同NavigationView
- 给Text添加搜刮框,可以给搜刮框添加可选值,还可以给这些值设置相应
20、List
列表,就是OC中的TableView,是对UITableView的包装
List{ ForEach(todos, id:\.name){ (todo) in Text("wenyi") }}说明:
- List内里设置每一项cell
- 通过ForEach举行循环设置。
- 每个cell体现一个文本"wenyi".
21、TabView
Tab的View,就是之前的tabbar
//TabViewTabView() { Text("Tab Content 1").tabItem { Image(systemName: "person") Text("Tab Label 1") }.tag(1).badge(Text("news")) Text("Tab Content 2").tabItem { Text("Tab Label 2") }.tag(2)}说明:
- 这里设置了两项,每项包罗自己的文本内容,以及item自身的内容
- tabItem可以设置图片和笔墨。
- 还可以设置标志.badge
设置动画效果:
TabView() { Text("Tab Content 1").tabItem { Image(systemName: "person") Text("Tab Label 1") }.tag(1).badge(Text("news")) Text("Tab Content 2").tabItem { Text("Tab Label 2") }.tag(2)}.tabViewStyle(.page).background(.orange)说明:
- item只有两个点
- 此时也可以取消白点(indexDispalyMode: .never)
- 这里的点如果想要设置图片,也是可以的
22、OnOpenURL
用来跳转页面,通过其他APP举行跳转到当前页面
//OnOpenURLstruct ContentView: View { @State var show = true @State var tabSelection = 1 var body: some View { TabView(selection: $tabSelection) { Text("Tab Content 1").tabItem { Image(systemName: "person") Text("Tab Label 1") }.tag(1).badge(Text("news")) Text("Tab Content 2").tabItem { Image(systemName: "person") Text("Tab Label 2") }.tag(2) }.onOpenURL { url in switch url.host { case "tab1": tabSelection = 1 case "tab2": tabSelection = 2 default: show.toggle() } } .sheet(isPresented: $show) { Text("URL参数错误") } }}设置scheme
效果:
说明:
- 给TabView增长一个跳转毗连,可以从外部应用跳转到当前页面
- 必要在info中设置一下scheme
- 如果想要删除URL type中的项,可以在Info.plist中删除,而且重新打开XCode
- .sheet用来弹出文本视图的弹框举行参数错误提示
23、interactiveDismissDisab
克制手势滑动关闭界面,必须加在按钮的背面
Button("Open Sheet") { show.toggle()}.sheet(isPresented: $show) { Button("Close") { show.toggle() } .interactiveDismissDisabled()}说明:
- 给按钮设置克制手势滑动关闭界面。此时就只能通过返回按钮返回。不能左滑返回了。
24、contextMenu
文本菜单
struct ContentView: View { @State var backgroundColor = Color.red @State var isShow = true var body: some View { Text("Hello world~").bold().font(.largeTitle).foregroundColor(.white).background(backgroundColor) .contextMenu (isShow ? ContextMenu{ Button("Red") { backgroundColor = .red } Button("Green") { backgroundColor = .green } Button("Blue") { backgroundColor = .blue } Button { backgroundColor = .yellow } label: { Label("yellow", systemImage: "scribble") } } : nil ) }}说明:
- 给一个view增长菜单选项
- 也可以设置是否体现菜单
- 案例中菜单选项有多个按钮,点击按钮后可以改变配景颜色。
- 配景颜色设置到文本视图中,所以通过点击菜单选项就可以改变文本视图的配景颜色。
25、Menu
菜单视图,可以嵌套
Menu("Menu") { Text("Item1") Text("Item2") Text("Item3") Button("Red") { backgroundColor = .red } Button("Green") { backgroundColor = .green } Button("Blue"){ backgroundColor = .blue } Button("Yellow"){ backgroundColor = .yellow } Menu("Menu") { Text("Item1") Text("Item2") Text("Item3") Button("Red") { backgroundColor = .red } Menu("Menu") { Text("Item1") Text("Item2") Text("Item3") Button("Red") { backgroundColor = .red } } }}说明:
- Menu来实现菜单视图,可以设置标题
- 菜单中可以放文本视图和按钮视图
- 并还可以再嵌套菜单视图,实现多层级菜单的选择。
26、Form
表单视图
Form和List在利用和现象是没有区别的,底层也是一样的,都是对UItableView的封装,可以看做是分组的List
用于分组数据输入的控件的容器,如在设置或查抄器中。
Form { Text("item1") Text("item2") Text("item3")}说明:
27、ScrollView
ScrollViewReader { proxy in Button("gotoBottom"){ proxy.scrollTo(90) } ScrollView(.vertical, showsIndicators: false) { VStack(alignment: .center, spacing: 10) { ForEach(0..<100) { Text("cell \($0)").font(.title) } .frame(maxWidth:.infinity) } }}说明:
- 设置方向,可以选择垂直照旧程度方向滑动
- 设置是否体现Indicators
- 通过署理增长按钮跳转某个cell,此时必要利用ScrollViewReader来实现。
- 好比这里点击按钮后,可以直接跳转到底90个cell。
28、Alert
//AlertButton("show Alert") { show.toggle()}.alert(isPresented: $show) { Alert.init(title: Text("title"), message: Text("message"), dismissButton: .cancel())} Button("show Dialog") { show.toggle()}.confirmationDialog("dialog", isPresented: $show) { Button("btn1") {} Button("btn2") {} Button("btn3") {}}}说明:
- 这里可以设置多种按钮范例
- 可以设置点击事故的相应
- 还可以设置按钮列表,举行选择点击
|