Saya memiliki aplikasi yang saya konversi dari iOS hanya ke iOS & Droid menggunakan MVVMCross.

Di aplikasi saya saat ini, saya memiliki tampilan peta yang menggunakan UISearchController yang memungkinkan pengguna untuk mencari lokasi terdekat. Ini didasarkan pada contoh Xamarin dan berfungsi dengan baik: Contoh Peta Xamarin

Untuk konversi saya punya:

  1. sebuah MapView terikat ke MapViewModel.
  2. Layanan pencarian yang disuntikkan ke MapViewModel.
  3. Membuat UISearchController dan mengikat teks pencarian ke properti di MapViewModel.

Ketika teks diperbarui, pencarian dipanggil dan hasilnya diambil. Yang saya perjuangkan adalah bagaimana mengikat hasil kembali ke SearchResultsView karena ini disajikan oleh UISearchController.

Adakah yang bisa memberi saya saran atau mengarahkan saya ke arah yang benar untuk menyelesaikan ini.

Saya memiliki cuplikan kode di bawah ini untuk memberikan gambaran tentang apa yang saya andalkan sejauh ini.

    [MvxFromStoryboard]
public partial class MapView : MvxViewController<MapViewModel>
{


    public MapView(IntPtr handle) : base(handle)
    {
    }

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();

        var searchResultsController = new SearchResultsView();

        //Not sure if this is required
        //var searchUpdater.UpdateSearchResults += searchResultsController.Search;

        var searchController = new UISearchController(searchResultsController)
        {
            //Nore sure if this is required
            //SearchResultsUpdater = searchUpdater
        };


        searchController.SearchBar.SizeToFit();
        searchController.SearchBar.SearchBarStyle = UISearchBarStyle.Minimal;
        searchController.SearchBar.Placeholder = "Enter a search query";
        searchController.HidesNavigationBarDuringPresentation = false;
        DefinesPresentationContext = true;
        NavigationItem.TitleView = searchController.SearchBar;

        //Bind to View Model
        var set = this.CreateBindingSet<MapView, MapViewModel>();
        set.Bind(searchController.SearchBar).To(vm => vm.SearchQuery);
        set.Apply();
    }

}

public class SearchResultsUpdator : UISearchResultsUpdating
{
    public event Action<string> UpdateSearchResults = delegate { };

    public override void UpdateSearchResultsForSearchController(UISearchController searchController)
    {
        this.UpdateSearchResults(searchController.SearchBar.Text);
    }
}


[MvxFromStoryboard]
public partial class SearchResultsView : MvxTableViewController<SearchResultsViewModel>
{
    public SearchResultsView() { }

    public SearchResultsView(IntPtr handle) : base(handle)
    {
    }

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();

        var source = new SearchResultsTableViewSource(TableView);
        TableView.Source = source;

        var set = this.CreateBindingSet<SearchResultsView, SearchResultsViewModel>();
        set.Bind(source).To(vm => vm.Results);
        set.Apply();


    }
}

[MvxFromStoryboard]
public partial class SearchResultsView : MvxTableViewController<SearchResultsViewModel>
{
    public SearchResultsView() { }

    public SearchResultsView(IntPtr handle) : base(handle)
    {
    }

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();

        var source = new SearchResultsTableViewSource(TableView);
        TableView.Source = source;

        var set = this.CreateBindingSet<SearchResultsView, SearchResultsViewModel>();
        set.Bind(source).To(vm => vm.Results);
        set.Apply();


    }
}
0
FinniusFrog 20 Maret 2019, 23:33

1 menjawab

Jawaban Terbaik

Saya telah memposting ini jika ada orang lain yang mencari contoh. Saya memutuskan cara terbaik untuk melakukan ini adalah membiarkan iOS menangani pengontrol tampilan pencarian untuk hasilnya. Kode berikut. Jangan ragu untuk mengoreksi atau menyarankan alternatif yang lebih baik

Melihat

    [MvxFromStoryboard]
    public partial class MapView : MvxViewController
    {
        UISearchController _searchController;
        SearchResultsViewController _searchResultsController;

        private IDisposable _searchResultsUpdateSubscription;
        private IMvxInteraction _searchResultsUpdatedInteraction;
        public IMvxInteraction SearchResultsUpdatedInteraction
        {
            get => _searchResultsUpdatedInteraction;
            set
            {
                if (_searchResultsUpdateSubscription != null)
                {
                    _searchResultsUpdateSubscription.Dispose();
                    _searchResultsUpdateSubscription = null;
                }

                _searchResultsUpdatedInteraction = value;
                if (_searchResultsUpdatedInteraction != null)
                {
                    _searchResultsUpdateSubscription = _searchResultsUpdatedInteraction.WeakSubscribe(OnSearchResultsUpdated);
                }
            }
        }


        private void OnSearchResultsUpdated(object sender, EventArgs e)
        {
            _searchResultsController.SearchResults = Results;
            _searchResultsController.ReloadSearchTable();
        }

        public List<Placemark> Results { get; set; }

        public MapView(IntPtr handle) : base(handle)
        {
        }

        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            //Bind to View Model
            var set = this.CreateBindingSet<MapView, MapViewModel>();
            set.Bind(_searchController.SearchBar).To(vm => vm.SearchQuery);
            set.Bind(this).For(v => v.Results).To(vm => vm.Results);
            set.Bind(this).For(v => v.SearchResultsUpdatedInteraction).To(vm => vm.SearchResultsUpdatedInteraction).OneWay();
            set.Apply();

        }

LihatModel

    public class MapViewModel : MvxViewModel
    {
        readonly ILocationService _locationService;

        private MvxInteraction _searchResultsUpdatedInteraction = new MvxInteraction();
        public IMvxInteraction SearchResultsUpdatedInteraction => _searchResultsUpdatedInteraction;

        public MapViewModel(ILocationService locationService)
        {
            _locationService = locationService;
        }
        //***** Properties *****

        private List<Placemark> _results;
        public List<Placemark> Results
        {
            get => _results;
            set
            {
                _results = value;
                RaisePropertyChanged();
            }
        }

        private string _searchQuery;
        public string SearchQuery
        {
            get => _searchQuery;
            set
            {
                _searchQuery = value;
                //Task.Run(UpdateResultsAsync).Wait();
                RaisePropertyChanged();
                UpdateResultsAsync();
            }
        }

        //***** Privates *****
        private async Task UpdateResultsAsync()
        {
            Results = await _locationService.SearchForPlacesAsync(_searchQuery);
            _searchResultsUpdatedInteraction.Raise();
        }
    }

SearchResultsViewController

    public class SearchResultsViewController : UITableViewController
    {
        static readonly string mapItemCellId = "mapItemCellId";

        public List<Placemark> SearchResults { get; set; }

        public SearchResultsViewController()
        {

            SearchResults = new List<Placemark>();
        }

        public override nint RowsInSection(UITableView tableView, nint section)
        {
            return SearchResults == null ? 0 : SearchResults.Count;
        }

        public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
        {
            var cell = tableView.DequeueReusableCell(mapItemCellId);

            if (cell == null)
                cell = new UITableViewCell();

            cell.TextLabel.Text = SearchResults[indexPath.Row].FeatureName;
            return cell;
        }

        public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
        {
           //Do stuff here
        }

        public void ReloadSearchTable()
        {
            this.TableView.ReloadData();
        }
    }

0
FinniusFrog 28 Maret 2019, 21:33