SwiftUI知识点(一)

前言:

Swift知识点,大至看完了,公司项目是Swift语言写的,后续苹果新出的SwiftUI,也需要学习一下

不知觉间,SwiftUI是19年出的,现在24年,5年前的东西了

学习的几个原因:
  1. 项目工程里面有一部分SwiftUI的代码;
  2. 跟上脚步,学习新知识,给自己加分;
  3. Vision AR的开发语言是SwiftUI,以后想开发或者接触这些新东西,语言需要提前准备

这次学习,参考的是:B站SwiftUI Bootcamp (Beginner Level),一个歪果仁的课,讲的很不错~

本博客所有代码已上传至github,欢迎下载~

SwiftUI_Bootcamp_Learn_Code


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 SwiftData

struct 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 SwiftUI

struct 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没有滚动属性,需要滚动的话,外面要包一个ScrollView
            LazyVGrid(
                columns: columns,
                //居中
                alignment: .center,
                //上下间距,即行间距,默认是6
                spacing: 1,
                //.sectionHeaders:头,划过去不消失,还在前面显示
                pinnedViews: [.sectionHeaders],
                
                content: {
                    ForEach(0..<70) { index in
                        Rectangle()
                            .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 in
                    RoundedRectangle(cornerRadius: 25)
                        .fill(.white)
                        .frame(height: 150)
                        .shadow(radius: 10)
                        .padding()
                }
            }
        }
        .background(.red)
    }
}

在这里插入图片描述

Button

在这里插入图片描述

state

只需要在监听的var变量前,加上@state即可。告诉这个属性是可观察的,后面有地方改变,则所有用到的地方,都会被改变

太6了

extractSubView

import SwiftUI

struct 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: Int
    let title: String
    let myColor: Color
    
    var body: some View {
        VStack{
            Text("\(count)")
            Text(title)
        }
        .padding()//增加间距
        .background(myColor)
        .cornerRadius(10)//加圆角
    }
}

在这里插入图片描述


@Binding


import SwiftUI

struct BindingBootcamp: View {
    
    @State var backgroundColor: Color = Color.green
    
    var body: some View {
        ZStack {
            backgroundColor
                .edgesIgnoringSafeArea(.all)
            ///在子控件创建的时候,将颜色传进去,加$符,即可完成双向绑定
            VStack {
                ButtonView(xxx: $backgroundColor)
            }
        }
    }
}

///将按钮提出来,不在一个view里面
struct ButtonView: View {
    /// 创建一个本地的属性,加一个@Binding, xxx是随便起的,一般命名与父属性一致,比如:backgroundColor
    @Binding var xxx: Color
    @State var ButtonColor: Color = Color.blue
    
    var body: some View {
        Button(action: {
            //按钮点击,去改变父类的背景颜色
            xxx = Color.orange
            ButtonColor = Color.green
        }, label: {
            Text("Button")
                .foregroundColor(.white)
                .padding()
                .padding(.horizontal)
                .background(ButtonColor)
                .cornerRadius(10)
        })
    }
}

#Preview {
    BindingBootcamp()
}

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值