Open jefffhaynes opened 4 years ago
@samhouts def looks like something that ought to be improved, looking at comments on #6182.
I tested with 4.0 and 4.6 RC.
@jefffhaynes I found that your example in 1 worked very well. No problems here on iOS 13.4.
The example in 3 naturally results in what you show. The layout needs to know a constraint, and in this case none is provided in a horizontal stack layout. This is perhaps something we can improve, but providing some sense of sizing would be idea. Use a FlexLayout instead and provide a Basis and/or use the Shrink/Grow to achieve the behavior you want.
<FlexLayout Direction="Row">
<Label Text="Some text" FlexLayout.Shrink="0"/>
<Editor BackgroundColor="LightBlue" AutoSize="TextChanges"/>
</FlexLayout>
Ok, I will experiment with the FlexLayout more in my specific use case. However, I'm confused as to how the first case is working for you. I am also simulating an iPhone 11 iOS 13.4 and I'm definitely having issues. FWIW, I'm doing this on the Windows simulator.
It also looks like you're doing this in some sort of navigation container whereas I'm simply nesting everything inside a ContentPage. Maybe try that?
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
ios:Page.UseSafeArea="true"
mc:Ignorable="d"
x:Class="EditorIssues.MainPage">
<StackLayout>
<Editor BackgroundColor="LightBlue" WidthRequest="200" AutoSize="TextChanges"/>
</StackLayout>
</ContentPage>
I tried using a FlexLayout without much success. It doesn't really behave the way you would expect except for in very contrived scenarios. Maybe you can give me some idea as to what I should be trying.
FWIW this is for a chat-style UI and thus far I've had no luck putting an editor at the bottom of the page and having it auto-size correctly.
As a side note, if the ListView isn't nested in a FlexLayout then it simply takes over the entire screen. I guess this is a side-effect of the ListView having broken behavior inside layouts but all of this adds up to making layout in Xamarin taxing to say the least.
<FlexLayout Direction="Column">
<!-- Header -->
<Label Text="HEADER"
FontSize="Large"
BackgroundColor="Aqua"
HorizontalTextAlignment="Center" />
<!-- Body -->
<FlexLayout FlexLayout.Grow="1">
<ListView/>
</FlexLayout>
<!-- Footer -->
<Editor FlexLayout.Basis="50" BackgroundColor="DarkGray"/>
</FlexLayout>
Edit: this problem exists irrespective of the keyboard being shown or not (e.g. if the layout is resized or padded to accommodate the keyboard on iOS).
This issue could be related (or the same) as #10417.
I think the fundamental issue here is a lack of real distinction between measure and layout. Roughly speaking, I think the layout system comes in and asks the editor how much space it needs to layout via the SizeThatFits override. The editor gives an optimistic (trivial) response and from then on the layout system is like, great, I'm just going to use that. Except what actually happens is the layout changes around the editor, affecting the element but the concept of that original measurement never changes and as far I can tell, there is no opportunity to update it.
I "fixed" this by creating a custom renderer for the editor and simply overriding SizeThatFits but using the element size, rather than the passed (optimistic) size.
public override CGSize SizeThatFits(CGSize size)
{
// ignore meaningless size
var fixedWidth = Element.Bounds.Size.Width;
var insetsWidth = Control.TextContainerInset.Right + Control.TextContainerInset.Left;
var newSize = Control.SizeThatFits(new CGSize(fixedWidth, nfloat.MaxValue));
var width = Math.Max((float)newSize.Width, (float)fixedWidth) + insetsWidth;
var height = Math.Ceiling(newSize.Height);
return new CGSize(width, height);
}
FWIW similar tricks are used in the LabelRenderer, which makes me think there is some validity to the approach. It would seem to suggest an issue with the layout system as there is no clear break between the control layout and the element layout and it isn't clear where one takes precedence vs. the other.
I must be missing something, as
<Editor
AutoSize="TextChanges"
MaxLength="80"/>
inside a StackLayout, on iOS (haven't tested other platforms) seems to completely ignore AutoSize. The editor always displays roughly five lines. The result is exactly the same as without 'AutoSize="TextChanges"'.
Is this just completely broken or am I doing something wrong? Is there any hope at all for this to get fixed? I am using Xamarin.Froms 4.8.0-pre3.
@Tommigun1980 pretty sure it's completely broken
This doesn't seem like a bug with AutoSize. A bug with AutoSize would be a scenario where a given text would layout differently if it was initially set vs typed in
AutoSize appears to be working fine here (unless I've missed something in the discussion)
For example if I take the xaml
<StackLayout Orientation="Horizontal">
<Label Text="Some text"/>
<Editor Text="oaihweifa wieuf awif aiwuiefh aiwehf aiwueh faiwuheif wuehfa iehfiuwahef aiwuif aiwieuf iawuefhlawe" BackgroundColor="LightBlue" AutoSize="TextChanges" />
</StackLayout>
The Editor will layout the same way if I start it out with a bunch of Text vs type the Text in The above SL produces the same layout on Android/iOS
If you use a Label here then the Label does wrap, so the bug seems more to do with how constraints are interpreted on an Editor
I haven't really seen here how AutoSize="TextChanges" itself is broken
Auto size does not work when text is set via binding, I don't think this requires any repro project JUST BIND EDITOR TO ANY LONG TEXT and you will have a bug with auto sizing
This is still an issue in the latest of 5.0, as is typical of the Xamarin team.
The FlexLayout is not a workaround for all scenarios. When the entry is within a ListView and a FlexLayout is used, the resulting behaviour forces UI elements out of the view when Editor wraps below.
<StackLayout Orientation="Horizontal">
<Label Text="Address:"/>
<Editor AutoSize="TextChanges"/>
</StackLayout>
This is still an issue in the latest of 5.0, as is typical of the Xamarin team.
The FlexLayout is not a workaround for all scenarios. When the entry is within a ListView and a FlexLayout is used, the resulting behaviour forces UI elements out of the view when Editor wraps below.
<StackLayout Orientation="Horizontal"> <Label Text="Address:"/> <Editor AutoSize="TextChanges"/> </StackLayout>
Yeah, can confirm AutoSize does nothing.
The last reported workaround here helped my scenario https://github.com/xamarin/Xamarin.Forms/issues/9550
@jefffhaynes Hi Jeff, I managed to fix it by creating my custom renderer and overriding OnElementPropertyChanged like this:
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (Control == null)
{
return;
}
if (e.PropertyName == "Text")
{
var contentSize = Control.SizeThatFits(Control.Bounds.Size);
Control.Frame = new CGRect(5, 0, Control.Frame.Size.Width - 2 * 5, contentSize.Height);
}
}
Hope it helps if you still have the problem :)
Description
This is basically an attempt to call attention to #6182, which was closed but appears to still be an issue.
Steps to Reproduce
Typing in the editor will result in bizarre layout behavior with additional spaces being added before the text reaches the extents of the control.
Far more problematic is something like this:
Expected Behavior
Multi-line expanding entry type behavior
Actual Behavior
Everything else
Basic Information
Screenshots