SwiftUI学习记录

快捷键

  • 资源库:⌘+⇧+L

布局和堆栈

  • 默认情况下,图像不可调整大小
    • 需要添加一个名为resizable的修饰符(在Modifiers里查找)
  • 增大间距

    • 添加间隙:

      • Views里的spacer
      • 框架默认最大(占满整个屏幕),可以自己去inspector里调整Frame
  • Frame过大导致有空隙(如下图)

        

  •         可以增加间隙(但它必须已经在V/H/ZStack里了)
  • 加阴影:Modifier里的Shadow
  • 排列顺序

    • 通常将框架Frame放在最前面,偏移放在最后。(否则可能显示不出来效果)

组件和视觉效果

  • 如何创建组件,重复多次使用该组件

    • ⌘+左键,然后选择Extract Subview
    • 在进行下一步前要先命名

      

  • 如命名为CardView,则在最下方自动生成如图

  • 组件的Frame设置

    • 主卡大小保持不变,设定规模效应(使用修饰符scaleEffect)
  • 混合模式 blendMode

    • 种类
      • Softlight
      • Overlay
      • Hardlight ——背景很亮的时候使用  e.g.白色
      • Multiply
    • 对阴影进行操作时,活力很重要——颜色不能太黯淡,除非你就要这样。(更适合iOS的风格)
  • iOS13的字体风格

    • 大标题:Large titile+Heavy

  • 分行显示

    • 当有长文字时,可以加linelimit来分行显示
  • dock栏(?)

    • Frame : 60*6
    • CornerRadius : 3
    • Opacity : 0.1
  • 分隔一个Stack里的物件

    • Inspect里的Spacing,设为20
  • 填满所有空白的小技巧

    • 骆驼式命名法
.frame(minWidth:0 , maxWidth: .infinity)

动画和状态

  • 设置“默认情况下,动画状态是不活动且没有显示的”,如下:
@State var show = false
  • 动画开始:action
    • 点击开始:
      • .onTapGesture   
      • self.show 是我们的布尔值
      • .toggle() 意味着他将在真假间来回切换
    • Show ? 10 :0
    • .animation()可以加过渡动画
      • 括号里选择后,则
        • 括号内可以加“duration: 2”,来设定持续多少秒,通常0.5S/0.3S
        • Default(默认值)对线性动画很有用,适用于不透明度/模糊等不需要气势的东西。

手势和事件

1、设置状态viewState

@State var viewState = CGSize.zero
  1. showState是用于布尔值的ture/false
  2. viewState是一个定位,我们需要一个由X和Y组成的位置
    1. 这里的zero意味着这是默认的道具,它被设为0

2、应用手势+检测轨道(track)的位置,然后应用于状态。

(此时已经完成了信息的接受,还未传递出去。)

  • 在onTapGesture下面(否则会报错)写上:

.gesture()

  • 对于拖拉手势,在括号内加上“DragGesture()”,再在下一行加上修饰符
    • 如.onChange{},则需要设置接收值,而从这个值,我们可以接受拖动的位置,所以我们要把这个位置应用到我们的视图状态。
    • 写法:
DragGesture()

   .onChanged{  value in

        self.viewState = value.translation

             }
  • Translation 和viewState的类型都是CGSiza(按⌥+单击可查看),即具有相同类型的值才可以互相匹配
  • 还有在.onChange的下一行写上.onEnded{},使得移动之后自动返回原位置。

3、设置偏移量接受信息

  • 偏移量用平移过后的X/Y坐标
  • 写法:(因为CGSize有两个值:width/height)
.offset(x: viewState.width, y: viewState.height)

SF符号和道具

如何创建侧边菜单+如何设置菜单动画+如何设置间距/内边距+如何将数据传递到组件里+如何用代码设置SF标志图标+检测屏幕尺寸以便跨设备自适应

  • 创建主屏幕

    • 右键选择New file,选择SwiftUI View
    • 用Image设置SF标志图标:systemName:(记住SF Symbols app里的名字)
      • 调整尺寸:找到Symbol Image Scale
      • 自定义颜色:foregroundColor
      • 添加边框(因为有些图标尺寸不同,设置了之后就都会完美地居中)
        • 32*32
        • .frame
      • 设置一些自定义数据来自定义每一项(通过复制来的每一项)

  •          创建一个容器

    • Background-cornerRadius-shadow-Spacer(占满上下屏幕)
    • -frame(使用min/max来使左右屏幕占满)
    • -padding(上下间距)
    • -spacing:20(每行之间的间距。在VStack的括号里加)
    • -.padding(.trailing,60)(只给行尾留空隙,来留出右边的间隙)
    • -spacer(左对齐所有图标。在母模块里操作)

使用数据创建列表

如何从数组中创建列表+如何创建数据模型+如何用它循环这些项并自动执行该列表(不需要复制粘贴4次)

  • 在body前输入
  • var menuItems = ["My Account","Billig", "Team", "Sign out”]
    • 使用索引(从0开始)
  • 前后对比:

  • 创建数据模型

    • 在代码的最后声明数据模型
    • Identifiable:

      • 允许我们不仅使用数据,还可以在以后进行操作
      • 至少需要一个可识别的.
        • E.g. var id = UUID()
        • 循环数据的时候,ID是必要的,有点像key in react
        • 任何时候建立数据模型的时候都需要这个作为默认值
      • 其他的数据如title/icon
    • 在结构菜单之后输入数据
      • let menuData = [
            Menu(title: "", icon: ""),
        
            Menu(title: "", icon: "")
        
        ]
  •         确保得到了数据(将存储的数据传输到变量上)
    •         var menu = menuData
  • Foreach来循环
    • Foreach(menu){ item in
      MenuRow(image: item.icon, text: item.title)   
      }

(这样使用"item in"就能分别看到每一项(menu是项的集合,item是单独的项))

菜单动画和绑定

菜单动画+运用绑定来把状态传递给组件

  • 将菜单移动到顶端

    • 用ZStack

    • 使得菜单栏下面可以有内容
  • 创建按键

    • Modifier找到button
  • 把菜单推到屏幕之外

    • offset
    • 使用屏幕尺寸
      • UIScreen.main.bounds.width/height(加个负就反向)
  • 设置动画状态

    • @State var show = false
      action: {self.show.toggle()}
    • 把动画状态变成抵消—显示菜单栏的时候它会是真的(用show  ? : )
  • 设定动画
  • 添加点击功能

    • .onTapGesture(count:1, perform: {
                      self.show.toggle()
                  })
  • 添加3d效果
  • 创建组件
    • 不见了一些数值
      • 对于show状态—使用绑定
        • @Binding var show : Bool
        • 去主组件把这个状态传递给菜单组件
          • 在主组件那边找到对应菜单组件的括号,加上MenuView(show: $show)
          • 这意味着他会同步改变
        • 从主组件那里听取状态的改变

过渡动画

创建漂浮选择栏按键及屏幕转换

  • 输入校准

    • ZStack(alignment: .topLeading) 
    • 如果有多个ZStack,要放在最外层的(?)m
      • 同样的效果可以通过以下这个来实现:
      • .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .topTrailing)
    • 要确保ZStack有Spacer(),否则不会抓到整个屏幕的尺寸

滚动内容

创建滚动视图+创建背景阴影

  • 投影

    • 直接进入样式指南
      • 左上角切换到assets
      • 做好颜色后  点开右侧的检查器
      • 选择颜色  打开属性检查器  直接修改不透明度
    • 获得十六进制的颜色值(代码长)
      • 设置不透明度
      • .shadow,然后选择一个基础色
      • 进入检查器  在颜色那栏点击自定义(Custom)
  • 现在已经拥有了一张卡片
    • 拥有父容器之后就可以创建组件了(否则不可以提取子视图)
      • 放在HStack下
  • 重复
    • ⌘+左键之后点击repeat
  • 把HStack嵌入组(Group)中(⌘+左键)
    • 类似于占位符
    • 把名字换成“ScrollView”
      • scrollview内层是HStack就是横线 内层是VStack就是纵向
      • ScrollView(. horizontal, showsIndicators: false) 即可左右滑动
      • 通过在HStack下使用frame(height: 480)来解决阴影截断问题/Spacer()

模态

如何创建一个内置的模式转换(也适用于iPad)+使用数据填充其余卡片

  • 模式转换

    • 将元素包装在一个演示按钮中
      • 在CourseView上一行加上一些东西
        • 1\
        • NavigationView {
          
                       ScrollView(.horizontal,showsIndicators: false) {
          
                           HStack {
          
                               ForEach(0 ..< 3) { item in
          
                                   NavigationLink(destination: ContentView()){
          
                                       CourseView()
          
          }

          • 效果:右滑产生一个新界面,这个新界面自带左上角的返回“back”功能
        • 2\
          • 代码:
          • @State var showContentView: Bool = false
            
                var body: some View {
            
                    ScrollView(.horizontal, showsIndicators: false) {
            
                        VStack {
            
                            HStack(spacing: 20) {
            
                                ForEach(0 ..< 3) { item in
            
                                    Button(action: {
            
                                        self.showContentView = true
            
                                    }) {
            
                                        CourseView()
            
                                    }.sheet(isPresented: self.$showContentView) {
            
                                        ContentView()
            
                                    }

            • 效果:从底部划出一个新的界面,原有界面在后面保留
          • 括号里可以写上任何目的地(要转到的屏幕)

  • 图标被自动上色

    • 去到模块的定义处
    • 在image那行的后面加上修饰符:image rendering mode
    • 设置为.original

                例:

  • 标题
  • 换数据

    • 先设置数据模型(前面有提到)
    • 再把存储的数据传给变量
    • 把Foreach括号里的换成变量的名字
    • CoursesView(titile:换成item.title)
  • 有时图片太小无法取全宽(full width)

    • 两个元素:文字和图片
    • 应该有一个完美的框架
      • 在image的渲染模式(renderingmode)后面添加一框架修改器(frame)
        • 同样可以用这个方法来使文字分行
      • 默认模式下image不能随框架缩放

        • 让图像可调整大小(image resizable)
          • 不能很好地缩放纵横比(可能被拉长)
            • 增加纵横比(Aspect Ratio)
            • 要在renderingmode的后面
            • .fill改成.fit
            • 可能会遇到一个图案大一个图案小的情况
              • 增加padding(.bottom,??)
              • 修改.frame的高度,以免挤占文字的区域
      • 文字好像没有一致的填充

        • 原因:frame是手动固定的
        • 处理办法:
          • 删掉frame
          • 用padding(.trailing,50)来实现一样的效果
      • 在两个水平模块之间增加空隙

        • 在HStack加(spacing:20)

模糊背景

iOS的特别之处

  • iOS和UIKit里的VisualEffectView在SwiftUI不可用
  • UIKit在SwiftUI可用
    • 我们将用Swift代码来实现模糊背景的功能
  • 创建一个新视图BlurView

    • 可以在任何地方使用,尤其是ZStack
      • 因为它会占用容器的整个宽度
      • 用VStack它则会堆积起来
  • 对于IOS12及其之前版本,我们应该在补全选项中选择.dark/.light/.extraLight
  • 在ContentView的ZStack里的最前面调用BlurView
  • 然后去到Home(主页)
    • 确保当你调用ContentView时没有background
      • 否则他会取消模糊
    • 如果还是看不见
      • 把HomeList()放在ZStack的最前面
  • 在滚动视图的上方加上标题

    • 回到HomeList,把ScrollView嵌入到VStack里
    • 创建新文本
  • 把在整个屏幕上居中的文字调到旁边

    • 法一:设置frame(不理想)
    • 法二:使用HStack
      • 在VStack后面设置间隔(Spacer())
        • 这样使用的是屏幕的全宽
  • 让两个不在同一个模块的文字对齐

    • 在inspector里设置left padding:70
    • 根据这个已知的数据来做调整
  • 在主页上做一些缩放动画

    • HomeList的.blur下面紧接着(在animation上方)加入scaleEffection,并设置成0.95

导航视图和列表

iOS自带的导航+创建一个有导航选项的表视图并在SwiftUI里显示+滑动删除/编辑模式+用很舒服的过渡来浏览不同屏幕+从侧面拖动回原来的地方

  • 更新列表

    • 创建一个新的file
    • 在资源库里的”views”里寻找navigation
    • Embed in List(嵌入列表中)
    • 放置修饰符,让标题变大
      • .navigationBarTitle(Text("Updates"))
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值