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颜色
相关推荐
for_ever_love__5 小时前
UI学习:多界面传值的正向传值(属性传值)和反向传值(代理传值)
学习·ui·ios·objective-c
开心就好20258 小时前
全面介绍iOS开发工具:Xcode、AppCode、CocoaPods、Fastlane和Git
后端·ios
懋学的前端攻城狮8 小时前
数据持久化与缓存策略:在离线与在线间架起桥梁
ios·swift
~央千澈~10 小时前
以cocos3.8.8开发的游戏为例商业实战项目举例cocos打包ios苹果安装包ipa完整详细教程-优雅草卓伊凡
ios
SameX11 小时前
iOS 足迹 App 的成就系统,我推倒重做了一次——踩了3个坑之后
ios
SameX12 小时前
我做了一个把专注计时变成「声音护照」的 iOS App,聊聊数据可视化和成长系统的设计思路
ios
SameX12 小时前
我用 SpriteKit 给存钱罐装了个物理引擎
ios
开心就好202512 小时前
Charles配置HTTP和HTTPS抓包完整指南
后端·ios
JarvanMo12 小时前
7 个开源 iOS 应用,让你成为更好的开发者
前端·ios
白玉cfc13 小时前
OC底层原理:alloc&init&new
c++·macos·ios·objective-c·xcode