I have a large amount of text, that I would like to display in a Text() view. If I wrap the view in a ScrollView I am able to scroll in either .horizontal, or .vertical direction.
However if I want scrolling in both directions, the layout is completely wrong. Almost as if there is a negative offset.
import SwiftUI
struct ContentView: View {
let text = """
<?xml version="1.0"?>
<PrettyXML>
<root xmlns="urn:schemas-upnp-org:device-1-0" xmlns:dlna="urn:schemas-dlna-org:device-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<device>
<deviceType>urn:schemas-upnp-org:device:MediaRenderer:2</deviceType>
<friendlyName>Sample Renderer</friendlyName>
<manufacturer></manufacturer>
<manufacturerURL></manufacturerURL>
<modelDescription/>
<modelName>Test device</modelName>
<modelNumber/>
<modelURL></modelURL>
<serialNumber>12354-12312789-123987129873</serialNumber>
<UDN>uuid:12312311-1234-1234-1234-123456789011</UDN>
<iconList>
<icon>
<mimetype>image/png</mimetype>
<width>120</width>
<height>120</height>
<depth>24</depth>
<url>/image-120x120x24.png</url>
</icon>
<icon>
<mimetype>image/png</mimetype>
<width>48</width>
<height>48</height>
<depth>24</depth>
<url>/image-48x48x24.png</url>
</icon>
<icon>
<mimetype>image/jpeg</mimetype>
<width>120</width>
<height>120</height>
<depth>24</depth>
<url>/image-120x120x24.jpg</url>
</icon>
<icon>
<mimetype>image/jpeg</mimetype>
<width>48</width>
<height>48</height>
<depth>24</depth>
<url>/image-48x48x24.jpg</url>
</icon>
</iconList>
<serviceList>
<service>
<serviceType>urn:schemas-upnp-org:service:ConnectionManager:2</serviceType>
<serviceId>urn:upnp-org:serviceId:ConnectionManager</serviceId>
<SCPDURL>/xml/ConnectionManager.xml</SCPDURL>
<controlURL>/Control/ConnectionManager</controlURL>
<eventSubURL>/Event/ConnectionManager</eventSubURL>
</service>
<service>
<serviceType>urn:schemas-upnp-org:service:AVTransport:2</serviceType>
<serviceId>urn:upnp-org:serviceId:AVTransport</serviceId>
<SCPDURL>/xml/AVTransport2.xml</SCPDURL>
<controlURL>/Control/AVTransport</controlURL>
<eventSubURL>/Event/AVTransport</eventSubURL>
</service>
<service>
<serviceType>urn:schemas-upnp-org:service:RenderingControl:2</serviceType>
<serviceId>urn:upnp-org:serviceId:RenderingControl</serviceId>
<SCPDURL>/xml/RenderingControl2.xml</SCPDURL>
<controlURL>/Control/Renderer/RygelRenderingControl</controlURL>
<eventSubURL>/Event/Renderer/RygelRenderingControl</eventSubURL>
</service>
</serviceList>
<presentationURL>http://10.0.0.1:80/</presentationURL>
<dlna:X_DLNADOC>DMR-1.51</dlna:X_DLNADOC>
</device>
</root>
"""
var body: some View {
// ScrollView(.horizontal) {
// ScrollView(.vertical) {
ScrollView([.horizontal, .vertical]) {
Text(text)
}
}
}
Is there a better approach to this, or is it just a bug that has no workaround currently? My only other thought would be to use a wrapped UITextView, which will only allow vertical scrolling, but if there is a way to manually set the frame width to be as large as necessary, then allow the ScrollView to only scroll horizontally.
An incredibly ugly way of solving this would be:
ScrollView(.horizontal, showsIndicators: false) {
ScrollView(.vertical, showsIndicators: false) {
Text(text)
}
}
However this only allows scrolling in one direction at a time which just feels unnatural.
It seems like this behaviour is also tied to updating views. Consider the following example which simulates an redraw:
struct ContentView: View {
@State var labelText = "Loading"
let text = """
<?xml version="1.0"?>
<PrettyXML>
<root xmlns="urn:schemas-upnp-org:device-1-0" xmlns:dlna="urn:schemas-dlna-org:device-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<device>
<deviceType>urn:schemas-upnp-org:device:MediaRenderer:2</deviceType>
<friendlyName>Sample Renderer</friendlyName>
<manufacturer></manufacturer>
<manufacturerURL></manufacturerURL>
<modelDescription/>
<modelName>Test device</modelName>
<modelNumber/>
<modelURL></modelURL>
<serialNumber>12354-12312789-123987129873</serialNumber>
<UDN>uuid:12312311-1234-1234-1234-123456789011</UDN>
<iconList>
<icon>
<mimetype>image/png</mimetype>
<width>120</width>
<height>120</height>
<depth>24</depth>
<url>/image-120x120x24.png</url>
</icon>
<icon>
<mimetype>image/png</mimetype>
<width>48</width>
<height>48</height>
<depth>24</depth>
<url>/image-48x48x24.png</url>
</icon>
<icon>
<mimetype>image/jpeg</mimetype>
<width>120</width>
<height>120</height>
<depth>24</depth>
<url>/image-120x120x24.jpg</url>
</icon>
<icon>
<mimetype>image/jpeg</mimetype>
<width>48</width>
<height>48</height>
<depth>24</depth>
<url>/image-48x48x24.jpg</url>
</icon>
</iconList>
<serviceList>
<service>
<serviceType>urn:schemas-upnp-org:service:ConnectionManager:2</serviceType>
<serviceId>urn:upnp-org:serviceId:ConnectionManager</serviceId>
<SCPDURL>/xml/ConnectionManager.xml</SCPDURL>
<controlURL>/Control/ConnectionManager</controlURL>
<eventSubURL>/Event/ConnectionManager</eventSubURL>
</service>
<service>
<serviceType>urn:schemas-upnp-org:service:AVTransport:2</serviceType>
<serviceId>urn:upnp-org:serviceId:AVTransport</serviceId>
<SCPDURL>/xml/AVTransport2.xml</SCPDURL>
<controlURL>/Control/AVTransport</controlURL>
<eventSubURL>/Event/AVTransport</eventSubURL>
</service>
<service>
<serviceType>urn:schemas-upnp-org:service:RenderingControl:2</serviceType>
<serviceId>urn:upnp-org:serviceId:RenderingControl</serviceId>
<SCPDURL>/xml/RenderingControl2.xml</SCPDURL>
<controlURL>/Control/Renderer/RygelRenderingControl</controlURL>
<eventSubURL>/Event/Renderer/RygelRenderingControl</eventSubURL>
</service>
</serviceList>
<presentationURL>http://10.0.0.1:80/</presentationURL>
<dlna:X_DLNADOC>DMR-1.51</dlna:X_DLNADOC>
</device>
</root>
"""
var body: some View {
ScrollView([.horizontal, .vertical]) {
Text(self.labelText)
}
.onAppear() {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.4) {
self.labelText = self.text
}
}
}
}