Home>
Premise, what I want to achieve

To realize a GUI that displays details when a button is pressed
I created the following control

<? xml version = "1.0" encoding = "UTF-8"?>
<ContentView xmlns = "http://xamarin.com/schemas/2014/forms"
             xmlns: x = "http://schemas.microsoft.com/winfx/2009/xaml"
             x: Class = "App1.View1">
  <ContentView.Content>
      <Grid>
          <Grid.RowDefinitions>
              <RowDefinition Height = "64" />
              <RowDefinition x: Name = "Height" Height = "0" />
          </Grid.RowDefinitions>
          <Button Grid.Row = "0" Text = "{Binding}" Clicked = "Button_Clicked" />
          <Grid Grid.Row = "1" IsClippedToBounds = "True" BackgroundColor = "Red">
              <Label Text = "{Binding}" />
          </Grid>
      </Grid>
  </ContentView.Content>
</ContentView>
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace App1
{
    [XamlCompilation (XamlCompilationOptions.Compile)]
    public partial class View1: ContentView
    {
        public View1 () =>InitializeComponent ();
        private void Button_Clicked (object sender, EventArgs e)
        {
            if (Height.Height.Value == 256)
                Height.Height = 0;
            else else
                Height.Height = 256;
        }
    }
}


I used this control in the Template of ListView as follows.

<? xml version = "1.0" encoding = "utf-8"?>
<ContentPage xmlns = "http://xamarin.com/schemas/2014/forms"
             xmlns: x = "http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns: local = "clr-namespace: App1"
             x: Class = "App1.MainPage">
  <Grid BackgroundColor = "Yellow" Margin = "64">
      <ListView HasUnevenRows = "True" x: Name = "list">
          <ListView.ItemTemplate>
              <DataTemplate>
                  <ViewCell>
                      <local: View1 BindingContext = "{Binding}" />
                  </ViewCell>
              </DataTemplate>
          </ListView.ItemTemplate>
      </ListView>
  </Grid>
</ContentPage>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace App1
{
    public partial class MainPage: ContentPage
    {
        public MainPage ()
        {
            InitializeComponent ();
            List<string>urls = new List<string>();
            urls.Add ("https://www.google.com/");
            urls.Add ("https://www.yahoo.com/");
            list.ItemsSource = urls;
        }
    }
}


On Android, a list of buttons displaying the URL is displayed as desired, and when the button is pressed, the area for detailed display is expanded below it, and the height of the items in the list is changed accordingly.

However, on iOS, it does not behave as desired and the display is corrupted.
Does not respond to button presses
The detailed display area is expanded in a state where the height of the item does not change and overlaps
If i repeat the development many times, another item that should be underneath may come out at the top
It behaves strangely.

Isn't such a UI possible on iOS?

Development environment

No real iPhone iOS v14.1
macOS Catalina v10.15.7
Visual Studio for mac v8.8 (build 2913)
Xcode v12.1 (12A7403)

  • Answer # 1

    How about doing the following? The height data is also bound, and redrawing is performed when the button is pressed.

    public partial class MainPage: ContentPage
    {
        public MainPage ()
        {
            InitializeComponent ();
            List<Item>urls = new List<Item>();
            urls.Add (new Item)
            {
                Url = "https://www.google.com/"
            });
            urls.Add (new Item)
            {
                Url = "https://www.yahoo.com/"
            });
            urls.Add (new Item)
            {
            });
            list.ItemsSource = urls;
        }
    }
    public class Item
    {
        public string Url {get;set;}
        public int Height {get;set;}
    }
    <? xml version = "1.0" encoding = "UTF-8"?>
    <ContentView xmlns = "http://xamarin.com/schemas/2014/forms"
                 xmlns: x = "http://schemas.microsoft.com/winfx/2009/xaml"
                 x: Class = "App1.View1">
      <ContentView.Content>
          <Grid>
              <Grid.RowDefinitions>
                  <RowDefinition Height = "64" />
                  <RowDefinition x: Name = "Height" Height = "{Binding Height}" />
              </Grid.RowDefinitions>
              <Button Grid.Row = "0" Text = "{Binding Url}" Clicked = "Button_Clicked" />
              <Grid Grid.Row = "1" IsClippedToBounds = "True" BackgroundColor = "Red">
                  <Label Text = "{Binding Url}" />
              </Grid>
          </Grid>
      </ContentView.Content>
    </ContentView>
    using System;
    using Xamarin.Forms;
    using Xamarin.Forms.Xaml;
    namespace App1
    {
        [XamlCompilation (XamlCompilationOptions.Compile)]
        public partial class View1: ContentView
        {
            public View1 () =>InitializeComponent ();
            private void Button_Clicked (object sender, EventArgs e)
            {
                var item = BindingContext as Item;
                if (item.Height == 256)
                    item.Height = 0;
                else else
                    item.Height = 256;
                var listView = Parent.Parent as ListView;
                var source = listView.ItemsSource;
                listView.ItemsSource = null;
                listView.ItemsSource = source;
            }
        }
    }