【问题标题】:Make TextEditor dynamic height SwiftUISwiftUI 制作 TextEditor 动态高度
【发布时间】:2021-09-25 10:11:50
【问题描述】:

我正在尝试创建一个不断增长的 TextEditor 作为聊天视图的输入。

例如,我们的目标是有一个可以展开直到达到 6 行的框。之后它应该可以滚动了。

我已经设法使用包含换行符\n 的字符串来做到这一点。

                        TextEditor(text: $composedMessage)
                            .onChange(of: self.composedMessage, perform: { value in
                                withAnimation(.easeInOut(duration: 0.1), {
                                    if (value.numberOfLines() < 6) {
                                        height = startHeight + CGFloat((value.numberOfLines() * 20))
                                    }
                                    if value.numberOfLines() == 0 || value.isEmpty {
                                        height = 50
                                    }
                                })
                            })

我创建了一个字符串扩展,它通过调用 string.numberOfLines() var startHeight: CGFloat = 50 返回换行数

问题:如果我粘贴一个包含很长文本的文本,当该字符串没有换行符时,它不会扩展。文本在 TextEditor 中被破坏。

如何计算 TextEditor 的中断次数并在该位置放置一个换行符?

【问题讨论】:

    标签: string text dynamic swiftui height


    【解决方案1】:

    我找到了解决办法!

    对于其他试图解决此问题的人:

    我添加了一个与输入字段宽度相同的Text,然后使用GeometryReader 计算自动换行的文本的高度。然后,如果您将高度除以字体大小,则得到行数。

    您可以隐藏文本字段(在 iOS 14 和 iOS 15 beta 3 中测试)

    【讨论】:

    • 您好,您能分享一下您的解决方案吗?我有一个类似的问题,正在努力使用 GeometryReader。
    • @Fabio 你能分享一下代码示例吗?
    【解决方案2】:

    这是一个根据问答改编的解决方案,

    struct ChatView: View {
        @State var text: String = ""
    
        // initial height
        @State var height: CGFloat = 30
    
        var body: some View {
            ZStack(alignment: .topLeading) {
                Text("Placeholder")
                    .foregroundColor(.appLightGray)
                    .font(Font.custom(CustomFont.sofiaProMedium, size: 13.5))
                    .padding(.horizontal, 4)
                    .padding(.vertical, 9)
                    .opacity(text.isEmpty ? 1 : 0)
    
                TextEditor(text: $text)
                    .foregroundColor(.appBlack)
                    .font(Font.custom(CustomFont.sofiaProMedium, size: 14))
                    .frame(height: height)
                    .opacity(text.isEmpty ? 0.25 : 1)
                    .onChange(of: self.text, perform: { value in
                        withAnimation(.easeInOut(duration: 0.1), {
                            if (value.numberOfLines() < 6) {
                                // new height
                                height = 120
                            }
                            if value.numberOfLines() == 0 || value.isEmpty {
                                // initial height
                                height = 30
                            }
                        })
                    })
            }
            .padding(4)
            .overlay(
                RoundedRectangle(cornerRadius: 8)
                    .stroke(Color.appLightGray, lineWidth: 0.5)
            )
        }
    
    }
    

    还有扩展,

    extension String {
        func numberOfLines() -> Int {
            return self.numberOfOccurrencesOf(string: "\n") + 1
        }
    
        func numberOfOccurrencesOf(string: String) -> Int {
            return self.components(separatedBy:string).count - 1
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-13
      • 2021-04-22
      • 2022-11-10
      • 2021-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-01
      相关资源
      最近更新 更多