listView ViewCell not adjusting it's size to content on iOS

I have a custom ViewCell that i use to populate a listView. It works like a charm on android, on iOS however i'm having issues.

The cell has a Horizontal stackLayout with a box and a 2nd stackLayout, the 2nd Stacklayout is vertical and has 2 labels.
On iOS if the labels has multiple rows of content the text overlaps the cell below. On Android it works just fine.

This is my code, what am i doing wrong?

public class NewsCell : ViewCell
    {
        public NewsCell ()
        {
            var headerLabel = new Label();
            var contentLabel = new Label();

            headerLabel.SetBinding(Label.TextProperty, "header");
            contentLabel.SetBinding(Label.TextProperty, "content");

            this.View = new StackLayout {
                Padding = new Thickness (0, 5),
                Orientation = StackOrientation.Horizontal,
                Children = {
                    new BoxView {
                        Color = Color.Accent,
                        WidthRequest = 50,
                        HeightRequest = 50
                    },
                    new StackLayout {
                        Spacing = 0,
                        Children = {
                            headerLabel,
                            contentLabel
                        }
                    }
                }

            };
        }
    }
«1

Posts

  • CraigDunnCraigDunn USXamarin Team Xamurai

    Xamarin.Forms on iOS does not yet support automatically adjusting the height of cells, you need to manually set the height of rows (their Height property) as well as set HasUnevenRows = true. This is tricky because there's no easy way to calculate the required height - you end up having to estimate.

    It's come up a few times on the forums.

    While not an ideal solution, one approach is demonstrated in this Speaker cell in the Evolve sample app.

  • PedroNeves.7715PedroNeves.7715 USMember ✭✭

    Is this issue solved now?

  • MichaelRumplerMichaelRumpler ATMember ✭✭✭✭✭

    @PedroNeves.7715 Nope

  • JMarcusJMarcus USMember ✭✭✭

    This works properly for me.

  • Taimoor.JanjuaTaimoor.Janjua DEMember ✭✭

    @JMarcus
    what works properly for you? strange issue with viewcell in forms iOS, it works perfectly in forms android.

  • CraigDunnCraigDunn USXamarin Team Xamurai

    The HasUnevenRows = true was fixed for iOS a while ago (around the time iOS 8 came out, late last year). You can see it working in the WorkingWithListView sampe (see the attached image, where different paragraphs of text make the cell automatically resize.

    image

  • Quan.HoangQuan.Hoang USMember

    @CraigDunn HasUnevenRows = true does work for me when I have all the elements of the Custom Cell appear on page loading. My issue is, on the iOS platform, when I set certain elements of my Custom Cell to display only after a button clicked event, the cell height is not expanding to fit the new elements. The result is that the new elements overlay over the top of the other cells. This only occur on iOS. The Android works perfectly.

  • MiguelCervantesMiguelCervantes MXMember ✭✭✭

    I'm facing the same working with XF 1.5.1 hasUnevenRows doesn't work when data is loading async. Any ideas?

  • TheRealJasonSmithTheRealJasonSmith USXamarin Team Xamurai
    edited October 2015

    its a known limitation of the iOS situation. We're still debating the best approach because the performance implications are pretty large. I would prefer users have to do something to trigger the resize, perhaps on all paltforms but certainly on iOS where the hit will be most noticeable. At least if users have to trigger the resize they can see where the performance hit comes from.

  • Quan.HoangQuan.Hoang USMember

    For my app, I have a chevron button that triggers the details to be displayed upon clicked... @TheRealJasonSmith Is this the trigger for resize that you are referring to? Otherwise, HasUnevenRows is working appropriately if I have all of the information displayed upfront.

  • TheRealJasonSmithTheRealJasonSmith USXamarin Team Xamurai

    The idea would be for you to call some sort of API that would allow a single update pass for the resize

  • ShaneNeuvilleShaneNeuville USUniversity ✭✭

    I'm all for that @TheRealJasonSmith :-) I've been having issues with this on WINRT where the binding content sometimes needs to make the viewcell expand or the user clicking on the cell needs to make it expand..... It's interesting because it's trivial to make dynamic expanding rows in native WINRT but I can't quite get Xam Forms to cooperate :-/ If I force the ViewCell height I can make it work... But then I have to calculate things which is never fun.,... An API call on the ViewCell would be nice... this.RecalculateSizePlease() Especially when I change visibility of things inside the cell's in a "More details" fashion

  • DavidDancyDavidDancy AUMember ✭✭✭✭

    @ShaneNeuville you might want to join in here.

  • TheRealJasonSmithTheRealJasonSmith USXamarin Team Xamurai

    @ShaneNeuville making it work on RT is not a problem, it merely doesn't because we didn't make it. We need a proper method to address the problem. RecalculateSizePlease (as you called it) is the current leading contender.

  • Quan.HoangQuan.Hoang USMember

    +1 for this API call.

  • ShaneNeuvilleShaneNeuville USUniversity ✭✭

    @TheRealJasonSmith Aw ok well good to know I'm not doing something wrong :-) I wasn't sure if there was a particular layout or cell structure I could use which would cause the cell to resize dynamically... I feel your pain on making this thing work... I just finished up some dynamic click expandable cell things in iOS using autolayouts and it was a PITA.... Took me about 5 minutes in XAML :-/ It might just be because I have 10 years more experience in XAML :-)
    either way
    PITA

  • TheRealJasonSmithTheRealJasonSmith USXamarin Team Xamurai

    The problem isn't making it work nicely for a single cell, like always its making it work nicely for ALL cells :( So many edge cases.

  • Quan.HoangQuan.Hoang USMember

    @ShaneNeuville I worked on the expandable cells for a little while, and really it was more trouble than it's worth for my case. I just put in a workaround for now by placing the cells inside a frame and inside a stack with a fixed height. It basically has a "card" feel. So this is alright for now, but I think ideally the expandable cell is where I want to take it.

    @TheRealJasonSmith I'm glad that you guys are at least looking at this issue. I know you have other big fish to fry, and knowing that it is on Xamarin's radar makes me feel much better.

  • JohnHardmanJohnHardman GBUniversity mod
    edited June 2016

    @TheRealJasonSmith - Since your post here in October 2015, has a solution been implemented for this? It seems that there are a lot of people struggling with this problem.

    Given that scrolling the ListView containing the ViewCell to be resized can make this work (e.g. if the first item in the list needs to be resized, scroll to the end of the list and then back again), what is it that scrolling triggers that lays out the cell again? Is this something we can access to force the layout to be done again without scrolling first? Just calling ForceLayout does not do it - there's something else that needs to happen.

  • JohnHardmanJohnHardman GBUniversity mod

    @TheRealJasonSmith - In the previous post, I should have said "manually scrolling", as there is a separate bug ( https://bugzilla.xamarin.com/show_bug.cgi?id=28277 ) when trying to programmatically scroll when using uneven rows.

    The question remains though - what is it that manually scrolling a ListView does that results in a ViewCell being presumably repopulated and its new height calculated and taken into account? I'm guessing that in the RecycleElement caching strategy code, it not only repopulates ViewCells and lays out the child views, but also signals the containing ListView of the new ViewCell height when a cell scrolls into view. If that's the case, is there any way we can force that to happen on iOS when we change the content of a ViewCell (and hence its desired height) that has already been displayed, whether using bindings or otherwise? Can that be done when the cell that needs to change height is in the middle of the display, rather than being scrolled out and in again?

    It does seem bizarre that re-sizing works out of the box when using XF on Android and Windows platforms, but requires this much work on iOS.

  • why_vincentwhy_vincent SEMember

    @JohnHardman is right. I've been working on this for 3 days now. Stackoverflow and google gives me nothing. Very strange that such a standard case cannot be done for iOS. Tested scrolling and when I do that then the cell resizes properly. I would like to find what manual scrolling is calling and call that method as you suggest. Gotten any progress when it comes to this? This is a deal breaker for me, will have to leave Xamarin.Forms if these type of workarounds are frequent.

  • JohnHardmanJohnHardman GBUniversity mod

    @why_vincent - I haven't done it yet as I've been delaying in the hope that a Xamarin.Forms update would resolve this. There has been mention of related bits in release notes, including a change pushed by somebody else who was hitting this problem, so I'm hoping the next stable release will contain something useful.

    If not, then I reckon the answer on iOS will be to delete the underlying data item from the collection and then insert it back in at the same position it had before. At best it will cause a bit of flicker, possibly even some scrolling. At worst... well, it might not work. But that will be my next course of investigation if the next stable release doesn't contain a fix.

  • JohnHardmanJohnHardman GBUniversity mod

    @why_vincent - It appears that there is a new XF version in the stable channel. The release notes are not yet visible where I would expect them, but you might want to try this new version as I believe it should fix a regression on the use of uneven rows.

  • why_vincentwhy_vincent SEMember

    @JohnHardman Thanks for your advice. I am going to try that now. If that doesn't work, would you try to implement it on Xamarin.iOS or that would be messy? To inject a listview like that. Is native the only way to go if you want something like this? This is my first time developing an app so I am fully aware of the no0biness of my questions.

  • JohnHardmanJohnHardman GBUniversity mod

    @why_vincent - I'll be trying the latest stable release before spending more time investigating other options. I don't like to think how much time I spent trying various options that didn't involve removing and re-inserting data. Let's just say that I don't want to spend more time on it unless absolutely necessary :-)

  • why_vincentwhy_vincent SEMember

    @JohnHardMan Fully agree. Speculating with a pessimistic mindset can be quite unpractical when developing =) I just updated to the latest stable release and sadly that didn't help me. If the cell has the correct size when the ContentPage is loaded then it's looking fine. If I resize it after that it overlaps. Scrolling still fixes it. Tried deleting and inserting cells but it is not working for me. I feel like it should, hence I'm assuming that I am doing something stupid.

    I have my ViewModel here( http://codepaste.net/j1efmx ) if you'd have a minute to see the setter of my "AllItems" property. I'm simply trying to clear the list then reload the items again, but I'm doing something wrong. Fully get it if you don't have time.

  • JohnHardmanJohnHardman GBUniversity mod

    @why_vincent - I'm in the midst of a major re-factoring right now. Once it's done, I'll update to the latest stable and see what happens.

  • why_vincentwhy_vincent SEMember

    @JohnHardman

    Thanks.

  • lucascclucascc BRMember

    Any news on this issue? I updated to the latest XF version and it doesn't seem to be fixed :(

  • SumeetKaleSumeetKale INMember

    Any update on this issue please ? I have been working for last 30 hours on this. I even tried ForceUpdateSize method of ViewCells, still not working

  • J-YenJ-Yen USMember ✭✭
    edited November 2016

    Any update on this issue please? How can i change the height of a ViewCell? On Android using the Height property of ViewCell works fine, but on iOS notting happens.

  • Neil-PepperNeil-Pepper GBUniversity ✭✭

    I have just come across this issue too. Have a button that expands a cell in a ListView, pretty common UX on mobile. Setting the height on the cell works great on Android, but no joy on iOS.

    @TheRealJasonSmith whats xamarin's latest thinking on this issue ?

    Are there any work arounds in the mean time however messy for now ?

    thanks

  • Neil-PepperNeil-Pepper GBUniversity ✭✭
    edited November 2016

    OK here is Xamarin forms official function to do this on ioS

    https://developer.xamarin.com/samples/xamarin-forms/UserInterface/ListView/DynamicUnevenListCells/

    but I found it poor UI, it seems to attempt to animate the cell getting bigger and looked poor on ios emulator at least , and android was ok anyway.

    So I now post a notification after i change the height to be picked up by the iOS listview customer renderer which just calls, tableView.ReloadData();, not pretty code but works nicely.

        static void HeightChanging(BindableObject bindable, object oldValue, object newValue)
            {
                var cell = (MyCell)bindable;
    
                cell.Height = (float)newValue;
    
                if((float)oldValue!=0)
                    MessagingCenter.Send<JobCell>(cell, "RefeshList");
            }
    
         public ListViewRenderer()
            {
                MessagingCenter.Subscribe<JobCell>(this, "RefeshList", (args) =>
                {
                    var tableView = (UITableView)Control;
                    if(tableView!=null)
                        tableView.ReloadData();
                });
            }
    
  • Neil-PepperNeil-Pepper GBUniversity ✭✭

    thanks @rmarinho thats the same post and technique I posted couple of hours ago. As i said it has poor experience for user as it seems to try and animate the cell resize.

    thanks anyway

  • RaymondKellyRaymondKelly USMember ✭✭✭

    There is a pull request to fix the weird animation that occurs but no idea if its made its way into a stable release yet.

  • TiagoFloresTiagoFlores PTMember
    edited December 2016

    My Code based on Neil Pepper Idea:
    public class CustomImage: Image
    {
    public CustomImage():base()
    {
    base.SizeChanged += CustomImage_SizeChanged;
    }

        private void CustomImage_SizeChanged(object sender, EventArgs e)
        {
            var height = ((CustomImage)sender).Height;
            var source = this.Source?.ToString();
    
            if (source == null)
                return;
         
            if (height > 1)
            {
                MessagingCenter.Send<CustomImage>(this, "ImageSizeChanged");
            }
           
        }
    }
    

    ListView Custom Renderer:
    [assembly: ExportRenderer(typeof(ListView), typeof(CustomListViewRenderer))]
    namespace XamarinForms.iOS.CustomRenderers
    {
    public class CustomListViewRenderer: ListViewRenderer
    {
    protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.ListView> e)
    {
    base.OnElementChanged(e);

            if (Control == null)
                return;
    
            var tableView = (UITableView) Control;
    
            MessagingCenter.Subscribe<CustomImage>(this, "ImageSizeChanged", (sender) => {
                if (tableView != null && tableView.DataSource !=null) {
                    tableView.ReloadData();
                }
                else
                {
                    
                    MessagingCenter.Unsubscribe<CustomImage>(this, "ImageSizeChanged");
                }
            });
    
    
        }
    
        
    }
    

    }

  • TiagoFloresTiagoFlores PTMember

    It seems that is more faster and reliable do it manually instead of relying on the default binding.
    https://github.com/luberda-molinet/FFImageLoading/wiki/Xamarin.Forms-Advanced

  • ClapotiClapoti CAMember ✭✭

    I also have the same problem on iOS... I have a "show more" button in a view cell (it contains a grid) which shows more text in a label... the text takes all the space it needs, but the viewcell doesn't resize.
    It works flawlessly on Android.
    Anybody found a solution ?

«1
Sign In or Register to comment.