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颜色
相关推荐
king_2020042612 分钟前
iPhone苹果手机iOS18如何隐藏打开APP怎么找出来恢复隐藏APP?
ios·智能手机·iphone
leluckys4 小时前
iOS-iOS在h5中判断手机是否装了app
ios
大雪山掘金4 小时前
APM - iOS 卡顿优化方案
ios·性能优化
MobTech袤博科技5 小时前
MobPush iOS端海外推送最佳实现
ios
蓝清水12 小时前
IOS17闪退问题Assertion failure in void _UIGraphicsBeginImageContextWithOptions
ios
有趣的杰克21 小时前
Flutter【组件】点击类型表单项
android·flutter·ios·dart
一丝晨光1 天前
final、const、readonly关键字在不同语言中代表着什么
java·开发语言·c++·面试·kotlin·c#·swift
码农--xc1 天前
iOS之如何创建.framework静态库
ios·静态库·.framework静态库·.framework
茶底世界之下1 天前
用来快速替代项目中HandyJSON的Codable库
前端·ios·swift
UWA1 天前
iOS包ShaderVariantCollection预热慢问题
ios·rendering·assetbundle