10

Z przykładów pod adresem Xamarin.com można tworzyć podstawowe aplikacje M.T. Dialog, ale w jaki sposób można zbudować prawdziwą aplikację?Strukturyzacja aplikacji MonoTouch.Dialog

Czy:

1) Tworzenie pojedynczego DialogViewController drzewo i stamtąd każdy view/RootElement lub,

2) Utwórz DialogViewController dla każdego widoku i korzystania z UINavigationController i przesunąć go na miarę potrzeb?

W zależności od odpowiedzi, lepszą odpowiedzią jest jak? Zbudowałem przykładową aplikację zadań, więc rozumiem dodawanie elementów do tabeli, klikanie w celu przejścia do "następnego" widoku do edycji, ale jak kliknąć, aby nie edytować? Jak kliknąć przycisk, przejdź do następnego widoku, jeśli odpowiedź ma numer 1?

Revised:

Nie ma chyba nikt prawidłowa odpowiedź, ale co mam wymyślić wydaje się pracować dla nas. Numer 2 z powyższego został wybrany, poniżej znajduje się przykład kodu, jaki obecnie istnieje. Co zrobiliśmy było stworzenie kontrolera nawigacyjnego w AppDelegate i dać dostęp do niej w całej aplikacji, takich jak ten:

public partial class AppDelegate : UIApplicationDelegate 
{ 
    public UIWindow window { get; private set; } 
    //< There's a Window property/field which we chose not to bother with 

    public static AppDelegate Current { get; private set; } 
    public UINavigationController NavController { get; private set; } 

    public override bool FinishedLaunching (UIApplication app, NSDictionary options) 
    { 
     Current = this; 
     window = new UIWindow (UIScreen.MainScreen.Bounds); 
     NavController = new UINavigationController(); 

     // See About Controller below 
     DialogViewController about = new AboutController(); 
     NavController.PushViewController(about, true); 

     window.RootViewController = NavController; 
     window.MakeKeyAndVisible(); 
     return true; 
    } 
} 

Następnie każdy Dialog ma strukturę takiego:

public class AboutController : DialogViewController 
{ 
    public delegate void D(AboutController dvc); 
    public event D ViewLoaded = delegate { }; 

    static About about; 
    public AboutController() 
     : base(about = new About()) 
    { 
     Autorotate = true; 
     about.SetDialogViewController(this); 
    } 

    public override void LoadView() 
    { 
     base.LoadView(); 
     ViewLoaded(this); 
    } 
} 

public class About : RootElement 
{ 
    static AboutModel about = AboutVM.About; 

    public About() 
     : base(about.Title) 
    { 
     string[] message = about.Text.Split(...); 
     Add(new Section(){ 
      new AboutMessage(message[0]), 
      new About_Image(about), 
      new AboutMessage(message[1]), 
     }); 
    } 

    internal void SetDialogViewController(AboutController dvc) 
    { 
     var next = new UIBarButtonItem(UIBarButtonSystemItem.Play); 
     dvc.NavigationItem.RightBarButtonItem = next; 
     dvc.ViewLoaded += new AboutController.D(dvc_ViewLoaded); 
     next.Clicked += new System.EventHandler(next_Clicked); 
    } 

    void next_Clicked(object sender, System.EventArgs e) 
    { 
     // Load next controller 
     AppDelegate.Current.NavController.PushViewController(new IssuesController(), true); 
    } 

    void dvc_ViewLoaded(AboutController dvc) 
    { 
     // Swipe location: https://gist.github.com/2884348 
     dvc.View.Swipe(UISwipeGestureRecognizerDirection.Left).Event += 
      delegate { next_Clicked(null, null); };    
    } 
} 

Utwórz podklasę potrzebnych elementów jak:

public class About_Image : Element, IElementSizing 
{ 
    static NSString skey = new NSString("About_Image"); 
    AboutModel about; 
    UIImage image; 

    public About_Image(AboutModel about) 
     : base(string.Empty) 
    { 
     this.about = about; 
     FileInfo imageFile = App.LibraryFile(about.Image ?? "filler.png"); 
     if (imageFile.Exists) 
     { 
      float size = 240; 
      image = UIImage.FromFile(imageFile.FullName); 
      var resizer = new ImageResizer(image); 
      resizer.Resize(size, size); 
      image = resizer.ModifiedImage; 
     } 
    } 

    public override UITableViewCell GetCell(UITableView tv) 
    { 
     var cell = tv.DequeueReusableCell(skey); 
     if (cell == null) 
     { 
      cell = new UITableViewCell(UITableViewCellStyle.Default, skey) 
      { 
       SelectionStyle = UITableViewCellSelectionStyle.None, 
       Accessory = UITableViewCellAccessory.None, 
      }; 
     } 
     if (null != image) 
     { 
      cell.ImageView.ContentMode = UIViewContentMode.Center; 
      cell.ImageView.Image = image; 
     } 
     return cell; 
    } 

    public float GetHeight(UITableView tableView, NSIndexPath indexPath) 
    { 
     float height = 100; 
     if (null != image) 
      height = image.Size.Height; 
     return height; 
    } 

    public override void Selected(DialogViewController dvc, UITableView tableView, NSIndexPath indexPath) 
    { 
     //base.Selected(dvc, tableView, path); 
     tableView.DeselectRow(indexPath, true); 
    } 
} 

@miquel

Obecna idea przepływu pracy to aplikacja, która zaczyna się od jpg Default.png, która przechodzi w pierwszy widok, z przyciskami kontroli przepływu, które przeniosłyby się do głównej aplikacji. Ten widok, który poprzednio pracowałem pod M.T.D. (MonoTouch.Dialog), który jest tabelą wierszy tekstu z obrazem. Po kliknięciu każdego wiersza przechodzi on do innego widoku, który zawiera bardziej szczegółowy wiersz/tekst.

Aplikacja obsługuje również zakupy w aplikacji, więc jeśli klient chce kupić więcej produktu, przełącz się na inny widok, aby przeprowadzić transakcję zakupu. Ta część była głównym powodem przełączenia się na M.T.D., ponieważ pomyślałem, że M.T.D. będzie do tego idealny.

Wreszcie nie byłoby ustawień zobaczyć ponownie włączyć zakupy itp

PS Jak można wiedzieć, kiedy aplikacja jest un-zminimalizowany? Chcielibyśmy ponownie pokazać zanik obrazu.

+0

Spróbuj spojrzeć na aplikację [TweetStation] (https://github.com/migueldeicaza/TweetStation) - w dużej mierze opiera się ona na MT.D – Jason

+0

To nie pomaga, ponieważ nie ma wyjaśnienia, dlaczego coś jest zrobione, na przykład 5 DVC. Chciałbym wiedzieć, jak zagnieżdżać okna dialogowe, używając jednej lub obu powyższych metod. –

+0

Chuck, pomogłoby ci opisać, jaki rodzaj aplikacji masz na myśli, i jeśli masz worfklow, który chcesz osiągnąć. Wtedy wszystko stanie się bardziej jasne. Czy myślisz, że możesz opublikować balsamiczną makietę tego, co próbujesz zrobić? Mógłbym skomentować, w jaki sposób można osiągnąć ten krok. –

Odpowiedz

1

Zadawałem sobie te same pytania. Użyłem struktury Dependency Injection Funq i tworzę nowy DialogViewController dla każdego widoku. Jest to efektywnie to samo podejście, z którego korzystałem wcześniej przy tworzeniu aplikacji ASP.NET MVC i że mogę utrzymać logikę kontrolera w przyjemny sposób. I podklasę DialogViewController dla każdego widoku, który pozwala mi przekazać do kontrolera wszelkie dane aplikacji wymagane dla danego kontrolera. Nie jestem pewien, czy to jest zalecane podejście, ale jak na razie działa to dla mnie.

Ja też spojrzałem na aplikację TweetStation i uważam, że jest to użyteczne odniesienie, ale powiązana dokumentacja wyraźnie mówi, że nie stara się być przykładem struktury MonoTouch.

1

Używam opcji 2, którą również podałeś, działa całkiem nieźle, ponieważ możesz edytować opcje paska narzędzi na podstawie widoku root i takie.

0

Opcja 2 jest bardziej realistyczna, ponieważ zapewnia również większą kontrolę nad każdym z nich. Może również pomóc, jeśli chcesz warunkowo załadować widok.