SwiftUI文本字段可触摸区域
SwiftUI的布局与我们习惯的大不相同。目前我正在对抗SwiftUI文本字段可触摸区域,swiftui,Swiftui,SwiftUI的布局与我们习惯的大不相同。目前我正在对抗TextFields。特别是他们的可接触区域 TextField( .constant(""), placeholder: Text("My text field") ) .padding([.leading, .trailing]) .font(.body) 这将导致一个非常小的文本字段(按高度) 添加框架修改器修复了该问题(视觉上) 但可触摸区域保持不变 我知道,框架修改器除了
TextField
s。特别是他们的可接触区域
TextField(
.constant(""),
placeholder: Text("My text field")
)
.padding([.leading, .trailing])
.font(.body)
这将导致一个非常小的文本字段
(按高度)
添加框架修改器修复了该问题(视觉上)
但可触摸区域保持不变
我知道,框架修改器除了在另一个视图中以指定的高度包装文本字段外,没有做其他事情
对于
图像
,是否有任何与resizeable()
等效的方法可以允许更高的文本字段和更宽的可触摸区域?我不知道哪种方法更适合您。
所以,我发布了两个解决方案
1) 如果只想缩小输入区域
2) 缩小整个形状区域
快速的解决方法是只在按钮中添加文本字段,这样无论你们在哪里点击(在按钮中),键盘都会打开;我知道这不是一个解决方案,但它完成了工作(有点)。带按钮的解决方案 如果您不介意使用,可以通过保存UITextField并在按下按钮时调用
becomeFirstResponder()
来完成
扩展视图{
public func textfield focusablerea()->一些视图{
TextFieldButton{self.contentShape(Rectangle())}
}
}
fileprivate结构文本字段按钮:查看{
init(标签:@escaping()->label){
self.label=标签
}
变量标签:()->标签
私有变量textField=弱(无)
var body:一些观点{
按钮(操作:{
self.textField.value?.becomeFirstResponder()
},标签:{
label().introspectTextField{
self.textField.value=$0
}
}).buttonStyle(PlainButtonStyle())
}
}
///保存对值的弱引用
公共阶级软弱{
公共弱var值:T?
公共初始化(u值:T?){
自我价值=价值
}
}
用法示例:
TextField(…)
.填充(100)
.textFieldFocusableArea()
因为我自己也在使用它,所以我会在github上不断更新它:
使用ResponderChain的新解决方案
按钮解决方案将添加可能不需要的样式和动画,因此我现在使用我的
import ResponderChain
扩展视图{
public func textfield focusablerea()->一些视图{
self.modifier(textfieldFocusableAreamModifier())
}
}
fileprivate结构TextFieldFocusableAreamModifier:ViewModifier{
@EnvironmentObject私有变量链:ResponderCain
@国家私有变量id=UUID()
func正文(内容:内容)->某些视图{
内容
.contentShape(矩形())
.响应者代号(id)
.ontapsigne{
chain.firstResponder=id
}
}
}
您必须在SceneDelegate中将ResponderCain设置为环境对象,请查看ResponderCain的自述以了解更多信息。稍微解决一下,但效果不错
struct CustomTextField: View {
@State var name = ""
@State var isFocused = false
let textFieldsize : CGFloat = 20
var textFieldTouchAbleHeight : CGFloat = 200
var body: some View {
ZStack {
HStack{
Text(name)
.font(.system(size: textFieldsize))
.lineLimit(1)
.foregroundColor(isFocused ? Color.clear : Color.black)
.disabled(true)
Spacer()
}
.frame(alignment: .leading)
TextField(name, text: $name , onEditingChanged: { editingChanged in
isFocused = editingChanged
})
.font(.system(size: isFocused ? textFieldsize : textFieldTouchAbleHeight ))
.foregroundColor(isFocused ? Color.black : Color.clear)
.frame( height: isFocused ? 50 : textFieldTouchAbleHeight , alignment: .leading)
}.frame(width: 300, height: textFieldTouchAbleHeight + 10,alignment: .leading)
.disableAutocorrection(true)
.background(Color.white)
.padding(.horizontal,10)
.padding(.vertical,10)
.border(Color.red, width: 2)
}
}
我也面临同样的问题你找到解决办法了吗?没有。我向苹果公司提交了一份雷达文件。他们说已经修好了,但不是。。。我最终放弃了up@GiuseppeLanza你说“他们说已经修好了”是什么意思?它应该通过应用框架来工作吗?还是填充?在Swift v2(2020)中仍然没有解决方案(除了
UIViewRepresentable
'ing UITextField),但我不希望我的文本字段出现在表单中。我想要的是一个视图上的文本字段,我希望它的活动大小由我选择。就像你们可以用UIKit做的一样:创建一个文本字段,给它一个框架,然后把它放在屏幕上。现在,虽然我可以添加框架修改器,但textfield被包装在视图中,textfield的可触摸区域仍然被包装到字段的内容中,这是一个很好的解决方法。。。但是当我们想要一个文本字段的时候,我们需要一个按钮,这让我们很烦恼。这是可行的,但我仍然认为必须有另一种方法。我不相信苹果没有考虑在表单之外使用textField的可能性;老实说,我很震惊,并不是只有一个属性可以调整以增加可点击区域,或者只是让可点击区域自动成为框架/边框的大小。@ThomasBahmandeji这是怎么做到的?我真的搞不懂,对我没用。按钮会点击,但文本字段不会成为第一响应者。根据这个答案:我想你是说把文本字段放在按钮内,对吗?我试过这个,但对我不起作用。你到底是怎么做的@ThomasBahmandejiI可以验证这是一个好的解决方案。使用第三方软件包并不理想,但在苹果发布本机软件包之前,该软件包可以很好地工作
var body: some View {
Form {
HStack {
Spacer().frame(width: 30)
TextField("input text", text: $inputText)
Spacer().frame(width: 30)
}
}
}
var body: some View {
HStack {
Spacer().frame(width: 30)
Form {
TextField("input text", text: $restrictInput.text)
}
Spacer().frame(width: 30)
}
}
struct CustomTextField: View {
@State var name = ""
@State var isFocused = false
let textFieldsize : CGFloat = 20
var textFieldTouchAbleHeight : CGFloat = 200
var body: some View {
ZStack {
HStack{
Text(name)
.font(.system(size: textFieldsize))
.lineLimit(1)
.foregroundColor(isFocused ? Color.clear : Color.black)
.disabled(true)
Spacer()
}
.frame(alignment: .leading)
TextField(name, text: $name , onEditingChanged: { editingChanged in
isFocused = editingChanged
})
.font(.system(size: isFocused ? textFieldsize : textFieldTouchAbleHeight ))
.foregroundColor(isFocused ? Color.black : Color.clear)
.frame( height: isFocused ? 50 : textFieldTouchAbleHeight , alignment: .leading)
}.frame(width: 300, height: textFieldTouchAbleHeight + 10,alignment: .leading)
.disableAutocorrection(true)
.background(Color.white)
.padding(.horizontal,10)
.padding(.vertical,10)
.border(Color.red, width: 2)
}
}