Just new to Monotouch! :D Very glad with it but still in the discovery phase... Hehehe...
I was wondering if i can see/change my labels from within my Table View, for example, in the Main.cs, please take a look:
public partial class AppDelegate : UIApplicationDelegate
{
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
//Do something in here (load my view or any other thing...)
}
public class TableViewDataSourceClientes : UITableViewSource
{
//Why can't I access my labels inside this class?
}
}
So, my question is pretty much it. Why i can access my labels and views and textboxes and etc. inside FinishedLauching and not in TableViewDataSourceClientes? ANd how can I achieve this?
My objective is to create a method inside of TableViewDataSourceClientes called RowSelected and change a label text when I select a row.
You cannot access your outlets/labels in the TableViewDataSourceClientes class because they are instance properties on your AppDelegate class. You can get at the AppDelegate from anywhere with UIApplication.SharedApplication.Delegate, you'll need to cast it to your AppDelegate type tho, and then expose the fields / properties you want as public members.
Related
On the start of my iOS application (that I am building with Xamarin and MvvmCross), I want to immediately change UIViewController to a UITabBarViewController. My code:
public class MainViewModel : BaseViewModel
{
public void Initialization()
{
ShowViewModel<TabLayoutViewModel>(); // Breaks here
}
}
public class MainViewController : BaseViewController<MainViewModel>
{
public override void ViewDidLoad()
{
base.ViewDidLoad();
this.ViewModel.Initialization();
}
}
public class TabLayoutViewController : MvxTabBarViewController<TabLayoutViewModel>
{
}
On the line ShowViewModel<TabLayoutViewModel>() it throws an exception:
A TabBarViewController cannot be presented as a child. Consider using
Root instead
I just want to push this controller on top of the stack. I know this is legal in plain iOS so there should be a way to do it with MvvmCross?
Update: Since MvvmCross 5.0.4 it is now possible to show a TabBarController as a child. Just mark your TabBarController with [MvxChildPresentation].
See this PR to the source code..
Original answer:
A TabBarController is not meant to be presented inside a UINavigationController. What you can do is to change the root ViewController of your Window. To do so, you can add the MvxRootPresentation attribute above the TabLayoutViewController class.
If you do need to show tabs inside a UINavigationController, you might find this question relevant.
I had to do just that last week.
What I do to quickly resolve this is simple:
1) Create a custom presenter that inherits from MvxIosViewPresenter (https://github.com/MvvmCross/MvvmCross/blob/develop/MvvmCross/iOS/iOS/Views/Presenters/MvxIosViewPresenter.cs).
2) Override the ShowChildViewController method, using the original as model and comment these two lines:
if (viewController is IMvxTabBarViewController)
throw new MvxException("A TabBarViewController cannot be presented as a child. Consider using Root instead");
3) Override the CreatePresenter method in Setup.cs:
protected override IMvxIosViewPresenter CreatePresenter()
{
return new CustomTabChildMvxIosViewPresenter(ApplicationDelegate, Window);
}
I am using Xamarin.iOS. I have created UIView with a few UITextFields. I am looking for best way to initialize text value in these textfields from code.
I can pass text data in the constructor of UIViewContoller, but I don't have access to textFields inside it (they are null). I can change text value of textFields in viewDidLoad method.
I don't want to create additional fields in controller class to store data passed by constructor and use them in viewDidLoad. Do you know better solution ?
I don't want to create additional fields in controller class to store
data passed by constructor and use them in viewDidLoad.
But that's how it's meant to be done.
Alternatively, you can create less fields/properties in your viewcontroller if you use a MVVM pattern:
public class UserViewModel {
public string Name { get; set;}
public string Title { get; set;}
}
public class UserViewController : UIViewController
{
UserViewModel viewModel;
public UserViewController (UserViewModel viewModel) : base (...)
{
this.viewModel = viewModel;
}
public override void ViewDidLoad ()
{
userName.Text = viewModel.Name;
userTitle.Text = viewModel.Title;
}
}
That's the kind of pattern which gives you a lot of code reuse accross platforms (android, WP, ...) and clearly separate concerns. It's a (very) little bit of extra code, but it's worth every byte.
I'm curious that is there any way to call #FXML variables in not only Controller Class but also in another classes. Well actually i'm dealing with SVGPath nodes and trying to implement various kind graphs. However i dont wanna write the whole code in only Controller Class. I will appreciate if you can help and also give clear answers. So thanks anyway :)
EDIT: let me introduce a simple example about my issue.
Controller class code section;
public class RiskControllerClass implements Initializable {
#FXML private SVGPath NA_1; // Alaska
#FXML private SVGPath NA_2; // NorthWest_Ter
.
.
}
Territory class which refers to a vertex in a graph
public class Territory {
public Territory(SVGPath nodeSVG, int territoryID, int playerID){
this.playerID = playerID;
this.territoryID = territoryID;
this.nodeSVG = nodeSVG;
this.label = nodeSVG.getId();
this.adjacencyList = new LinkedList<>();
this.edgeSet = new LinkedList<>();
}
.
.
}
so i want to implement my graph another class than Controller class something like GameBoard
public class GameBoard {
// Want to call #FXML instance variables here
}
There is no other way than to access your controller and call methods from it. There is no magical way an #FXML annotation makes private variables globally available. #FXML is only used to mark certain fields for the FXMLLoader so he can access them via reflection in the instantiation process of your FXML - nothing else.
Refere to this questions on how to access the controller:
Accessing FXML controller class
JavaFX: How to get stage from controller during initialization?
I have an app (written using MonoTouch and currently working) that I want to add landscape orientation to. I am using a UITabBarController.
I don't see how to create a controller that will allow me to override the "ShouldAutorotate..." method. Can anybody point me to an example using a UITabBarController in MonoTouch?
TweetStation contains a sample precisely for this setup, and propagates the rotation down all of the nested view controllers.
Are you subclassing UITabBarController?
You are probably non subclassing and just adding a vanilla controller in Interface Builder. You have to subclass to override that property.
First make a new class like this:
//Test this, it's off the top of my head
[Register("YourTabController")]
public class YourTabController : UITabBarController
{
public YourTabController (IntPtr handle) : base (handle) { }
[Export("initWithCoder:")]
public YourTabController (NSCoder coder) : base (coder) { }
//Override should rotate
public bool ShouldAutoRotateToInterfaceOrientation(UIInterfaceOrientation o)
{ return true; }
}
Then, if you already have a UITabBarController in IB, there is a 'Class' property that you set to the name of your new class.
I am using a custom UITableViewDelegate and in my controller I want to run some code when the tableview has a rowselected. I noticed the UITableViewDelegate already has an event called RowSelected but you cannot use it I'm guessing because there is a method in UITableViewDelegate with the exact same name.
If I write:
mytableviewdelegate.RowSelected += myeventhandler;
This will not compile and gives the error:
"Cannot assign to 'RowSelected' because it is a 'method group'"
Any ideas, I have a work around which is fine so Im really looking at working out if this is a bug in MonoTouch?
How are you implementing the custom UITableViewDelegate? I would suggest using Monotouch's UITableViewSource as it combines both the UITableViewDataSource and the UITableViewDelegate into one file which makes things so much easier.
Some example code:
(in your UIViewController that contains the UITableView)
tableView.Source = new CustomTableSource();
Then you'll want to create a new class for this:
public class CustomTableSource : UITableViewSource
{
public CustomTableSource()
{
// constructor
}
// Before you were assigning methods to the delegate/datasource using += but
// in here you'll want to do the following:
public override int RowsInSection (UITableView tableView, int section)
{
// you'll want to return the amount of rows you're expecting
return rowsInt;
}
// you will also need to override the GetCells method as a minimum.
// override any other methods you've used in the Delegate/Datasource
// the one you're looking for in particular is as follows:
public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
{
// do what you need to here when a row is selected!
}
}
That should help you get started. In the UITableViewSource class you can always type public override and MonoDevelop will show you what methods are available to be overriden.