ios入门实例(五):随机选中姓名

前言

本章实例主要为通过@State,list显示列表名,通过randomElement随机选中names item,和通过动态TextField动态输入信息,Toggle开关控制是添加name还是删除name

demo 效果

展示简单的随机选中姓名和随机删除姓名的功能

步骤

创建项目Pick-a-Pal显示姓名list

快速创建ios项目:Pick-a-Pal(点击查看xcode创建项目)

主入口文件ContentView添加个@State属性的names用来动态存储"名字"集,通过ForEach遍历显示

swift 复制代码
// ContentView.swift

import SwiftUI 

struct ContentView: View { 
   @State private var names: [String] = ["Elisha", "Andre", "Jasmine", "Po-Chun"] 
   
   var body: some View { 
       VStack { 
          List { 
             ForEach(names, id: \.self) { name in 
                Text(name) 
             }
          } 
       } 
       .padding()
   } 
 } 
 
#Preview { 
  ContentView() 
}

效果:

动态添加姓名

在页面底部添加TextField输入框,用来接收输入的姓名

diff 复制代码
// ContentView.swift

import SwiftUI 

struct ContentView: View { 
   @State private var names: [String] = ["Elisha", "Andre", "Jasmine", "Po-Chun"] 
+  @State private var nameToAdd = ""
   
   var body: some View { 
       VStack { 
          List { 
             ForEach(names, id: \.self) { name in 
                Text(name) 
             }
          } 
+          TextField("Add Name", text: $nameToAdd) 
+           .onSubmit { 
+              names.append(nameToAdd) 
+              nameToAdd = "" 
+          }
       } 
       .padding()
   } 
 } 
 
#Preview { 
  ContentView() 
}

这里的变量 nameToAdd 用来接收输入变量,通过键盘"回车"键触发onSubmit方法

当输入内容为空时候"回车"也会添加一条空数据 姓名item ,这里需要对 nameToAdd进行判空校验

diff 复制代码
// ContentView.swift

          TextField("Add Name", text: $nameToAdd) 
           .onSubmit { 
+              if !nameToAdd.isEmpty{
                  names.append(nameToAdd) 
                 nameToAdd = "" 
+              } 
          }

输入开头相似的name会被自动更正,这里可以使用autocorrectionDisabled把该功能关闭

diff 复制代码
// ContentView.swift

          TextField("Add Name", text: $nameToAdd) 
+          .autocorrectionDisabled()          

开启simulator查看

由于点击TextField输入框在真机情况下是会有软键盘弹出,为了查看实际效果可以运行在Xcode simulator上查看

选择头部菜单启动simulator:Product > Run again.

当启动虚拟机时Xcode将停止Preview,这时候可以在Xcode中关闭Preview视图步骤:

tip:Debug 区域在XCode右下方可以通过 view > Debug Area > Hide Debug Area 进行隐藏

随机选中name

首先选中的name是个变量使用@State,名称为 pickedName,当有值时候显示出来

diff 复制代码
// ContentView.swift

struct ContentView: View { 
   ...
+  @State private var pickedName ="" 

 var body: some View { 
       VStack { 
+        Text(pickedName.isEmpty ? " " : pickedName)
         ...
       }
 }      

}

这里的?三元操作符(文档)前端的同学经常会使用到

底部添加触发随机选中name的Button,使用randomElement()来随机获取names中的姓名,当 names为空时候randomElement()会返回nil,这里使用 if ...else来做兼容处理

diff 复制代码
// ContentView.swift

    VStack {
       ...
+       Button("Pick Random Name") {
+          if let randomName = names.randomElement() {
+              pickedName = randomName 
+           } else { 
+              pickedName = "" 
+           }
+       }
    }

输入框与Button边界不是很好识别,添加个Divider边界分割线效果

diff 复制代码
// ContentView.swift

    VStack {
       ...
+       Divider()
       Button("Pick Random Name") {
         if let randomName = names.randomElement() {
              pickedName = randomName 
           } else { 
              pickedName = "" 
           }
      }
    }
    ...

随机删除name

上述说明主要是添加name随机选中 name,接下来通过Toggle开关来控制随机 选中/删除 name,首先设置开关标识 shouldRemovePickedName 默认为false

diff 复制代码
// ContentView.swift

struct ContentView: View { 
   ...
+  @State private var shouldRemovePickedName = false

           ...
           Divider() 
+          Toggle("Remove when picked", isOn: $shouldRemovePickedName)
           ....

shouldRemovePickedName为true开启删除name逻辑

diff 复制代码
// ContentView.swift

    VStack {
       ...
       Button("Pick Random Name") {
       
          if let randomName = names.randomElement() {
             pickedName = randomName 
+            if shouldRemovePickedName { 
+                 names.removeAll { name in 
+                     return (name == randomName)
+                } 
+             }
           } else { 
              pickedName = "" 
          }
       }
    }

其中 removeAll 为数组遍历的一个闭包方法,删除的item返回为 true的,有点像前端的 filter

按钮样式调整

随机选中的Button样式不够明显,这里使用 buttonStyle修改下样式

diff 复制代码
// ContentView.swift

    VStack {
       ...
       Button("Pick Random Name") {
        ...
       }
+       .buttonStyle(.borderedProminent) 
+       .font(.title2) //增大字号
    }

现在按钮是有效果,但是边距太窄,这里通过label去设定下padding

diff 复制代码
// ContentView.swift

    VStack {
       ...
-       Button("Pick Random Name") {
+       Button{
        ...
+       }label: { 
+        Text("Pick Random Name") 
+          .padding(.vertical, 8) 
+           .padding(.horizontal, 16) }
        ...
    }

样式调整

  1. 选中的人添加icon,使用字体图标的hierarchical(文档)分等级渲染
diff 复制代码
// ContentView.swift

    VStack {
+         VStack(spacing: 8) { 
+          Image(systemName: "person.3.sequence.fill") 
+             .foregroundStyle(.tint)
+             .symbolRenderingMode(.hierarchical)
+          Text("Pick-a-Pal")
+         } 
+         .font(.title)
+          .bold()
+       }
        ...
   }     

2.list边缘使用clipShape裁剪成圆角

diff 复制代码
// ContentView.swift

    VStack {
          ...
          List { 
             ForEach(names, id: \.self) { name in 
                Text(name) 
             }
          } 
+         .clipShape(RoundedRectangle(cornerRadius: 8))          
        ...
   }     
  1. 选中的 name 字体加粗放大和添加主体颜色.pickedNameRed 0.345, Green 0.337, Blue 0.812.查看如何添加主体颜色)
diff 复制代码
// ContentView.swift

    VStack {
          ...
          Text(pickedName.isEmpty ? " " : pickedName)
+             .font(.title2)
+             .fontWeight(.bold)
+             .foregroundColor(.pickedName)         
        ...
   }     

最终效果:

总结

本章节主要是对@State巩固和一些组件和api的用

  • TextField输入框组件以及onSubmit方法
  • Divider 分割线组件
  • Toggle 开关组件
  • .randomElement 该方法用于数组随机获取item
  • .removeAll该方法用于数组删除,通过遍历当 return true的item 将被删除
  • hierarchical分级渲染icon颜色
相关推荐
键盘敲没电5 小时前
【IOS】GCD学习
学习·ios·objective-c·xcode
SY.ZHOU6 小时前
Significant Location Change
macos·ios·cocoa
MaoJiu9 小时前
Flutter造轮子系列:flutter_permission_kit
flutter·swiftui
吴Wu涛涛涛涛涛Tao13 小时前
深入理解 Swift Codable:从基础到进阶
ios
大熊猫侯佩16 小时前
由一个 SwiftData “诡异”运行时崩溃而引发的钩深索隐(三)
数据库·swiftui·swift
大熊猫侯佩16 小时前
由一个 SwiftData “诡异”运行时崩溃而引发的钩深索隐(二)
数据库·swiftui·swift
大熊猫侯佩16 小时前
用异步序列优雅的监听 SwiftData 2.0 中历史追踪记录(History Trace)的变化
数据库·swiftui·swift
大熊猫侯佩16 小时前
由一个 SwiftData “诡异”运行时崩溃而引发的钩深索隐(一)
数据库·swiftui·swift
Jouzzy19 小时前
【iOS安全】iPhone X iOS 16.7.11 (20H360) WinRa1n 越狱教程
安全·ios·iphone
二流小码农1 天前
鸿蒙开发:实现一个标题栏吸顶
android·ios·harmonyos