AXE
AXE

Reputation: 8455

Xamarin.Forms layout is empty on iOS

I have a Xamarin.Forms app that uses Alex Rainman's CarouselView (https://github.com/alexrainman/CarouselView) to present a carousel (surprise! :) ). Each page in the carousel consists of a list of items. On Android it looks like this:Android screenshot

It is similar on Windows. However, on iOS I get this:iOS screenshot

At first I thought it was a bug in the CarouselView component and submit an issue but the author said it was working fine on his side. I tried to debug it in whatever ways I could think of but couldn't find the problem. The CarouselView is instantiated and added to the view hierarchy. The ViewModel is instantiated and working fine if I replace it with say a ListView displaying the columns. Now I'm out of ideas and would really appreciate some help!

Here is my code:

MainPage.xaml:

<controls:CarouselViewControl Orientation="Horizontal" 
                                  InterPageSpacing="0"
                                  Position="0" 
                                  ItemsSource="{Binding Columns}" 
                                  VerticalOptions="FillAndExpand" 
                                  HorizontalOptions="FillAndExpand"
                                  BackgroundColor="Gray"
                              ShowIndicators="True"
                              ShowArrows="True">
    <controls:CarouselViewControl.ItemTemplate>
        <DataTemplate>
            <ContentView HorizontalOptions="FillAndExpand"
                             VerticalOptions="FillAndExpand"                                 
                             Padding="20">
                <ListView HorizontalOptions="FillAndExpand"
                              VerticalOptions="FillAndExpand"
                              BackgroundColor="LightGray"
                              Header="{Binding Name}"
                              ItemsSource="{Binding Tasks}"
                              ItemSelected="ListView_ItemSelected">
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <ImageCell ImageSource="{Binding Image}"
                                           Text="{Binding Title}"/>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
            </ContentView>
        </DataTemplate>
    </controls:CarouselViewControl.ItemTemplate>
</controls:CarouselViewControl>

(The code behind just calls InitializeComponent() in the constructor)

ColumnsViewModel.cs:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace ProofOfConcept
{
    public class ColumnsViewModel : BindableObject
    {
        public static readonly BindableProperty PositionProperty = BindableProperty.Create(nameof(Position), typeof(int), typeof(ColumnsViewModel), 0, BindingMode.TwoWay);

        public ObservableCollection<Column> Columns { get; set; }

        public int Position
        {
            get { return (int)this.GetValue(PositionProperty); }
            set { this.SetValue(PositionProperty, value); }
        }

        public ColumnsViewModel()
        {
            Columns = new ObservableCollection<Column>();

            Random random = new Random();
            for (int i = 0; i < 10; i++)
            {
                Column column = new Column
                {
                    Name = String.Format("Column {0}", i),
                    Background = Color.FromRgb(random.Next(0, 255), random.Next(0, 255), random.Next(0, 255))
                };

                ObservableCollection<Task> tasks = new ObservableCollection<Task>();
                for (int t = 0; t < 25; t++)
                {
                    Task task = new Task
                    {
                        Title = String.Format("Column #{0}, Task #{1}", i, t),
                        Color = Color.Lavender
                    };
                    tasks.Add(task);
                }
                column.Tasks = tasks;

                Columns.Add(column);
            }
        }
    }
}

Column.cs:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace ProofOfConcept
{
    public class Column
    {
        public string Name { get; set; }
        public ObservableCollection<Task> Tasks { get; set; }
        public Color Background { get; set; }
        public string Image
        {
            get
            {
                return "http://loremflickr.com/100/100";
            }
        }
    }
}

Task.cs:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace ProofOfConcept
{
    public class Task : BindableObject
    {
        public static readonly BindableProperty ColorProperty = BindableProperty.Create(nameof(Color), typeof(Color), typeof(Task), Color.White, BindingMode.TwoWay);

        public string Title { get; set; }
        public string Assignee
        {
            get
            {
                return "Ivan";
            }
        }

        public Color Color
        {
            get { return (Color)this.GetValue(ColorProperty); }
            set { this.SetValue(ColorProperty, value); }
        }

        public string Image
        {
            get
            {
                return "http://loremflickr.com/100/100";
            }
        }
    }
}

Also, here is a zip of the whole solution (without the Windows project since it was very big and not really relevant).

Upvotes: 0

Views: 431

Answers (2)

Microwales
Microwales

Reputation: 11

In case anyone have this issues in iOS even after calling "init". You can try giving height request to the CarouselViewControl. This is mostly the case if the control is in a grid and you are using Auto for RowDefinitin.Height

Upvotes: 0

Alessandro Caliaro
Alessandro Caliaro

Reputation: 5768

Usage

In your iOS and Android projects call:

Xamarin.Forms.Init();
CarouselViewRenderer.Init();





    namespace ProofOfConcept.iOS
    {
        // The UIApplicationDelegate for the application. This class is responsible for launching the 
        // User Interface of the application, as well as listening (and optionally responding) to 
        // application events from iOS.
        [Register("AppDelegate")]
        public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
        {
            //
            // This method is invoked when the application has loaded and is ready to run. In this 
            // method you should instantiate the window, load the UI into it and then make the window
            // visible.
            //
            // You have 17 seconds to return from this method, or iOS will terminate your application.
            //
            public override bool FinishedLaunching(UIApplication app, NSDictionary options)
            {
                global::Xamarin.Forms.Forms.Init();
                CarouselViewRenderer.Init();
                LoadApplication(new App());

                return base.FinishedLaunching(app, options);
            }
        }
    }

Upvotes: 1

Related Questions