1

I am using SwiftUI 2's new TextEditor. What I'd like to do is the TextEditor to scroll to top automatically when it's text changes which currently is not the case.

animated gif of text changes without automatically scrolling to top

Here's the example project's code:

import SwiftUI

struct ContentView: View {
    @State private var text: String = Self.text1
    
    static private var text1 = """
Text 1:
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
"""
    
    static private var text2 = """
Text 2:
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
"""
    
    var body: some View {
        VStack {
            TextEditor(text: $text)
                .frame(maxHeight: 150)
            Button("Toggle Text") {
                if text == Self.text1 {
                    text = Self.text2
                } else {
                    text = Self.text1
                }
            }
        }
        
    }
}

I found a few threads concerning ScrollView that did not help, couldn't find anything on TextEditor though.

appfrosch
  • 1,146
  • 13
  • 36
  • You could try approach with `enclosingScrollView` from this https://stackoverflow.com/a/60855853/12299030 – Asperi Jan 13 '21 at 13:44
  • Do you mean I should enclose it in a ScrollView and work with a ScrollViewReader then? I am failing to work out from stated SO on how to do this in my specific case... – appfrosch Jan 13 '21 at 13:53

1 Answers1

2

Here is a possible solution using ScrollViewReader for SwiftUI 2.0 and ScrollView

var body: some View {
    ScrollViewReader { sp in
        ScrollView {
            TextEditor(text: $text)
                .id(0)
        }.frame(maxHeight: 150)

        Button("Toggle Text") {
            if text == Self.text1 {
                text = Self.text2
                sp.scrollTo(0, anchor: .top)
            } else {
                text = Self.text1
                sp.scrollTo(0, anchor: .top)
            }
        }
    }
}
davidev
  • 7,694
  • 5
  • 21
  • 56
  • Have to correct myself–works with iOS, but unfortunately not with macOS (which I did not mention as a requirement–my bad)... Do you have any suggestion for macOS (the issue being that scrolling does not work at all there with this solution...) – appfrosch Jan 13 '21 at 16:20
  • Thanks for checking. Even though I am on the same specs (macOS 11.1, Xcode 12.3), I cannot scroll. My 3rd party Logitech mouse won't do anything while my Trackpad pushes the text up or down for a second, but then moves the text back to the top by default. Giving up for today :-/ – appfrosch Jan 13 '21 at 17:28
  • 1
    You are right, it is not working on macOS. I will check it again – davidev Jan 13 '21 at 17:32
  • Thanks for confirming, @davidev. Have you had the chance to further investigate in this regard? – appfrosch Jan 18 '21 at 08:35