iOS开发 SwiftUI 5 : 文本输入 密码输入 多行输入

目录

[单行输入和密码输入 TextField SecureField](#单行输入和密码输入 TextField SecureField)

示例

[双向绑定 变量](#双向绑定 变量)

[预设格式 textFieldStyle](#预设格式 textFieldStyle)

[内容类型 textContentType](#内容类型 textContentType)

[设置键盘类型 keyboardType](#设置键盘类型 keyboardType)

[禁止自动纠正 disableAutocorrection](#禁止自动纠正 disableAutocorrection)

再谈Padding

再谈text

[关闭键盘 取消焦点](#关闭键盘 取消焦点)

[背景覆盖 overlay](#背景覆盖 overlay)

[多行编辑 TextEditor](#多行编辑 TextEditor)

介绍

综合示例


单行输入和密码输入 TextField SecureField

示例

单行输入使用TextField和SecureField,区别是SecureField会用*代替输入的字符。

代码:

Swift 复制代码
struct SwiftUIViewTextField: View {
    @State var str: String = ""
    var body: some View {
        VStack(alignment: .leading, spacing: 20) {
            Text("\(str)").frame(minWidth: 120).border(.blue)
            TextField("Hello, World!", text: $str)
                .border(.blue)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .textContentType(.telephoneNumber)
                .keyboardType(.numberPad)
                .disableAutocorrection(true)
                .padding()
            SecureField("请输入密码", text: $str).border(.blue)
        }.padding().border(.red)
    }
}

效果:

双向绑定 $变量

之前我们用过@State变量来自动刷新界面,输入型视图要把输入的内容保存到变量去需要不同的绑定方式,增加符号"$",实现双向绑定。

Swift 复制代码
TextField("Hello, World!", text: $str)

因为例子中Text和SecureField也绑定到同一个变量,所以三个框会同步变化。

预设格式 textFieldStyle

textFieldStyle的参数指示预设的格式,比如RoundedBorderTextFieldStyle(),圆角带Padding(注意由于设置了border,失去了圆角,这是个冲突)。内置变量.roundedBorder也是一样的。

其余格式PlainTextFieldStyle(或内置变量.plain)和DefaultTextFieldStyle(或内置变量.automatic)差不多,不用设置。

内容类型 textContentType

这是给系统的提示,而不是对内容的约束。系统会根据提示调整键盘的细节,改善用户体验(然而莫名其妙的变化会伤害用户体验)。使用什么键盘是需要自己设置的。

.telephoneNumber 电话号码。

设置键盘类型 keyboardType

一般用到的就是指定数字键盘:

Swift 复制代码
.keyboardType(.numberPad)

禁止自动纠正 disableAutocorrection

什么时候他们才会意识到全人类都痛恨自动纠正啊。

Swift 复制代码
.disableAutocorrection(true)

再谈Padding

padding是填充的意思,在四周增加空白,但具体效果不同对象有所不同。

上面的示例给VStack和TextField都设置了Padding和Border,但是明显看出对VStack,填充是在边框之内,而对于TextField,填充却在边框之外,似乎缺乏统一的概念设计。

再谈text

我们注意到text是跟随内容自动变化的,示例代码强制了最小宽度,有内容的时候高度会变大,整个VStack的边框也会变大(红色),这种灵活的效果我不是很习惯。

关闭键盘 取消焦点

我们会发现很多应用输入完数据后键盘不会消失,导致部分界面被遮盖,无法进行下一步。这是因为输入框不会在点击外部空白区域时失去焦点,从而系统认为仍然处于输入状态。

解决方法很简单,输入框有个.focused($isFocus),参数是绑定的布尔变量,用来指示或控制输入框的状态,我们只需要在点击输入框外部空白时将绑定变量设置为false即可。

Swift 复制代码
    @FocusState private var isFocus: Bool //绑定变量

    var body: some View 
    {
        VStack
        {
            TextField(。。。。。。)
                .focused($isFocus)//设置绑定变量
        }
        .padding()
        .border(.red)
        .background(.green) //这句挺重要
        .ignoresSafeArea(.all)
        .onTapGesture 
        {
            isFocus = false //取消焦点
        }
    }

代码不复杂,在外层的onTapGesture设置代码即可,一般应该在最外层的容器上做。

里面有一句设置了最外层容器的背景色,标注了"这句挺重要",为什么呢?因为没有这一句时似乎系统认为顶级容器挺小的,取消焦点这个功能不是很灵,加了这一句就很灵了。注意任何情况下点击顶部安全区都无效,不论是否使用了.ignoresSafeArea(.all)。有一点奇怪,对于VStack,忽略安全区将导致边界正确显示在屏幕最外围,与ZStack不同。

不论是否使用了.ignoresSafeArea(.all),顶级的背景色都是全屏的。

关闭键盘还有些不同的方法,这个方法是官方推荐的方法(但是仍然不是很理想)。

背景覆盖 overlay

可以用overlay修饰TextField,overlay的参数是视图。修改一下之前的TextField:

Swift 复制代码
            TextField("Hello, World!", text: $str)
                .font(.system(size: 80))
                .border(.blue)
                .textFieldStyle(.roundedBorder)
                .textContentType(.telephoneNumber)
                .keyboardType(.numberPad)
                .disableAutocorrection(true)
                //.padding()
                .overlay(
                    HStack {
                        Image(systemName: "magnifyingglass")
                            .font(.system(size: 80))
                        Spacer()
                    }
                )

效果:

其实也不是啥好主意。

多行编辑 TextEditor

介绍

多行编辑有两点很不同:没有placeholder参数,默认大小是尽可能大。

还有一点也很不同:必须先隐藏默认背景才能设置背景。(.scrollContentBackground(.hidden))

综合示例

这个例子包含了本篇全部内容:

Swift 复制代码
import SwiftUI

struct SwiftUIViewTextField: View {
    @State var str: String = ""
    @FocusState private var isFocus: Bool
    var body: some View {
        VStack(alignment: .leading, spacing: 20) {
            Spacer()
            Text("\(str)")
                .frame(minWidth: 120)
                .border(.blue)
                .background(.blue)
                .foregroundStyle(.red)
            TextField("Hello, World!", text: $str)
                .font(.system(size: 80))
                .border(.blue)
                .textFieldStyle(.roundedBorder)
                .textContentType(.telephoneNumber)
                .keyboardType(.numberPad)
                .disableAutocorrection(true)
                //.padding()
                .overlay(
                    HStack {
                        Image(systemName: "magnifyingglass")
                            .font(.system(size: 80))
                        Spacer()
                    }
                )
                .focused($isFocus)
            SecureField("请输入密码", text: $str)
                .border(.blue)
            TextEditor(text:$str) //第一个多行文本,设置了背景色和前景色,默认大小
                .scrollContentBackground(.hidden)
                .background(.gray)
                .foregroundStyle(.red)
            TextEditor(text:$str) //第二个多行文本,指定了最大高度
                .border(.red)
                .frame(maxHeight:80)
            
            Spacer()
        }
        .padding()
        .border(.red)
        .background(.green)
        //.ignoresSafeArea(.all)
        .onTapGesture {
            isFocus = false
        }
    }
}

效果:

我们可以看到,Text是能显示多行的,TextField则把多行显示在一行,换行变成了空白。Text很简单地设置了背景色,TextEditor则必须禁用默认背景才能显示自己设置的背景色。TexeEditor的默认大小是尽可能大的。

相关推荐
iosTiov17 小时前
ios生态的分发密钥:企业签、V3签、TF签深度解析与选型指南
安全·ios·团队开发·苹果签名·稳定
2501_9159184118 小时前
介绍如何在电脑上查看 iPhone 和 iPad 的完整设备信息
android·ios·小程序·uni-app·电脑·iphone·ipad
晨枫阳19 小时前
iOS Universal Links配置
ios
2501_9160088919 小时前
没有 Mac 如何在 Windows 上创建 iOS 应用描述文件
android·macos·ios·小程序·uni-app·iphone·webview
菜的不敢吱声1 天前
swift学习第4天
服务器·学习·swift
北京自在科技1 天前
苹果iOS 26.3实现跨安卓数据无缝迁移
android·ios·findmy
郑梓斌1 天前
Luban 2 Flutter:一行代码在 Flutter 开发中实现图片压缩功能
flutter·ios
遥不可及zzz1 天前
ios adjust Google 设备端转化衡量
ios