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颜色
相关推荐
恋猫de小郭9 小时前
什么?Flutter 可能会被 SwiftUI/ArkUI 化?全新的 Flutter Roadmap
flutter·ios·swiftui
网安墨雨13 小时前
iOS应用网络安全之HTTPS
web安全·ios·https
威化饼的一隅13 小时前
【多模态】swift-3框架使用
人工智能·深度学习·大模型·swift·多模态
福大大架构师每日一题14 小时前
37.1 prometheus管理接口源码讲解
ios·iphone·prometheus
BangRaJun1 天前
LNCollectionView-替换幂率流体
算法·ios·设计
刘小哈哈哈1 天前
iOS 多个输入框弹出键盘处理
macos·ios·cocoa
靴子学长1 天前
iOS + watchOS Tourism App(含源码可简单复现)
mysql·ios·swiftui
一如初夏丿2 天前
xcode15 报错 does not contain ‘libarclite‘
ios·xcode
杨武博2 天前
ios 混合开发应用白屏问题
ios
BangRaJun2 天前
LNCollectionView
android·ios·objective-c