How to get a default iOS navigation back button - c#

How can I get the default back button on an iOS UINavigationController? I have the button being added in code, but I want the default style. Is there an Enum of System Images that contains the '<', or is there not really a way, and Ill have to design my own?
Heres the code to make the button:
controller.DetailViewController.NavigationItem.SetLeftBarButtonItem (new UIBarButtonItem(UIBarButtonSystemItem.Stop, (sender, args) => {
controller.DetailViewController.NavigationController.PopViewController(true);
}), true);
Its written in C# using mono touch, and Xamarin.iOS, but I can work on porting Objective-c/Swift code if needed. Im just stuck at this point and can't seem to figure it out at all.

If you push your view controller then you will get default back button with navigation bar. If you don't want to push to push viewController then you need to add it on storyBoard. For pushing the view controller you write the code as
Your_ViewController *viewController = [self.storyboard instantiateViewControllerWithIdentifier:#"Your_ViewController"];
[self.navigationController pushViewController:viewController animated:YES];

Related

Xamarin Forms - attaching scrollview.Scrolled to a function

When I attach a scrollview to a function like this
textScroll.Scrolled += (sender, e) => { onScrolled(); };
Each time I scroll up or down, OnScrolled() is called multiple times. I know I can get the size of the content and compare it to the ScrollY value, obviously the ScrollY value changes each time, but as far as I can see I won't know when the last call happens (per user scroll).
I only want to call this once per scroll, failing that call it each time as is happening now, but only act when I know I'm on the last call.
Is this possible?
thanks
It is possible, but with a custom renderer for each platform.
On iOS: you will want to implement delegates for DecelerationEnded and WillEndDragging. The reason for also implementing DecelerationEnded is to allow for a fling by the user and waiting for the velocity to come to 0.
On Android it is a bit more complicated. Here is a native Android SO post I followed and translated into c# in a renderer. Works pretty well for me.
Android: Detect when ScrollView stops scrolling
After having both implemented, you can call to your Xamarin.Forms view in order to notify that the view has Stopped scrolling (i.e. final call)

Xamarin - Constantly getting NSInvalidArgumentException on Button click

I'm currently doing some cross-platform mobile development through Visual Studio using Xamarin (so in C#) and am about to start the iOS portion. I've never done iOS development before and thought I could get myself acquainted with their "Hello, iOS" Tutorials. Unfortunately, things have not been going smoothly. I constantly get NSInvalidArgumentExceptions from my TouchUpInside actions:
Foundation.MonoTouchException: Objective-C exception thrown.
Name: NSInvalidArgumentException Reason:
-[ViewController TranslateButton_TouchUpInside:]:
unrecognized selector sent to instance 0x7b6200d0
I can occasionally remedy it for a moment by literally remaking the Buttons, but it breaks pretty much right afterwards. The actual error itself occurs in my Main.cs file:
using UIKit;
namespace CheckinIOS
{
public class Application
{
static void Main(string[] args)
{
UIApplication.Main(args, null, "AppDelegate"); //this line is where it breaks
}
}
}
In case it is any helpful, I am trying to deploy to iPhone 5S simulator running iOS 9.3 (but it breaks on iPhone 6 simulator as well). I could also post more of my code if necessary, but I copypasted all the C# from Xamarin's tutorial, and did the same thing as them for Main.storyboard.
I have spent a while looking for people with the same problem as me, but their solutions either did not work, or they got the error for slightly different reasons. Any assistance is appreciated.
EDIT: Here is my implementation of TranslateButton_TouchUpInside:
TranslateButton.TouchUpInside += (object sender, EventArgs e) =>
{
// Convert the phone number with text to a number
// using PhoneTranslator.cs
translatedNumber = PhoneTranslator.ToNumber(PhoneNumberText.Text);
// Dismiss the keyboard if text field was tapped
PhoneNumberText.ResignFirstResponder();
if (translatedNumber == "")
{
CallButton.SetTitle("Call", UIControlState.Normal);
CallButton.Enabled = false;
}
else
{
CallButton.SetTitle("Call " + translatedNumber, UIControlState.Normal);
CallButton.Enabled = true;
}
};
The iOS Runtime is looking for a method called (in Obj-C land) TranslateButton_TouchUpInside: in your ViewController class. However there is no method exported to Obj-C with that name. A first guess is that you added an event to the button in the storyboard that perhaps had that name, but you either deleted that method or never implemented it.
Try opening your storyboard in iOS Designer and removing any event from the Properties->Events tab when your button is selected on the canvas. Also I assume your button has the name TranslateButton in the Properties->Widget pane when the button is selected on the canvas.
There are a couple ways to attach events to controls in Xamarin iOS. One, and the preferred way, is to create an event in iOS Designer for the control. If you do this, a partial method stub will be in the .designer.cs file with an Export attribute that exports the method name to the Obj-C runtime. You will then need to implement this method, using the same signature (without the Export Attribute), in your main .cs file for the ViewController. This is called, in Obj-C land, an action.
The other way is to do as is shown in your code snippet. In this case you ONLY need to give the control a name in the Properties->Widget pane that you can then use in code to subscribe to the TouchUpInside event. This is called, in Obj-C land, an outlet.
My guess is that you did both but without ever implementing the TranslateButton_TouchUpInside: method in your ViewController. Note that this is the Obj-C name used in the Export attribute of the method stub created in the .designer.cs file when you add an event to a control.
But it is hard to say without seeing the storyboard and both the main ViewController.cs file and the ViewController.designer.cs file

Is my code legal in Android usage?

I asked a question recently about how to disable the back button is Android, after a while I got it working with these lines of code
public override void OnBackPressed ()
{
// base.OnBackPressed (); /* Comment this base call to avoid calling Finish() */
// Do nothing
}
And just recently someone commented this
Disabling the back button is counter-intuitive and breaks the device
usage contract imposed by Android. So i suggest you rethink.
-Question-
What would be a possible change to this? I dont want to be able to press the back button when playing my quiz game because that would make be able to cheat. New to android Development
Instead of simply making the back button do nothing, you could have it create a popup asking something along the lines of "Are you sure you want to leave the quiz? (This will count as a loss)". And have it take the user back to the main page of your app if he confirms (instead of back to the previous page).
Why not imitate what many websites do and make it so going 'back' to a page works but doesn't display any information?
It depends on your code, but perhaps you can make your buttons and text (or whatever it is you don't want them interacting with) change to be unseen whenever they move on to a new page. Or just throw up a message that says 'You can't do that' to cover the page that they'll only ever see if they go back to view it again.

C# PresentViewController to a viewcontroller in storyboard

I am creating my first Xamarin-application (C#) in iOS and I am having trouble with navigating in storyboard. All of my tabbar-,navigation- and viewcontrollers are in the storyboard. In almost every viewcontroller, I added a menu (Facebook- and YouTube-style) which slides from the side. From there it has to be possible to return to the first viewcontroller (home) in storyboard. Because the menu is active in almost every controller of my application, I don't use segues (It would be a mess in my storyboard).
So I would want to use PresentViewController(), but when I do this, the page turnes black and doesn't show anything.
homeViewController home = new homeViewController();
PresentViewController(home, true, null);
Does it turn black because PresentViewController expects a XIB-file from the homeViewController? I want the user to stay in the storyboard, so he can continue by segueing through my application.
Does someone has an idea?
Thanks in advance.
Did you create the empty constructor yourself? If so, then its not loading the information from the storyboard, which is why it's black.
To create the controller call this:
var controller = Storyboard.InstantiateViewController("HomeViewController") as UIViewController;
You will also have to open the controller in XCode and set its "Storyboard ID" to "HomeViewController". This is the second tab from the left (I think) in the details pane. The same tab where you change the class.

Button Questions in MonoTouch

I'm working with MonoTouch and I have come up with three questions around buttons that I'm hoping someone can help me with.
I'm trying to change the "Back" button in the title bar. How do I do this? I've seen the thread posted here: How to change text on a back button. However, that doesn't work. I get the vibe that I'm not accessing the controller property. Currently, I receive a NullReferenceException when I attempt to set the button text in the ViewDidLoad method. Currently, I'm trying to set the text like such:
this.NavigationItem.BackBarButtonItem.Title = "Back";
I have the suspicion that I'm not accessing the root controller, but I'm not sure how to do this.
For a "back" button on a separate page, I want to perform a custom action. I want it to go back like it does. But before that happens, I want to execute some custom code. How do I do this?
I need to create something that looks like a hyperlink within a paragraph of text. How do I do that?
MonoTouch seems cool. However, the learning curve is a bit steeper than I had anticipated. Thank you!
For your first question the MonoTouch-specific answer (to the question you provided) works perfectly.
this.NavigationItem.BackBarButtonItem = new UIBarButtonItem ("MyBack", UIBarButtonItemStyle.Plain, null);
Make sure to the all the answers. This code needs to be called in the pushing controller, not the controller being pushed.
UPDATE
For your second question you likely noticed a few overloads that takes a Selector or a delegate. However they won't work for a Back button.
One way to work around this iOS limitation is to override ViewDidAppear or ViewDidDisappear to get similar notification.
I solved your third question by creating a custom button in de viewbuilder. Setting the type to custom removes de standard borders and makes it look like a line of text. Simply change its size and style it to make it look more like an hyperlink. I left an empty space in my text and and put my custom button in that space.
I created an extension method that allows you to change the back button text and optionally handle the TouchUp action with your own code. It also keeps the same border look as the default back button.
public static class MyExtensions
{
public static void SetCustomBackButton(this UIViewController uiViewController, string buttonText, Action onClick)
{
uiViewController.NavigationItem.HidesBackButton = true;
var dummyButton = UIButton.FromType (UIButtonType.Custom);
var backButton = (UIButton)MonoTouch.ObjCRuntime.Runtime.GetNSObject (
MonoTouch.ObjCRuntime.Messaging.IntPtr_objc_msgSend_int (
dummyButton.ClassHandle, MonoTouch.ObjCRuntime.Selector.GetHandle ("buttonWithType:"), 101));
backButton.SetTitle (buttonText, UIControlState.Normal);
backButton.TouchUpInside += delegate {
if (onClick != null)
onClick ();
else
uiViewController.NavigationController.PopViewControllerAnimated (true);
};
uiViewController.NavigationItem.LeftBarButtonItem = new UIBarButtonItem (backButton);
}
}

Categories