Forum Xamarin.iOS

Activity Indicator not Showing

brianduccabrianducca ARMember ✭✭
edited October 2016 in Xamarin.iOS

Hello, i'm having an issue with activity indicator, it's not showing, i have my main storyboard with a login screen and then a home screen. I need to login via restCall with an API and then if the credentials are right, continue to home.
The activity controller name is loadingIndicator in the code.

LoginController:

public override bool ShouldPerformSegue(string segueIdentifier, NSObject sender)
        {
            if (string.IsNullOrWhiteSpace(txtUsername.Text) || string.IsNullOrWhiteSpace(txtPassword.Text))
            {
                UIAlertView userError = new UIAlertView("Error", "You need to fill the fields", null, "Ok", null);
                userError.Show();
                return false;
            }
            if (!_userNameValid)
            {
                UIAlertView userError = new UIAlertView("Error", "Please enter a valid username", null, "Ok", null);
                userError.Show();
                return false;
            }
            if (!CrossConnectivity.Current.IsConnected)
            {
                UIAlertView userError = new UIAlertView("Error", "Internet Connection Failed", null, "Ok", null);
                userError.Show();
                return false;
            }

            return TryLogin().Result;
        }

private Task<bool> TryLogin()
        {   

            RestService restCall = new RestService(txtUsername.Text, txtPassword.Text);
        loadingIndicator.StartAnimating();
            var answer = restCall.CheckCredentials().ContinueWith((response) =>
              {
                  if (!response.Result.Success)
                  {
                      BeginInvokeOnMainThread(() =>
                      {
                          UIAlertView userError = new UIAlertView("Error", response.Result.StatusMessage, null, "Ok", null);
                          userError.Show();
                          loadingIndicator.StopAnimating();
                      });
                      return false;
                  }
                  return true;
              });
            loadingIndicator.StopAnimating();
            return answer;
        }

RestService:

public async Task<ApiResponse> CheckCredentials()
        {
            var uri = new Uri(string.Format(Constants.RestURL, "checkcredentials"));
            HttpResponseMessage response = await client.GetAsync(uri).ConfigureAwait(false);
            var jsonResult = JsonConvert.DeserializeObject<ApiResponse>(response.Content.ReadAsStringAsync().Result);
            return jsonResult;          
        }

Best Answer

Answers

  • JF.0444JF.0444 USMember ✭✭✭

    If it's never showing the spinner it might be behind another view. You can try View.BringSubViewToFront (LoadingIndicator).

    If the loading indicator is created on the storyboard are you hiding it on load? If so set LoadingIndicator.Hidden = false before animating

  • brianduccabrianducca ARMember ✭✭

    @JF.0444 said:
    If it's never showing the spinner it might be behind another view. You can try View.BringSubViewToFront (LoadingIndicator).

    If the loading indicator is created on the storyboard are you hiding it on load? If so set LoadingIndicator.Hidden = false before animating

    It's showing, but not in the way i want, i shows like 0,05 milisecs, when the login is already processed, the desire way should be, the spinner starts -> check for credentials -> spinner stops -> credentials result

  • JF.0444JF.0444 USMember ✭✭✭

    In that case see @ManuelDambrine answer, changes to UI won't be processed till OS gets control of UI thread to render changes which is why it's only showing for .5 seconds

  • PlamenYovchevPlamenYovchev USMember ✭✭

    Hi guys,

    I am experiencing pretty strange behavior with the activity indicator. It does not shows up. Is there something which I am not doing right ?

           protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
                    {
                        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
                    }
    
                    protected void SetValue<T>(ref T backingField, T value, [CallerMemberName] string propertyName = null)
                    {
                        if (EqualityComparer<T>.Default.Equals(backingField, value))
                        {
                            return;
                        }
    
                        backingField = value;
    
                        OnPropertyChanged(propertyName);
                    }
    
            private bool isLoading;
                public bool IsLoading
                {
                    get { return isLoading; }
                    set
                    {
                        SetValue(ref isLoading, value);
                    }
                }
    
        public InitialDataPageViewModel()
                {
                    this.initialDataService = new InitialDataService();
                    this.DownloadInitialDataCommand = new Command(async () =>
                    {
                        this.IsLoading = true;
                        await DownloadInitialData();
                        this.IsLoading = false;
                    });
                }
    
                public async Task DownloadInitialData()
                {
                        if (dataToInsert == null)
                        {
                            dataToInsert = this.initialDataService.GetInitialData();
                        }
    
                        await this.initialDataService.SaveInitialData(dataToInsert);
                }
    
         <StackLayout>
                <StackLayout HorizontalOptions="Center">
                    <Label Text="Welcome" FontSize="Large" />
                </StackLayout>
                <StackLayout>
                    <Button Text="Download" Command="{Binding DownloadInitialDataCommand}" />
                </StackLayout>
                <StackLayout>
                    <ActivityIndicator IsRunning="{Binding IsLoading}" Color="Black" />
                </StackLayout>
            </StackLayout>
    
  • PlamenYovchevPlamenYovchev USMember ✭✭

    Hi guys,

    I am experiencing pretty strange behavior with the activity indicator. It does not shows up. Is there something which I am not doing right ?

           protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
                    {
                        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
                    }
    
                    protected void SetValue<T>(ref T backingField, T value, [CallerMemberName] string propertyName = null)
                    {
                        if (EqualityComparer<T>.Default.Equals(backingField, value))
                        {
                            return;
                        }
    
                        backingField = value;
    
                        OnPropertyChanged(propertyName);
                    }
    
            private bool isLoading;
                public bool IsLoading
                {
                    get { return isLoading; }
                    set
                    {
                        SetValue(ref isLoading, value);
                    }
                }
    
        public InitialDataPageViewModel()
                {
                    this.initialDataService = new InitialDataService();
                    this.DownloadInitialDataCommand = new Command(async () =>
                    {
                        this.IsLoading = true;
                        await DownloadInitialData();
                        this.IsLoading = false;
                    });
                }
    
                public async Task DownloadInitialData()
                {
                        if (dataToInsert == null)
                        {
                            dataToInsert = this.initialDataService.GetInitialData();
                        }
    
                        await this.initialDataService.SaveInitialData(dataToInsert);
                }
    
         <StackLayout>
                <StackLayout HorizontalOptions="Center">
                    <Label Text="Welcome" FontSize="Large" />
                </StackLayout>
                <StackLayout>
                    <Button Text="Download" Command="{Binding DownloadInitialDataCommand}" />
                </StackLayout>
                <StackLayout>
                    <ActivityIndicator IsRunning="{Binding IsLoading}" Color="Black" />
                </StackLayout>
            </StackLayout>
    
  • RobertDebaultRobertDebault USUniversity ✭✭✭

    I found a solution to this problem but I don't know that I like it. If you pass the UI to the view controller then set the IsBusy in the view controller the Activity Indicator will respond correctly. So your command call would look something like this... I did not include all of the code but this should give you what you need.

    MyPage(Xaml)

    <ContentPage.Content>


    <ActivityIndicator.Color>

    </ActivityIndicator.Color>

    <ListView.....>


    </ContentPage.Content>

    xaml.cs
    public MyPage()
    {
    BindingContext = viewModel = new MyPageViewModel(this);
    }

    MyPageViewModel.cs
    public MyPage _page;
    public MyPageViewModel(MyPage callPage){
    _page = callPage;
    }
    DoSomethingCommand(){
    _page.IsBusy = true;
    // do whatever
    _page.IsBusy = false;
    }

Sign In or Register to comment.