How can I pass a closure into ViewModifier button? - swiftui

Not sure how to add an optional action to TextFieldButton view and have the TextFieldClearButton view modifier accept the action.
struct TextFieldClearButton: ViewModifier {
#Binding var fieldText: String
var action: (() -> Void)? = nil
func body(content: Content) -> some View {
content
.overlay {
if !fieldText.isEmpty {
HStack {
Spacer()
Button {
fieldText = ""
action
} label: {
Image(systemName: "multiply.circle.fill")
}
.foregroundColor(.secondary)
.padding(.trailing, 4)
}
}
}
}
}
extension View {
func showClearButton(_ text: Binding<String>) -> some View {
self.modifier(TextFieldClearButton(fieldText: text))
}
}
struct TextFieldButton: View {
#State private var text = ""
#FocusState private var isTextFieldFocused: Bool
var body: some View {
VStack {
TextField("", text: $text)
.textFieldStyle(.roundedBorder)
.focused($isTextFieldFocused)
.showClearButton($text)
}
.padding()
.background(Color.purple)
}
}
So far I can only get an "Expression of type '(() -> Void)?' is unused" warning and I am not sure how or if this needs to passed in as a #Binding.

Here is the full working version of this code:
#Binding var fieldText: String
var action: (() -> Void)? = nil
func body(content: Content) -> some View {
content
.overlay {
if !fieldText.isEmpty {
HStack {
Spacer()
Button {
fieldText = ""
action?()
} label: {
Image(systemName: "multiply.circle.fill")
}
.foregroundColor(.secondary)
.padding(.trailing, 4)
}
}
}
}
}
extension View {
func showClearButton(_ text: Binding<String>, action: (() -> Void)? = nil) -> some View {
self.modifier(TextFieldClearButton(fieldText: text, action: action))
}
}
struct TextFieldButton: View {
#State private var text = ""
#FocusState private var isTextFieldFocused: Bool
var body: some View {
VStack {
TextField("", text: $text)
.textFieldStyle(.roundedBorder)
.focused($isTextFieldFocused)
.showClearButton($text, action: testPrint)
}
.padding()
.background(Color.purple)
}
func testPrint() {
print("Test Print Successful.")
}
}

action is a property of type (() -> Void)? You need to call the action closure, you can do this by changing it from action to action?()
Button {
fieldText = ""
action?()
} label: {
Image(systemName: "multiply.circle.fill")
}

Related

SwiftUI's custom modal logic: how to present view from parent

Coming from UIKit, I'm building my own modal navigation logic in SwiftUI, because I want custom layouts and animations. Here, I want a generic bottom sheet like so:
I have achieved something close with the following code:
enum ModalType: Equatable {
case normal // ...
#ViewBuilder
var screen: some View {
switch self {
case .normal: ModalView()
// ...
}
}
}
struct ContentView: View {
#State var presentedModal: ModalType?
var body: some View {
VStack {
Button("Present modal", action: { presentedModal = .normal }).foregroundColor(.black)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(.gray)
.modifier(ModalBottomViewModifier(item: $presentedModal) { $0.screen })
}
}
struct ModalView: View {
#Environment(\.dismissModal) private var dismissModal
var body: some View {
VStack {
Button("Close", action: { dismissModal() })
}
.frame(maxWidth: .infinity)
.frame(height: 300)
.background(
RoundedRectangle(cornerRadius: 32)
.fill(.black.opacity(0.5))
.edgesIgnoringSafeArea([.bottom])
)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
// MARK: - Modal logic
struct ModalBottomViewModifier<Item:Equatable, V:View>: ViewModifier {
#Binding var item: Item?
#ViewBuilder var view: (Item) -> V
func body(content: Content) -> some View {
ZStack(alignment: .bottom) {
content
if let item = item {
view(item)
.environment(\.dismissModal, { self.item = nil })
.transition(.move(edge: .bottom))
}
}
.animation(.easeOut, value: item)
}
}
private struct ModalDismissKey: EnvironmentKey {
static let defaultValue: () -> Void = {}
}
extension EnvironmentValues {
var dismissModal: () -> Void {
get { self[ModalDismissKey.self] }
set { self[ModalDismissKey.self] = newValue }
}
}
Now I'd like to make this system reusable, so that I don't have to add the ModalBottomViewModifier to all my app screens. For that, I'd like to be able to apply the modifier to the button instead of the screen, just like it's possible with fullScreenCover:
Button("Present modal", action: { isPresented = true }).foregroundColor(.black)
.fullScreenCover(isPresented: $isPresented) { ModalView() }
This is not possible with my current solution, because the modal view will appear next to the button and not fullscreen.
How can I achieve this? Or should I be doing something different?
Here's a simple solution using UIKit:
extension View {
func presentModalView<Content: View, Item: Equatable>(item: Binding<Item?>, #ViewBuilder view: #escaping (Item) -> Content) -> some View {
func present() {
guard let itemy = item.wrappedValue else {return}
DispatchQueue.main.async {
let topMostController = self.topMostController()
let someView = VStack {
Spacer()
view(itemy)
.environment(\.dismissModal, {item.wrappedValue = nil})
}
let viewController = UIHostingController(rootView: someView)
viewController.view?.backgroundColor = .clear
viewController.modalPresentationStyle = .overFullScreen
topMostController.present(viewController, animated: true)
}
}
return self.onChange(of: item.wrappedValue) { value in
if value != nil {
present()
}else {
topMostController().dismiss(animated: true)
}
}.onAppear {
if item.wrappedValue != nil {
present()
}
}
}
func topMostController() -> UIViewController {
var topController: UIViewController = UIApplication.shared.windows.first!.rootViewController!
while (topController.presentedViewController != nil) {
topController = topController.presentedViewController!
}
return topController
}
}
Usage:
struct ContentView: View {
#State var presentedModal: ModalType?
var body: some View {
VStack {
Button("Present modal", action: { presentedModal = .normal }).foregroundColor(.black)
.presentModalView(item: $presentedModal, view: {$0.screen})
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(.gray)
}
}

showing TextField in Alert function at SwiftUi

I am new in SwiftUi and I am trying to show Alert message with TextField and action button, I want to use Alert function for this, but I can't add TextField in Alert function,I shared code at below, how can I add TextField in Alert function? thanks..
.alert(isPresented:$showAlertDialog) {
Alert(
title: Text("Please Enter sended E-mail Code"),
message: Text("There is no undo"),
primaryButton: .destructive(Text("Submit")) {
print("Deleting...")
},
secondaryButton: .cancel()
)
}
As of iOS 15 alerts are not capable of showing TextFields. But you can make a custom SwiftUI alert.
struct TextFieldAlert: ViewModifier {
#Binding var isPresented: Bool
let title: String
#Binding var text: String
let placeholder: String
let action: (String) -> Void
func body(content: Content) -> some View {
ZStack(alignment: .center) {
content
.disabled(isPresented)
if isPresented {
VStack {
Text(title).font(.headline).padding()
TextField(placeholder, text: $text).textFieldStyle(.roundedBorder).padding()
Divider()
HStack{
Spacer()
Button(role: .cancel) {
withAnimation {
isPresented.toggle()
}
} label: {
Text("Cancel")
}
Spacer()
Divider()
Spacer()
Button() {
action(text)
withAnimation {
isPresented.toggle()
}
} label: {
Text("Done")
}
Spacer()
}
}
.background(.background)
.frame(width: 300, height: 200)
.cornerRadius(20)
.overlay {
RoundedRectangle(cornerRadius: 20)
.stroke(.quaternary, lineWidth: 1)
}
}
}
}
}
extension View {
public func textFieldAlert(
isPresented: Binding<Bool>,
title: String,
text: Binding<String>,
placeholder: String = "",
action: #escaping (String) -> Void
) -> some View {
self.modifier(TextFieldAlert(isPresented: isPresented, title: title, text: text, placeholder: placeholder, action: action))
}
}
Use it on the root view. (don't attach it to Buttons to other inner elements for example). This will ensure that presenting view is disabled.
Sample usage:
struct ContentView: View {
#State var isAlertDisplayed = false
#State var text = "Text to change"
var body: some View {
VStack {
Text("Press the button to show the alert").multilineTextAlignment(.center)
Text("Current value is: \(text)")
Button("Change value") {
withAnimation {
isAlertDisplayed = true
}
}
.padding()
}
.textFieldAlert(isPresented: $isAlertDisplayed, title: "Some title", text: $text, placeholder: "Placeholder", action: { text in
print(text)
})
.padding()
}
}

SwiftUI : I can't make ZStack view in NavigationLink's Screen

This is my NavigationLink DetailView,
import SwiftUI
struct AddChildrenView: View {
#State var word : String = ""
#State var meaning : String = ""
#State var isShowAlert : Bool = false
#State var isClicked : Bool = false
#EnvironmentObject var itemModel : ItemModel
var item : Item
var body: some View {
ZStack {
if item.children.count == 0 {
NochildrenView()
}
List {
ForEach(item.children) { child in
WordListRowView(children: child)
.onTapGesture {
withAnimation(.linear(duration: 0.3)) {
itemModel.favoriteChildren(item: item, children: child)
}
}
}
.onDelete { indexSet in
itemModel.deleteChildren1(item: item, indexSet: indexSet)
}
}
.id(UUID())
}
.navigationBarTitle("\(item.group!)'s Words")
.navigationBarTitleDisplayMode(.inline)
.navigationBarItems(trailing:
HStack {
Button(action: {
addChildren()
}, label: {
Image(systemName: "plus")
})
Button(action: {
itemModel.shuffleChildren(item: item)
}, label: {
Image(systemName: "shuffle")
})
NavigationLink(destination: FlashCardView(item: item)) {
Image(systemName: "play.rectangle")
}
.disabled(item.children.isEmpty)
})
}
}
extension AddChildrenView {
func addChildren() {
let alert = UIAlertController(title: "Saving word", message: "Type word and meaning 😀", preferredStyle: .alert)
alert.addTextField { word in
word.placeholder = "Type a word"
}
alert.addTextField { meaning in
meaning.placeholder = "a meaning of word"
}
let addfolderAction = UIAlertAction(title: "Add", style: .default, handler: {
(_) in
self.word = alert.textFields![0].text!
self.meaning = alert.textFields![1].text!
itemModel.addNewChildren(item: item, word: word, meaning: meaning)
})
let cancelAction = UIAlertAction(title: "Cancel", style: .destructive, handler: {
(_) in
})
alert.addAction(addfolderAction)
alert.addAction(cancelAction)
UIApplication.shared.windows.first?.rootViewController?.present(alert, animated: true, completion: nil)
}
}
This is MotherView with NavigationLink,
import SwiftUI
struct HomeView: View {
#State var folderName : String = ""
#EnvironmentObject var itemModel : ItemModel
var body: some View {
NavigationView{
ZStack {
if itemModel.items.count == 0 {
NoItemView()
}
List{
ForEach(itemModel.items) {item in
if let group = item.group {
NavigationLink(destination: {
AddChildrenView(item : item)
}, label: {
HStack{
Image(systemName: "folder")
.foregroundColor(.yellow)
Text(group)
.font(.headline)
.lineLimit(1)
}
})
}
}
.onMove(perform: itemModel.moveItem)
.onDelete(perform: itemModel.deleteItem)
}
.listStyle(.plain)
}
.navigationViewStyle(StackNavigationViewStyle())
.navigationTitle("SelfDic 📒")
.navigationBarItems(trailing:
Button(action: {
addFolderView()
}, label: {
Image(systemName: "folder.badge.plus")
}))
.navigationBarItems(leading: EditButton())
}
}
}
extension HomeView {
func addFolderView() {
let alert = UIAlertController(title: "Saving folder", message: "Type a name of folder 🙂", preferredStyle: .alert)
alert.addTextField { name in
name.placeholder = "folder's name"
}
let addfolderAction = UIAlertAction(title: "Add", style: .default, handler: {
(_) in
self.folderName = alert.textFields![0].text!
itemModel.addNewFolder(text: folderName)
})
let cancelAction = UIAlertAction(title: "Cancel", style: .destructive, handler: {
(_) in
})
alert.addAction(addfolderAction)
alert.addAction(cancelAction)
UIApplication.shared.windows.first?.rootViewController?.present(alert, animated: true, completion: nil)
}
}
struct HomeView_Previews: PreviewProvider {
static var previews: some View {
HomeView()
}
}
**I wanted to use Zstack in my linked View
The logic is that, If there is no item.children, I will show NoChildrenView().
But, It doesn't work.
How can I treat this problem?**
I hope I can solve this!
Thank you all senior developers!!
I didn't fully check all code, but in AddChildrenView there might be missing an else. Like you have it now the empty list will be always shown above your NochildrenView()
if item.children.count == 0 {
NochildrenView()
} else { // here
...

How we can adding a search bar with side bar icon to the navigation view?

I want to add a search bar to the navigation bar, but I do not know how to use search bar with sidebar icon in the same HStack. I put example screenshot with ContentView code. Any help would be appreciated.
Screenshot:
ContentView:
struct ContentView: View {
#State private var isShowing = false
var body: some View {
ZStack {
if isShowing {
SideMenuView(isShowing: $isShowing)
}
TabView {
NavigationView {
HomeView()
.navigationBarItems(leading: Button(action: {
withAnimation(.spring()) {
isShowing.toggle()
}
} , label: {
Image(systemName: "list.bullet")
}))
}
.tabItem {
Image(systemName: "1.circle")
Text("Page 1")
}
NavigationView {
HomeTwoView()
.navigationBarItems(leading: Button(action: {
withAnimation(.spring()) {
isShowing.toggle()
}
} , label: {
Image(systemName: "list.bullet")
}))
}
.tabItem {
Image(systemName: "2.circle")
Text("Page 2")
}
}
.edgesIgnoringSafeArea(.bottom)
//.cornerRadius(isShowing ? 20 : 0) //<< disabled due to strange effect
.offset(x: isShowing ? 300 : 0, y: isShowing ? 44: 0)
.scaleEffect(isShowing ? 0.8 : 1)
}.onAppear {
isShowing=false
}
}
}
As I mentioned in comments this is not possible in SwiftUI (2.0) yet. What you can do is integrating with UIKit.
Integrate with UIKit
class UIKitSearchBar: NSObject, ObservableObject {
#Published var text: String = ""
let searchController = UISearchController(searchResultsController: nil)
override init() {
super.init()
self.searchController.obscuresBackgroundDuringPresentation = false
self.searchController.definesPresentationContext = true
self.searchController.searchResultsUpdater = self
}
}
extension UIKitSearchBar: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
// Publish search bar text changes.
if let searchBarText = searchController.searchBar.text {
self.text = searchBarText
}
}
}
struct SearchBarModifier: ViewModifier {
let searchBar: UIKitSearchBar
func body(content: Content) -> some View {
content
.overlay(
ViewControllerResolver { viewController in
viewController.navigationItem.searchController = self.searchBar.searchController
}
.frame(width: 0, height: 0)
)
}
}
extension View {
func add(_ searchBar: UIKitSearchBar) -> some View {
return self.modifier(SearchBarModifier(searchBar: searchBar))
}
}
final class ViewControllerResolver: UIViewControllerRepresentable {
let onResolve: (UIViewController) -> Void
init(onResolve: #escaping (UIViewController) -> Void) {
self.onResolve = onResolve
}
func makeUIViewController(context: Context) -> ParentResolverViewController {
ParentResolverViewController(onResolve: onResolve)
}
func updateUIViewController(_ uiViewController: ParentResolverViewController, context: Context) { }
}
class ParentResolverViewController: UIViewController {
let onResolve: (UIViewController) -> Void
init(onResolve: #escaping (UIViewController) -> Void) {
self.onResolve = onResolve
super.init(nibName: nil, bundle: nil)
}
#available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func didMove(toParent parent: UIViewController?) {
super.didMove(toParent: parent)
if let parent = parent {
onResolve(parent)
}
}
}
Usage
struct Example: View {
#StateObject var searchBar = UIKitSearchBar()
var body: some View {
NavigationView {
Text("Example")
.add(searchBar)
.navigationTitle("Example")
}
}
}
In my own project I am using computed property to filter stuff, it can be helpful for you too. Here is my code:
var filteredExams: [Exam] {
examModel.exams.filter({ searchBar.text.isEmpty || $0.examName.localizedStandardContains(searchBar.text)})
}
Screenshot

View automatically jumps to Multiline Text Field

My SwiftUI View is kinda acting weird since i added a MultilineTextField. When pressing a item on the List, the view kind jumps back and forth and then it jumps automatically to the last text field in the view as seen in this video. This just happened after i added a MultilineTextField at the end.
MultilineTextField definition:
import Foundation
import SwiftUI
import UIKit
fileprivate struct UITextViewWrapper: UIViewRepresentable {
typealias UIViewType = UITextView
#Binding var text: String
#Binding var calculatedHeight: CGFloat
var onDone: (() -> Void)?
func makeUIView(context: UIViewRepresentableContext<UITextViewWrapper>) -> UITextView {
let textField = UITextView()
textField.delegate = context.coordinator
textField.isEditable = true
textField.font = UIFont.preferredFont(forTextStyle: .body)
textField.isSelectable = true
textField.isUserInteractionEnabled = true
textField.isScrollEnabled = false
textField.backgroundColor = UIColor.clear
if nil != onDone {
textField.returnKeyType = .done
}
textField.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
return textField
}
func updateUIView(_ uiView: UITextView, context: UIViewRepresentableContext<UITextViewWrapper>) {
if uiView.text != self.text {
uiView.text = self.text
}
if uiView.window != nil, !uiView.isFirstResponder {
uiView.becomeFirstResponder()
}
UITextViewWrapper.recalculateHeight(view: uiView, result: $calculatedHeight)
}
fileprivate static func recalculateHeight(view: UIView, result: Binding<CGFloat>) {
let newSize = view.sizeThatFits(CGSize(width: view.frame.size.width, height: CGFloat.greatestFiniteMagnitude))
if result.wrappedValue != newSize.height {
DispatchQueue.main.async {
result.wrappedValue = newSize.height // !! must be called asynchronously
}
}
}
func makeCoordinator() -> Coordinator {
return Coordinator(text: $text, height: $calculatedHeight, onDone: onDone)
}
final class Coordinator: NSObject, UITextViewDelegate {
var text: Binding<String>
var calculatedHeight: Binding<CGFloat>
var onDone: (() -> Void)?
init(text: Binding<String>, height: Binding<CGFloat>, onDone: (() -> Void)? = nil) {
self.text = text
self.calculatedHeight = height
self.onDone = onDone
}
func textViewDidChange(_ uiView: UITextView) {
text.wrappedValue = uiView.text
UITextViewWrapper.recalculateHeight(view: uiView, result: calculatedHeight)
}
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if let onDone = self.onDone, text == "\n" {
textView.resignFirstResponder()
onDone()
return false
}
return true
}
}
}
struct MultilineTextField: View {
private var placeholder: String
private var onCommit: (() -> Void)?
#Binding private var text: String
private var internalText: Binding<String> {
Binding<String>(get: { self.text } ) {
self.text = $0
self.showingPlaceholder = $0.isEmpty
}
}
#State private var dynamicHeight: CGFloat = 100
#State private var showingPlaceholder = false
init (_ placeholder: String = "", text: Binding<String>, onCommit: (() -> Void)? = nil) {
self.placeholder = placeholder
self.onCommit = onCommit
self._text = text
self._showingPlaceholder = State<Bool>(initialValue: self.text.isEmpty)
}
var body: some View {
UITextViewWrapper(text: self.internalText, calculatedHeight: $dynamicHeight, onDone: onCommit)
.frame(minHeight: dynamicHeight, maxHeight: dynamicHeight)
.background(placeholderView, alignment: .topLeading)
}
var placeholderView: some View {
Group {
if showingPlaceholder {
Text(placeholder).foregroundColor(.gray)
.padding(.leading, 4)
.padding(.top, 8)
}
}
}
}
#if DEBUG
struct MultilineTextField_Previews: PreviewProvider {
static var test:String = ""//some very very very long description string to be initially wider than screen"
static var testBinding = Binding<String>(get: { test }, set: {
// print("New value: \($0)")
test = $0 } )
static var previews: some View {
VStack(alignment: .leading) {
Text("Description:")
MultilineTextField("Enter some text here", text: testBinding, onCommit: {
print("Final text: \(test)")
})
.overlay(RoundedRectangle(cornerRadius: 4).stroke(Color.black))
Text("Something static here...")
Spacer()
}
.padding()
}
}
#endif
Code:
struct DetailZwei : View {
#State var data : dataTypeZwei
#State var viewModel = GerätEditieren()
#Environment(\.presentationMode) var presentationMode
#State private var showingAlert = false
var body : some View {
NavigationView {
ScrollView {
VStack {
Group {
Section(header: Text("")) {
Text("Seriennummer")
TextField("Seriennummer", text: $data.sn).textFieldStyle(RoundedBorderTextFieldStyle())
Text("Objekt")
TextField("Objekt", text: $data.objekt).textFieldStyle(RoundedBorderTextFieldStyle())
Text("Gerätetyp")
TextField("Gerätetyp", text: $data.typ).textFieldStyle(RoundedBorderTextFieldStyle())
Text("Geräteposition")
TextField("Geräteposition", text: $data.pos).textFieldStyle(RoundedBorderTextFieldStyle())
}
Group {
Text("Installationsdatum")
TextField("Installationsdatum", text: $data.ida).textFieldStyle(RoundedBorderTextFieldStyle())
Text("Leasing oder Gekauft?")
TextField("Leasing oder Gekauft?", text: $data.lg).textFieldStyle(RoundedBorderTextFieldStyle())
Text("Ablaufdatum Leasing")
TextField("Ablaufdatum Leasing", text: $data.la).textFieldStyle(RoundedBorderTextFieldStyle())
Text("Ablaufdatum Garantie")
TextField("Ablaufdatum Garantie", text: $data.ga).textFieldStyle(RoundedBorderTextFieldStyle())
}
Section(header: Text("")) {
Text("Strasse")
TextField("Strasse", text: $data.str).textFieldStyle(RoundedBorderTextFieldStyle())
Text("Hausnummer")
TextField("Hausnummer", text: $data.nr).textFieldStyle(RoundedBorderTextFieldStyle())
Text("Postleitzahl")
TextField("Postleitzahl", text: $data.plz).textFieldStyle(RoundedBorderTextFieldStyle())
Text("Ort")
TextField("Ort", text: $data.ort).textFieldStyle(RoundedBorderTextFieldStyle())
}
Section(header: Text("")) {
Text("Ansprechperson")
TextField("Ansprechperson", text: $data.vp).textFieldStyle(RoundedBorderTextFieldStyle())
Text("Telefonnummer")
TextField("Telefonnummer", text: $data.tel).textFieldStyle(RoundedBorderTextFieldStyle())
}
Section(header: Text("VDS").bold()) {
Text("Eingetragen durch")
TextField("Eingetragen durch", text: $data.ed).textFieldStyle(RoundedBorderTextFieldStyle())
Text("Lieferdatum VDS")
TextField("Lieferdatum VDS", text: $data.ldvds).textFieldStyle(RoundedBorderTextFieldStyle())
}
// This is the Text Field
Section(header: Text("")) {
Text("Zusätzliche Informationen")
MultilineTextField("Zusätzliche Informationen", text: $data.zusatz).overlay(RoundedRectangle(cornerRadius: 4).stroke(Color.black))
}
}.padding()
.navigationBarTitle("Gerät bearbeiten", displayMode: .inline)
.navigationBarItems(leading: Button(action: { self.handleCancelTapped() }, label: {
Text("Abbrechen")
}),
trailing: Button(action: { self.handleDoneTapped() }, label: {
Text("Speichern")
})
// .disabled(!viewModel.modified)
)
}.alert(isPresented: $showingAlert) {
Alert(title: Text("Änderungen gespeichert"), message: Text("Die Änderungen vom Gerät \(data.sn) wurden erfolgreich gespeichert!"), dismissButton: .default(Text("Zurück").bold()){
self.handleCancelTapped()
})
}
}
}
}
When you opening the view, your Custom TextField calls firstResponders. Just remove calling firstResponder on load and your view will start at the beginning.
func updateUIView(_ uiView: UITextView, context: UIViewRepresentableContext<UITextViewWrapper>) {
if uiView.text != self.text {
uiView.text = self.text
}
if uiView.window != nil, !uiView.isFirstResponder {
//uiView.becomeFirstResponder() << Here calling firstResponder
}
UITextViewWrapper.recalculateHeight(view: uiView, result: $calculatedHeight)
}
SwiftUI TextFields do not support firstResponder yet, however with Representable and using UIKit it is possible, like in your solution, Grüezi