Quantcast
Channel: Xamarin.Forms — Xamarin Community Forums
Viewing all articles
Browse latest Browse all 77050

iOS - Crash on StackLayout Children.Clear()

$
0
0

Hey, i'm having trouble figuring out why my app is crashing. It works fine on Android, but on iOS I get

System.NullReferenceException
Object reference not set to an instance of an object

I attached my iOS device crash logs. Here is part of it...

...
Exception Type: EXC_BAD_ACCESS (SIGABRT)
Exception Subtype: KERN_INVALID_ADDRESS at 0x00000000
...
13 StreetSupervisorIOS 0x016028fc handle_signal_exception (exceptions-arm.c:530)
14 StreetSupervisorIOS 0x0123a6d4 Xamarin_Forms_Platform_iOS_VisualElementPackager_HandleChildRemoved_object_Xamarin_Forms_ElementEventArgs + 268
...

Here are snippets of my code. It crashes on layout.Children.Clear(), but not every time. Neither layout nor layout.Children is null, but I still get the NullReferenceException...

    // UserList is a StackLayout in my xaml containted within UserScrollList (ScrollView)
    // UserRows contains the RelativeLayouts that I will put in the UserList
    UserRows = new Dictionary<int, RelativeLayout>();


    private void ClearUserRows()
    {
        Log.Debug("Clearing UserView rows");
        foreach (RelativeLayout layout in UserRows.Values)
        {
            layout.Children.Clear ();  //CRASHES HERE
        }

        UserRows.Clear();
        UserList.Children.Clear();
        this.UserListScroll.IsClippedToBounds = false;
        this.UserListScroll.IsClippedToBounds = true;
    }

    public void CreateUserRows()
    {
        ClearUserRows ();

        List<UserEntry> sortedUsers = ViewModel.OnlineUsers.OrderBy(ue => ue.Fullname).ToList();

        // Remove the UserList temporarily so the layout doesn't recalculate a million times during the loop.  It was taking a long time before
        this.UserListScroll.Content = null;
        foreach (UserEntry ue in sortedUsers) 
        {
            Label name = new Label ();
            name.HorizontalOptions = LayoutOptions.StartAndExpand;
            name.Text = ue.Fullname;
            name.YAlign = TextAlignment.Center;
            name.TextColor = (Color)this.Resources ["TextColor"];
            name.Font = Font.SystemFontOfSize (20);

            Image chkBackground = new Image ();
            chkBackground.HorizontalOptions = LayoutOptions.End;
            chkBackground.IsVisible = true;
            chkBackground.Aspect = Aspect.Fill;

            if(ue.Selected)
            {
                chkBackground.Source = Device.OnPlatform (
                    iOS: CHECKBOX_CHECKED,
                    Android: CHECKBOX_CHECKED,
                    WinPhone: CHECKBOX_CHECKED);
            }else
            {
                chkBackground.Source = Device.OnPlatform (
                    iOS: CHECKBOX_EMPTY,
                    Android: CHECKBOX_EMPTY,
                    WinPhone: CHECKBOX_EMPTY);
            }

            BetterButton clickDetector = new BetterButton ();
            clickDetector.Opacity = 1;
            clickDetector.BackgroundColor = Color.Transparent;
            clickDetector.Text = "";
            clickDetector.CommandParameter = ue.EmployeeID;
            clickDetector.Command = ViewModel.UserClicked;

            RelativeLayout layout = new RelativeLayout ();
            layout.HorizontalOptions = LayoutOptions.StartAndExpand;
            layout.HeightRequest = 40;
            layout.WidthRequest = 1000000000;

            layout.Children.Add (name,
                Constraint.Constant (15),
                Constraint.Constant (0),
                Constraint.RelativeToParent ((parent) => {
                    return parent.Width * 0.8;
                }),
                Constraint.RelativeToParent ((parent) => {
                    return parent.Height;
                }));

            layout.Children.Add (chkBackground,
                Constraint.RelativeToParent ((parentView) => {
                    return parentView.Width - 30;
                }),
                Constraint.RelativeToParent ((parentView) => {
                    return (parentView.Height * 0.5) - 11;
                }),
                Constraint.Constant (22),
                Constraint.Constant (22));

            layout.Children.Add (clickDetector,
                Constraint.Constant (-5),
                Constraint.Constant (-5),
                Constraint.RelativeToParent ((parent) => {
                    return parent.Width + 10;
                }),
                Constraint.RelativeToParent ((parent) => {
                    return parent.Height + 10;
                }));
            if(!UserRows.ContainsKey(ue.EmployeeID))
                UserRows.Add (ue.EmployeeID, layout);

            this.UserList.Children.Add (layout);
        }
        this.UserListScroll.Content = this.UserList;
        this.UserListScroll.IsClippedToBounds = false;
        this.UserListScroll.IsClippedToBounds = true;
    }

It is probably worth noting that the crash is relatively new. Before I added these lines

    // Remove the UserList temporarily so the layout doesn't recalculate a million times during the loop.  It was taking a long time before
        this.UserListScroll.Content = null;

    //loop

    this.UserListScroll.Content = this.UserList;

it worked fine. The reason I remove the list and put it back is that the list was taking very long to load on iOS. When I orphan the StackLayout from its parent ScrollView, the layout doesn't get recalculated a lot and the list loads faster.

Any help would be appreciated. Thanks in advance!


Viewing all articles
Browse latest Browse all 77050

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>