NullReferenceException when trying to go to previous storyboard - xamarin.ios

a bit of an iOS beginner here. I am tasked with creating a button that will navigate to the previous view controller. I have tried a lot of different ways, but the most recent is as follows:
partial void ButtonPressedPreviousOne(UIButton sender)
{
UIStoryboard HomeStoryboard = UIStoryboard.FromName("Home", null);
UserProfileViewController prevController = HomeStoryboard.InstantiateViewController("User_Profile_VC") as UserProfileViewController;
NavigationController.PopToViewController(prevController, true);
}
This throws a null reference exception. I only partially understand what is meant by this. Is there something wrong with the above code or am I missing something entirely different?

iOS Navigation controller has method NavigationController.PopViewController(true).
Try this one. But I strongly recommended check stack before do this like
public bool CanGoBack => NavigationController.ViewControllers.Length > 1;

Let see how navigation works:
Push:
To move from one page to another, an application will push a new page
onto the navigation stack, where it will become the active page, as
shown in the following diagram:
When we push a page, we usually use:
NavigationController.PushViewController();
Pop:
To return back to the previous page, the application will pop the
current page from the navigation stack, and the new topmost page
becomes the active page, as shown in the following diagram:
When we pop a page:
If you want to go back to previous page, use:
NavigationController.PopViewController(true);
If you want to go back to root page, use:
NavigationController.PopToRootViewController(true);
If you want to go back to specific page in Navigation Stack, use:
NavigationController.PopToViewController(viewController, true);
Refer : hierarchical Navigation
Back to your code:
If you use PopToViewController, the first paramater(prevController in your code) should be a existing ViewController in Navigation Stack instead of a new created. You got a null reference exception because the prevController you created is not in your Navigation Stack.
In your case, you can use:
var navController = this.NavigationController;
foreach (var controller in navController.ViewControllers)
{
if (controller is UserProfileViewController)
{
NavigationController.PopToViewController(controller,true);
break;
}
}
Note: if UserProfileViewController is the previous page you want to pop, use NavigationController.PopViewController(true); directly is simpler and faster.

Related

Is there a way to prevent the user pressing the back button on their device from popping the current view from the stack?

I'm using React-Native-Navigation from Wix (version 2) to setup navigation in my React Native app. I'm using the sideMenu layout with the center section being a stack. When the user selects one of the side menu items the selected view is pushed onto that center stack. If the user presses their back button on Android, then the view is popped from the stack, but I don't always want this to happen, mainly if the view they selected is a WebView.
If the view is a WebView, I want to manually handle the user pressing the hardware back button. If the WebView can "goBack" then the view will go back, but if it can't then the view will be popped from the stack (as it normally would).
I've tried overriding the back button press using the BackHandler class from react-native and this allows me to capture that press and have the WebView go back if able, but the act of popping the view from the stack also fires. Is there a way in React-Native-Navigation v2 to tell it, "Hey I got this, don't pop unless I tell you to."?
My current code for this section is as follows:
componentDidMount() {
BackHandler.addEventListener('hardwareBackPress', this.backHandler);
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.backHandler);
}
backHandler = () => {
if (this.state.canGoBack) {
this.webviewRef.current.goBack();
// I thought this might force the back press to be
// ignored by react-native-navigation, but no dice.
return false;
} else {
// WebView can't go back so pop view like normal
Navigation.pop(this.props.componentId);
}
}
I was expecting this to only pop the view from the stack if the WebView can't currently go back and otherwise just have the WebView go back.
What actually occurs is both events fire. I.e. the WebView goes back, but the view is also popped from the stack.
I was able to find the answer to this through some more digging in the React Native Navigation and React Native docs.
The event subscriptions are called in reverse order (i.e. last registered subscription first), and if one subscription returns true then subscriptions registered earlier will not be called.
So the issue was in my backHandler method. Instead of returning false I needed to return true.
backHandler = () => {
if (this.state.canGoBack) {
this.webviewRef.current.goBack();
// We've handled the event so we return true and the
// handler on the view's parent can effectively be ignored. Yay!
return true;
} else {
// WebView can't go back so pop view like normal
Navigation.pop(this.props.componentId);
}
}

Sharepoint 2010 Site Page with User Control = Blank Page

I have a problem with a site definition, it has several site pages, in those pages i need to have a top menu, so i created a user control, that draw that menu, and added it to the pages.
After deploying the solution i can create the site just fine.
In the initial phase, i have hard coded values for the menu links, and in each of the pages i could see the menu.
Now the menu it's dynamic, so i have a sharepoint list with the menu options, so i changed the code, instead of hard-coded values, i get them from a list, the code runs fine, i can check that while debugging, but in the end i get a complete blank page.
I can't interact with sharepoint data inside a user control that will be used in a site page?
I tested the control in a normal/application page and it works just fine, in both cases (hard-coded and sharepoint data).
A simple sample of the code:
protected void Page_Load(object sender, EventArgs e)
{
lblDate.Text = DateTime.Now.ToLongTimeString();
ddlData.Items.Clear();
//Option Manual - WORKS FINE
ddlData.Items.Add("Manual 1");
ddlData.Items.Add("Manual 2");
ddlData.Items.Add("Manual 3");
//Option Sharepoint Data - DOESNT WORK
SPSecurity.RunWithElevatedPrivileges(delegate () {
using (SPSite site = SPContext.Current.Site)
{
using (SPWeb web = site.RootWeb)
{
foreach (SPList lista in web.Lists)
{
ddlData.Items.Add(lista.Title);
}
}
}
});
}
The rest of the code, it's a simple page with the reference to this user control, and the aspx code of the user control only have the declaration of this two controls.
After several tests, i came to conclusion that i have two problems:
1 - In this project for some reason, unknown to me, inside the code someone had added some code to clear the errors, that's why i had the blank page.
2 - After seeing the error, i could confirm that if i use site pages and trying to get the data with Using, when it tries to dispose the objects it throws the exception, so the solution was simple, just remove the Usings.
Thanks

faces-redirect=true not working while creating and rendering view

I am currently working on a JSF 2.2 application. As per requirements, I have created custom view handler (using ViewHandlerWrapper) for my application. All the methods are just passing to default view handler except renderView which I am overriding as follows -
private viewHandler viewHandlerWrapped = null;
renderView(FacesContext facesContext, UIViewRoot viewToRender) {
String viewId = viewToRender.getViewId();
if (viewId == some condition) {
/* Do calculation to derive viewId */
}
UIViewRoot viewRoot = viewHandlerWrapped.createView(facesContext,viewId+"?faces-redirect=true");
facesContext.setViewRoot(viewRoot);
//now let system render the view
viewHandlerWrapped.renderView(facesContext,viewRoot);
}
The above is working fine and rendering & navigation is happening as expected. The only issue is faces-redirect=true is not working. The URL seems to be always one behind.
I have gone through many answers given in stackoverflow or internet. But nowhere I am able to find how to solve this.
I think I am doing something wrong e.g. ?faces-redirect=true might not be the correct way while creating view. But I am not sure what can be done to correct this.
Can someone please help me out with this?
After struggling with this for more than 4 weeks, I finally found a way to get the correct URL (instead of previous one). I am updating my answer here in case any one else falls into same problem -
"It looks like we can not use the faces-redirect=true the way I was using while creating and rendering the pages. It should be suffixed with form action. So I have changed my code as follows -
1) actions are returned on click of a button e.g.
public string doAction {
----
return "action?faces-redirect=true";
}
2) Code is updated to use implicit navigation wherever possible. With this, I didn't need to build my custom viewhandler as navigation is happening implicitly. So, I have scrapped the viewhandler.
With above two simple steps, the correct URL is being displayed on the browser now.

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.

Avoiding from MomoryLeak while performing Segues

I can use navigation without segues (1) but I would like to use it (2).
Performing a segue and navigating back make my app slower ! Because it doesn't dispose destination view when I navigate back. How do you use this segues in a right way ?
/*1) This code ok! But what about segues */
if(_tabbarController==null)
_tabbarController = (UITabBarController)this.Storyboard
.InstantiateViewController ("MainTabbarController");
this.NavigationController.PushViewController (_tabbarController,true);
/*2) If I run this code I get a new instance of UITabbar */
this.PerformSegue("SegueShowDetail",this);
If you're using the Storyboard and a Navigation Controller, the navigation controller should automatically release your view and associated memory with it when it pops off the stack.
For example, if you've got a method that gets called when you push a button to go to another view, you'd have:
[self performSegueWithIdentifier:#"mySegueName" sender:self];
When you click the back button at the top left of your secondary view, this will trigger the navigation controller to dispose of the view.

Resources