SwiftUI教程(三)常用View和Modifiers具体讲解和利用

藏宝库编辑 2024-10-5 10:20:13 95 0 来自 中国
SwiftUI教程系列文章汇总
本文紧张陈诉常见的View和Modifiers的熟悉和利用
紧张内容:

  • 常用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
效果:
5.gif 说明:

  • 给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") {}}}说明:

  • 这里可以设置多种按钮范例
  • 可以设置点击事故的相应
  • 还可以设置按钮列表,举行选择点击
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-11-23 16:05, Processed in 0.184893 second(s), 35 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表