gpt4 book ai didi

ios - 如何始终在 SwiftUI 中显示键盘

转载 作者:行者123 更新时间:2023-12-02 16:20:50 25 4
gpt4 key购买 nike

我正在尝试在 SwiftUI 中开发一款填字游戏应用。我想始终显示键盘,并能够选择一个正方形并让按键在那里输入一个字母。有没有办法始终在 View 中显示键盘?如果我使用 TextField,我可以让键盘显示出来,但是让拼图的每个单元格成为一个文本字段似乎相当笨拙。提前致谢。

最佳答案

最终产品:https://imgur.com/a/Q85GOWj

我决定删除我的其他答案并尝试练习代码。首先,您需要创建一个始终是第一响应者的 UITextField。您可以这样做:

struct PermanentKeyboard: UIViewRepresentable {
@Binding var text: String

class Coordinator: NSObject, UITextFieldDelegate {
var parent: PermanentKeyboard

init(_ parent: PermanentKeyboard) {
self.parent = parent
}

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

//Async to prevent updating state during view update
DispatchQueue.main.async {
if let last = string.last {

//Check if last character is alpha
if last.isLetter {

//Changes the binding to the last character of input, UPPERCASED
self.parent.text = String(last).uppercased()

}

//Allows backspace
} else if string == "" {
self.parent.text = ""
}
}

return false
}
}

func makeCoordinator() -> Coordinator {
Coordinator(self)
}

func makeUIView(context: Context) -> UITextField {
let textfield = UITextField()
textfield.delegate = context.coordinator

//Makes textfield invisible
textfield.tintColor = .clear
textfield.textColor = .clear

return textfield
}

func updateUIView(_ uiView: UITextField, context: Context) {
uiView.text = text

//Makes keyboard permanent
if !uiView.isFirstResponder {
uiView.becomeFirstResponder()
}

//Reduces space textfield takes up as much as possible
uiView.setContentHuggingPriority(.defaultHigh, for: .vertical)
uiView.setContentHuggingPriority(.defaultHigh, for: .horizontal)
}
}

它被包装在一个 UIViewRepresentable 中,这样我们就可以在我们的 SwiftUI View 中使用它。当我们的 View 可见并且它的键盘永远不会被关闭时,这个文本字段将自动聚焦。

现在我们必须使用实际的填字游戏制作我们的 SwiftUI View 。首先,我将在我们的 ContentView 中定义一个结构,它将用作填字游戏框:

struct CharacterBox: View {
@Binding var character: String
@Binding var selectedInput: Int
let index: Int

var isSelected: Bool {
index == selectedInput
}

var body: some View {
ZStack {
//Required for tap gesture to work
Rectangle()
.fill(Color.white)

//To signify selection
Rectangle()
.stroke(isSelected ? Color.orange : Color.black)

Text(character)
.foregroundColor(.black)
}
.frame(width: 50, height: 50)
.onTapGesture {
selectedInput = index
}
}
}

这个 CharacterBox 结构可以绑定(bind)到我们 ContentView 中的状态变量字符串,如果它与选定的输入变量匹配,那么它也会被不可见的文本字段修改。

到 ContentView。我们需要为每个要绑定(bind)的 CharacterBox 创建一个状态变量,但显然我们不能手动完成。因此,我们将创建一个数组,并让每个 CharacterBox 根据其索引绑定(bind)到一个字符串。

在此之前,我创建了这个函数来帮助我们用一些空字符串初始化一个数组。

func createEmptyStringArray(count: Int) -> [String] {
var array = [String]()

for _ in 0..<count {
array.append("")
}

return array
}

如果你愿意,你可以把它放在 ContentView 之外;它还可以让您稍后重用它。然后我们将要绑定(bind)的输入定义为一个数组,如下所示:

@State private var inputs = createEmptyStringArray(count: 3)
@State private var selectedInput = 0

selectedInput 是 inputs 数组中字符串的索引,不可见文本字段将绑定(bind)到该字符串。要为每个 CharacterBox 进行绑定(bind),我们可以将此函数放在我们的 ContentView 中:

func getInputBinding(index: Int) -> Binding<String> {
Binding<String>(
get: {
inputs[index]
},
set: {
inputs[index] = $0
}
)
}

请注意,因为您定义的每个 CharacterBox 的索引不应更改,所以可以使用函数来获取这样的 Binding。但是,对于我们的 selectedIndex,我们需要它在每次 selectedIndex 更改时更新绑定(bind),因此我们必须改用计算属性。像这样定义它:

var selectedInputBinding: Binding<String> {
Binding<String>(
get: {
inputs[selectedInput]
},
set: {
inputs[selectedInput] = $0
}
)
}

最后,把它们放在一起,这就是我们的 body :

var body: some View {
ZStack {
PermanentKeyboard(text: selectedInputBinding)

//Hides textfield and prevents user from selecting/pasting/copying
Rectangle()
.fill(Color.white)
.frame(maxWidth: .infinity, maxHeight: .infinity)

//Your crossword with bindings to inputs here; this is hard coded/manually created
VStack(spacing: 1) {
ForEach(0 ..< inputs.count) { index in
CharacterBox(character: getInputBinding(index: index), selectedInput: $selectedInput, index: index)
}
}
}
}

关于ios - 如何始终在 SwiftUI 中显示键盘,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65545374/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com