How do you use a storyboard reference in a Tab Bar Controller with Visual Studio? - xamarin.ios

I have a view controller in one storyboard that I'd like to reuse in another storyboard's Tab Bar Controller. In XCode, I can add a storyboard reference and then ctrl-drag from the Tab Bar Controller to it, and it shows up as another tab, just like a View Controller would in the same storyboard. I'm trying to do this in VS 2017 though and it doesn't seem to work. Or if it does, I'm unsure of how to do it. I tried adding a storyboard reference and ctrl-dragging, just like I do for normal View Controllers. I select "Tab" under "View Relationship" which pops up when I finish dragging, but it never makes the link and never makes the tab.
Is this even something that is valid? And if it is, is it a bug/limitation with VS that I can't do this, and is there a workaround?
Edit:
I managed to get this to work programmatically. Here's what I did in case anyone wants to know. However, I still would like to know the answer to my previous questions.
First, in your desired VC (I'm going to call it TestVC), make sure you add a Tab Bar Item (not a tab bar). Set up the title and image as you would normally. Then, in your Tab Bar Controller's ViewDidLoad method, do something like this:
var storyboard = UIStoryboard.FromName("StoryboardNameTestVCIsIn", null);
var vc = storyboard.InstantiateViewController("TestVC");
var existing = new List<UIViewController>(ViewControllers);
existing.Add(vc);
ViewControllers = existing.ToArray();

Is this even something that is valid? And if it is, is it a bug/limitation with VS that I can't do this, and is there a workaround?
It is not support to add Tab relationship by this way. As you mentioned above, you could only implement that programmatically. Maybe in the near future Xamarin will support it like in Xcode.
Click on the segue , and you can see all the actions you can do.

Related

How to fix UICollectionView - All cells disappear - Xamarin ios

I am using a UICollectionView in C# Xamarin ios and sometimes all of the cells will disappear from the screen. This happens normally on a scroll and I have to re-invoke the view that my UICollection View is on.
I can't show my exact code as this is a project that I am working on but the initialization basics look a little like this:
Bounds screenBounds = screen.Bounds
UICollectionViewFlowLayout layout = new UICollectionViewFlowLayout();
UICollectionView collectionView = new UICollectionView(layout, bounds)
I initialize a few other things like source and register cell and also add separation and border styles.
I have been also getting an error about a view not being in the hierarchy don't know if this has anything to do with it.
I do return the collectionView at the end and will add this returned value to my template which has a scroll view in which I add the UICollectionView to.
May I also mention I don't use any of the StoryBoard and am using a DuqueReusable cell in my collection view source.
I have been stuck on this for ages so thank you in advance for anyone who can give me any sort of tips or answers to this question.
Insure you make any changes to ItemsSource or to cells data on UI thread only, otherwise you might obtains an uncatchanble async crash and you'll end up with an empty view.
Device.BeginInvokeOnMainThread(() => {
// do your stuff
});

Show back button even if no pages are in back stack

I'm making a Master/Details app with Template 10. The Master/Details Template 10 sample uses a CommandBar to get full control over when the back button is shown, but I'd like to show the back button on a PageHeader or on the shell. The problem is, since there is no back stack, the button refuses to be shown. How should I handle this?
Override the OnNavigatedTo event and set AppViewBackButtonVisibility to Visible in the code-behind file for each page that you want to enable the title bar back button.
Take a look here: http://grogansoft.com/blog/?p=1116
The important part is "AppViewBackButtonVisibility"
if (rootFrame.CanGoBack)
{
// Show UI in title bar if opted-in and in-app backstack is not empty.
SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
AppViewBackButtonVisibility.Visible;
}
I also suggest you take a look at the AppBar properties.
Especially the Visibility which gets or sets the visibility of a UIElement and you could force the visibility of an item:
https://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.appbar.aspx
So I've created a hacky solution to this. Basically I'm adding a dummy value onto the stack so that the back button thinks there is something to go back to.
var entry = new PageStackEntry(typeof(bool), null, null);
Frame.BackStack.Insert(0, entry);
Then I've added a BootStrapper.BackRequested event which sets HandledEventArgs.Handled to true so Template10 doesnt actually pop the page. That way I've got full control over the back stack and the back visibility.

Wrong View shown (Catel)

I'm trying to open a View with a ViewModel from my MainWindowViewModel.
It works, but all I get is a blank window. It binds the correct title but every other control is missing.
Did anyone have the same problem and found a solution?
You forgot the call to InitializeComponent in your code-behind. Just a tip: create a base class with the Catel behaviors, then use that as a base view. It will keep your actual window code-behind much cleaner.

Programmatically changing tabs in a Monotouch app

Forgive me for my ignorance, as I'm new to Monotouch and I'm sure this is a simple thing but I can't find the answer anywhere.
I have an iPhone app in Monotouch that uses a UITabBarController for root navigation. It is defined in it's own class file. There is also a separate view controller class file for the content of each tab. So tab1 shows viewcontroller1, tab2 shows viewcontroller2, etc.
I want a user to be able to click on button1 inside of viewcontroller1 and have the app take them to tab2 and show viewcontroller2.
I have an event handled for the click of button1 and I can do things like pop up alerts when it's clicked, but I can't figure out how to get the tab bar to be accessible for me to call it. Please help!
Edit: I need to know not only how to make it accessible, but I also don't know what method to call to make it change.
When you create your "child" view controllers, pass in a reference to the "parent" tab controller. Then you child can call a method on it's parent to update the current tab index.
something like
btn1.TouchUpInside += (sender, args) => TabBarController.SelectedIndex = 0 ;

How does MonoTouch autogenerate XIB code behind?

I'm a C# programmer dabbling in a bit of iPhone development using MonoTouch.
I add a new View Interface Definition to my project and double click to open it up in Interface Builder. I add a UIButton. I save the file, and inspect the xib.designer.cs file, and I can see no reference to the new button.
I downloaded the code from http://monotouchexamples.com/ where I could see an example of autogenerated code behind :
[MonoTouch.Foundation.Connect("infoButton")]
private MonoTouch.UIKit.UIButton infoButton {
get {
return ((MonoTouch.UIKit.UIButton)(this.GetNativeField("infoButton")));
}
set {
this.SetNativeField("infoButton", value);
}
}
I opened up MainWindow.xib in interface builder. I notice a few differences. File's Owner is of type UIApplication instead of NSObject. What is the importance of this? There is an App Delegate object of type AppDelegate. I can't add an AppDelegate to my own view, or at least I can't find it in the Library. Do I need to add one? I can see that the existing controls on MainWindow.xib have Referencing Outlets to the App Delegate. I add a new button and I want to hook it up. When I click and drag a New Referencing Outlet to the App Delegate a context menu appears that lists the existing controls. How do I add a new element to this list, or where does this list come from?
I've been spoilt by the Visual Studio world where I just dump a button on a form and start writing code for the click event. Could someone provide some pointers about the steps needed to get this working on MonoTouch?
Thanks,
Patrick
Adding a button by itself is not enough. The button is not accessible outside the Interface Builder. You need add an Outlet, and connect the button with the outlet in Interface Builder.
Remember: Outlets are the members in your Controller class that get a reference to the controls, you can't just access the controls without them.
As Dave says, you need to add an outlet to your controller class, and connect your button to that outlet, before any auto-generated code will appear. This caught me out too initially.
You choose your controller class in the Interface Builder library window, choose 'outlets' in the bottom part of the library, and add an outlet there. You then need to select your button, choose the connections tab of the inspector window, and drag from the "New referencing outlet" circle over to your controller class. Interface Builder will then prompt you to choose an outlet to connect to. Then when you save, you should get the auto-generated code appear in the .xib.designer.cs file, and then you should be able to reference your button via that outlet variable in your .xib.cs file.
It sounds like the project I created is out of date - I remember there were quite a few changes around how the generated buttons are created in the designer file. I will update the project soon for you.
As Dave said, to get the code to be auto generated you need to add an outlet with Interface Builder. There should be an example on this video here - http://bit.ly/aWoItN but the server seems to be down at the moment.
Hope this helps,
ChrisNTR

Resources