Can't show NavigationBar on SplitView MonoTouch - c#

I have a problem using an navigation bar on my split view. I want the navigationbar showing on the left view there my TableView is (see picture Click Here).
This is my AppDelegate:
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
// create a new window instance based on the screen size
window = new UIWindow (UIScreen.MainScreen.Bounds);
this.masterViewController = new MasterViewControl();
this.detailViewController = new DetailViewController();
this.splitController = new UISplitViewController();
this.splitController.ViewControllers = new UIViewController[] {
this.masterViewController,
this.detailViewController
};
this.splitController.Delegate = new SplitControllerDelegate(this.detailViewController);
window.RootViewController = this.splitController;
// make the window visible
window.MakeKeyAndVisible ();
return true;
}
And the MasterViewController im trying to use it this way
'this.buttonAdd = new UIBarButtonItem("Edit", UIBarButtonItemStyle.Bordered, this.ButtonAdd_Clicked);
this.NavigationItem.SetRightBarButtonItem ( this.buttonAdd, true);'

You might want to try an existing solution, like MGSplitViewController. There's a video of it available here.
The original source code (objective-c) and MonoTouch bindings are available.
Or you can use a MonoTouch/C# port from Krumelur, which will be easier to use if you want to change/update the code base.

Related

How to add a custom view dynamically to a view in Visual Studio for Mac C#

I'm working through a project where I'm going to have multiple square size instances of the same set of form components.
I can either create 8 instances manually in my form UI or what I'd rather do is create a view (or Item Renderer) and then dynamically add instances of that view to my main view.
How do I add a create and add a custom view dynamically to the main view in my Xamarin form?
Note: Including Swift tag because you might know the answer if you know Swift or Objective C since the API wraps Apple API.
If IIUC:
Create a view in XCode Interface Builder
In ViewDidLoad create an instance of the custom instance views
Add each instance to the main view
I'd read a guide if there was one but I can't find anything specifically on this.
Some what related. I can create a new View in Xcode interface Builder pretty easily. Is there a way to export that as a class to my application?
Update:
I've found a textfield in Interface Builder where I can enter the name of a class. Back in Visual Studio my main View Controller can see the HelloWorld class. I've found a method named AddChildViewController. I try testing it. Nothing happens. Do I need to set the position and size? I can't find any API to do this.
Tomorrow I will scour the ancient texts again for example code. Maybe there is something I missed?
public override void ViewDidLoad()
{
base.ViewDidLoad();
var view = new HelloView(this.Handle);
var handle = view.Handle;
base.AddChildViewController(view);
var view2 = new HelloView(this.Handle);
handle = view.Handle;
base.AddChildViewController(view2);
}
I noticed a note in the console log:
<ViewController: 0x600000a94180> already have child of:
<ViewController: 0x600000a94180>
Update II:
This adds a new NSView and then a NSButton in that view to the main window:
var frame = new CoreGraphics.CGRect(0, 0, 100, 100);
var button = new NSButton(frame) {
Title = "My Button",
};
var view = new NSView(frame) {};
view.AddSubview(button);
View.AddSubview(view);
It doesn't add my custom class yet though.
Update III:
I'm able to add the custom HelloWorldView class but the controls are not visible. If I add a button to the form I see it but it is anchored to the bottom of the screen. I don't see the controls created from Interface Builder.
//var frame = this.View.Frame;
var frame = new CoreGraphics.CGRect(0, 0, 100, 20);
var button = new NSButton(frame) {
Title = "My Button"
};
var frame2 = new CoreGraphics.CGRect(0, 0, 100, 100);
var helloView = new HelloView() {
};
helloView.Frame = frame2;
helloView.AddSubview(button);
mainFrame.AddSubview(helloView);
HelloView.cs:
public partial class HelloView : NSView
{
public HelloView () : base ()
{
}
}
Note about the code above: I removed the handle parameter because it was causing a compiler error.
Setup: Visual Studio for Mac using Xamarin C# and XCode Interface Builder
--
Notes for the bounty.
To receive the bounty you must show how to do either step 1 or step 2 mentioned above in the Bounty Requirements section. I prefer step 1. If you are unsure ask.

How to detect Xamarin Forms tabbed page click - iOS?

My scenario is, I have a Tabbed page in Xamarin Forms:
public partial class MainPage : TabbedPage
{
public MainPage()
{
InitializeComponent();
var playPage = new NavigationPage(new PlayPage())
{
Title = "Play",
Icon = "play.png"
};
var settingsPage = new NavigationPage(new SettingsPage())
{
Title = "Settings",
Icon = "settings.png"
};
var favoritesPage = new NavigationPage(new FavoritesPage())
{
Title = "Favorites",
Icon = "fave.png"
};
var aboutPage = new NavigationPage(new AboutPage())
{
Title = "About",
Icon = "info.png"
};
Children.Add(playPage);
Children.Add(favoritesPage);
Children.Add(settingsPage);
Children.Add(aboutPage);
}
}
I want to add a pause and play function to my app. On start up, the PlayPage would initially have the play.png icon and when I click on the PlayPage again it would change the icon to pause.png. Page is not changing just the page icon. Anyone has any idea how this could be done?
Edit:
So I have created a custom renderer, in OnElementChanged I utilize the ViewControllerSelected:
var tabbarController = (UITabBarController)this.ViewController;
if (null != tabbarController)
{
tabbarController.ViewControllerSelected += OnTabBarReselected;
}
And my OnTabBarReselected I have:
private void OnTabBarReselected(object sender, UITabBarSelectionEventArgs e)
{
switch (TabBar.SelectedItem.Title)
{
case "Play":
TabBar.SelectedItem.Title = "Pause";
TabBar.SelectedItem.Image = UIImage.FromFile("pause.png");
break;
}
}
This only does half of the work. It changes the Title of the selected tab bar from Play to Pause after I click on the same tab but not the Icon. The icon remains "play.png" until I get out of that tab page (selecting another tab). Anyone has any idea why?
You will need to implement a custom renderer to pull this off. There are some implementations on James Montemagno's blog where he talks about changing the icons.
iOS:
http://motzcod.es/post/138225183932/tintcolor-selectedimage-xamarin-forms-ios
Droid:
http://motzcod.es/post/157544468267/xamarin-forms-android-selected-and-unselected-tab-colors
This is however not necessarily related to your requirement of tapping the icon and changing that specific icon since all this code only runs when the page initially loads. It could be a nice starting point though. Check in there if there's a property on TabbedPage that changes when you tap on the current tab and change the icon at that point.
You also have a OnCurrentPageChanged event you can override in TabbedPage, but that isn't called when the page is already active.

Closing Xamarin forms Navigation Drawer

I just started with Xamarin forms and followed this example. But for the landscape mode it always has Navigation drawer opened. Is this default behavior? Below is my code
public class NavigationDrawer : MasterDetailPage // Navigation Drawer using MasterDetailPage
{
public override bool ShouldShowToolbarButton()
{
return true;
}
ContentPage gotoPage;
public NavigationDrawer()
{
Title = "Navigation Drawer Using MasterDetailPage";
string[] myPageNames = { "Camera2 Demo", "Second", "Third" };
SizeChanged += NavigationDrawer_SizeChanged;
ListView listView = new ListView
{
ItemsSource = myPageNames,
};
this.Master = new ContentPage
{
Title = "Options",
Content = listView,
Icon = "hamburger.png"
};
listView.ItemTapped += (sender, e) =>
{
switch (e.Item.ToString())
{
case "Camera2 Demo":
gotoPage = new CameraPage();
break;
case "Second":
gotoPage = new SecondPage();
break;
case "Third":
gotoPage = new ThirdPage();
break;
default:
gotoPage = new NavigationPage1();
break;
}
Detail = new NavigationPage(gotoPage);
((ListView)sender).SelectedItem = null;
this.IsPresented = true;
};
Detail = new NavigationPage(new HomePage());
IsPresented = false;
//// For Windows Phone, provide a way to get back to the master page.
//if (Device.OS == TargetPlatform.WinPhone)
//{
// (this.Detail as ContentPage).Content.GestureRecognizers.Add(
// new TapGestureRecognizer((view) =>
// {
// this.IsPresented = true;
// }));
//}
}
Question
1) How would I control opening and closing of Navigation Drawer? I found a way where it would give us control over the width of the navigation Drawer. Here is the Link. But is this the best option available right now?
1) Since project requires to be crossplaform Xamarin forms controls seems to be one of the option.
2) Should we go with Custom controls and not Xamarin forms controls?
I just started with Xamarin sample code would appreciate if someone can guide me through this.
1) How would I control opening and closing of Navigation Drawer?
Use this.IsPresented = true; to open and this.IsPresented = false; to close the drawer.
About the other questions I don't understand you good, but depending on your requirements, you should create custom controls or download one from NuGet.
Note:
I believe the most important thing for a beginner is to learn how to implement a native code using DependencyService and also to use Design patterns like MVVM.
You would need to set MasterBehavior = MasterBehavior.Popover on the MasterDetailPage to force it to exhibit the behaviour you are after, otherwise it will default to MasterBehavior.Default, which in Landscape mode will be always open.

Binding a HTML control into a stacklayout using xamarin forms

Being a newbie to Xamrin I am struggling to adding some HTML to a StackLayout via Xamarin Forms. I have tried quite a few things and had a Google around.
Firstly I can't work out which bindable object I am supposed to be using. As I cannot find a straight answer on Google/Xamarin I am going to assume this is not as easy I was hoping.
var nameEntry = new Label ();
nameEntry.SetBinding (Label.TextProperty, "Club.ClubName");
var webView = new WebView ();
webView.SetBinding ( ??? , "Club.Description");
var content = new StackLayout {
Children = {
nameEntry,
???
}
};
I am not sure if this is possible within Xamarin forms itself. Can anyone help?
I should point out my data for the form is being retrieved asynchronously on a remote json endpoint
protected override void OnAppearing ()
{
base.OnAppearing ();
if (ViewModel == null || ViewModel.IsLoading)
return;
ViewModel.LoadItemsCommand.Execute (Club.ClubId);
}
My remote json api contains, Description contatins a HTML snippet which I would like to use.
{
ClubName: "Stourbridge",
Description: "<p>This club meets every TWO weeks on a <b>Friday</b>.</p>"
...
}
Try the following example that will show how to do the bindings.
Note that you have to use a HtmlWebViewSource to achieve this, and bind the WebView.Source to this.
Clicking the button will change the view model and update the WebView appropriately to the newly changed text.
StackLayout objStackLayout = new StackLayout();
MyView objMyView = new MyView();
objMyView.MyHtml = "<html><head></head><body><h1>Title</h1><p>Some body text</p></body></html>";
HtmlWebViewSource objHtmlWebViewSource = new HtmlWebViewSource();
objHtmlWebViewSource.SetBinding(HtmlWebViewSource.HtmlProperty, "MyHtml");
objHtmlWebViewSource.BindingContext = objMyView;
WebView objWebview = new WebView();
objWebview.HorizontalOptions = LayoutOptions.FillAndExpand;
objWebview.VerticalOptions = LayoutOptions.FillAndExpand;
objWebview.Source = objHtmlWebViewSource;
Button objMyButton2 = new Button();
objMyButton2.Text="Change Html";
objMyButton2.Clicked+=((o2,e2)=>
{
objMyView.MyHtml = "<html><head></head><body><h1>Title</h1><p>Some body text that has changed.</p></body></html>";
});
objStackLayout.Children.Add(objMyButton2);
objStackLayout.Children.Add(objWebview);
The view model is just a simple one with a bindable property as below:-
public class MyView
: Xamarin.Forms.View
{
public static readonly BindableProperty MyHtmlProperty = BindableProperty.Create<MyView, string>(p => p.MyHtml, default(string));
public string MyHtml
{
get { return (string)GetValue(MyHtmlProperty); }
set { SetValue(MyHtmlProperty, value); }
}
}
Before clicking the button gives:-
After clicking the button, adjusts the view model, and automatically updates the control via the binding giving:-

Edit ABPeoplePickerNavigationController navigationbar button

ABPeoplePickerNavigationController _contactController;
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
window = new UIWindow (UIScreen.MainScreen.Bounds);
_contactController = new ABPeoplePickerNavigationController();
//viewController = new HomeScreen ();
//navController = new UINavigationController (_contactController);
window.RootViewController = _contactController;
window.MakeKeyAndVisible ();
return true;
}
so now when the app opens the contact list is displayed. I want to put a different functionality to the rightnavigationbar Button instead of the cancel? How do i do this? how to get access to this button?
ABPeoplePickerNavigationController control couldn't be modified without finding right subviews in it's view. Moreover, app with such modifications could be denied by Apple.
Try to make your own UIViewController, which functionality will be close to iOSs ABPeoplePickerNavigationController:
Read contacts via AddressBook class;
Pass contact data into UITableView with sections and indexes.

Categories

Resources