Further to my experiences with MvvmCross, I've managed to build an app for iPhone which starts with a TabBarController. I can also successfully navigate within each tab to deeper levels. The problems start when I want to customise the navigationBar on the deeper levels - setting the backButton colours, etc. The code I use for navigation is the standard viewModel code -
this.RequestNavigate<InJourneyViewModel>();
…which works fine, but I can't do anything to the navigated-to view's navBar, other than set its title.
Any thoughts or advice appreciated!
I think it might help if you posted some more of your code that is failing.
My suspicion is that the problem is a more generic Cocoa, MonoTouch and/or backbarbutton problem.
I've just played with the ViewDidLoad code in MapView.cs in https://github.com/slodge/MvvmCross/tree/master/Sample%20-%20CirriousConference/Cirrious.Conference.UI.Touch
At the end of this, I was able to add some bar button changes like:
var leftButton = new UIBarButtonItem("FooBar", UIBarButtonItemStyle.Bordered, null);
leftButton.TintColor = UIColor.Green;
NavigationItem.SetLeftBarButtonItem(leftButton, false);
NavigationItem.RightBarButtonItem.TintColor = UIColor.Red;
Which resulted in:
Alternatively, by placing code in the WelcomeView:
var leftButton = new UIBarButtonItem("FooBar", UIBarButtonItemStyle.Bordered, null);
leftButton.TintColor = UIColor.Green;
NavigationItem.BackBarButton = leftButton;
Then I succeed in achieving:
Alternatively, by using code like:
UIBarButtonItem.AppearanceWhenContainedIn(typeof(UINavigationBar)).TintColor = UIColor.Blue;
Then this enabled me to customise all the navigation bar buttons like:
At one point, I also managed to achieve:
... but sadly I've genuinely no idea which code combo gave me that! If your problem is with back buttons in particular, then I think you will need to dig around other questions and/or post some code and hope someone can help - there's lots of posts about how to do this, but I can't quite figure out what they all mean for MonoTouch - e.g. Separate title in NavigationBar and navigation buttons
Related
I am developing a Xamarin.Forms app with Prism in which I'd like to incorporate an onboarding page (more specific a top user benefits page, following the Material Design guidelines).
The app itself is structured around a NavigationPage to which I navigate with
NavigationService.NavigateAsync("/NavigationRootPage/MainPage")
in my App(). On the first start I'd like to show the onboarding page instead and I am having quite some issues getting it right.
My first approach was to navigate to MainPage with
_navigationService.NavigateAsync("/NavigationRootPage/MainPage")
from my viewmodel, when the user clicks the Get Started! button. This kind of worked by is also kind of ugly, since this absolute navigation will destroy the oboarding page immediately and not animate the transition. Furthermore at the moment the oboarding page is destroyed, the MainPage will be built, which will take a small, but noticeable, amount of time. In effect the user will notice the MainPage being built up, which does not look smooth at all.
My second approach was to navigate in a relative fashion from my viewmodel.
_navigationService.NavigateAsync("NavigationRootPage/MainPage")
This works way smoother, with the transition animation and after the animation is done, the MainPage is already ready to go. But again there is a major drawback. You can navigate back to the onbaording page, which we dont't want neither. And - to my knowledge - there is no (clean) way to remove the page from the navigation stack, too. I tried calling PageUtility.DestroyPage on my onboarding page, but this only worsened things, since it seemed to keep the page, but destroy the viewmodel, resulting in my onboarding page being shown without data when pushing the back button.
My third approach did not work at all, although it seemed promising to me. In my App() I pushed my navigation page with the main page then then my onboarding page modal
NavigationService.NavigateAsync("/NavigationRootPage/MainPage");
NavigationService.NavigateAsync("OnboardingPage", useModalNavigation: true);
and then in my viewmodel
_navigationService.GoBackAsync(useModalNavigation: true)
but this approach
showed the header of the NavigationPage although the onbaording page was supposed to be shown as a modal
refused to GoBackAsync - when calling this method, nothing happens
waiting for the first call to NavigateAsync did not change anything either.
Some other things I've tried
Implemented INavigationOptions in my viewmodel with ClearNavigationStackOnNavigation being true
Tried setting Application.MainPage after my NavigationPage was shown, but to no avail
I would have believed that this was king of a common requirement when programming an app. Is there something I've missed? Or will I have to live with one of those drawbacks?
I think you are overthinking this. If you want to show your Onborading page first then just navigate to it first.
`NavigateAsync("NavigationPage/OnboardingPage");
Or if you want to have the MainPage in the stack, then start the app with a deeplink
`NavigateAsync("NavigationPage/MainPage/OnboardingPage");
If you don't want to show the navigation header, just hide it for the onboarding page.
Don't use an absolute navigation unless you want to completely reset the navigation stack (equivalent to MainPage = new MainPage()).
I have found a solution, which is not the most beautiful one (it is actually quite ugly) but working.
In my MainPages viewmodel I implemented INavigatingAware and navigated to my OnboardingPage modally
public async void OnNavigatingTo(NavigationParameters parameters)
{
await _navigationService.NavigateAsync("LandingPage", useModalNavigation: true);
}
However, removing the moal page with
this._navigationService.GoBackAsync(useModalNavigation: true);
does not work as expected. The modal is not removed (although it should work this way from looking at the code, but I did not manage to debug with Re# generated PDBs). Hence I had to go the ugly (non-MVVM) way and create an event handler for Button.Click and remove the modal manually
private void Button_OnClicked(object sender, EventArgs e)
{
this.Navigation.PopModalAsync();
}
This will return to my MainPage smoothly with an animation and my MainPageis already up and running without being built up while already visible.
Still, I'd appreciate an answer on how to do it the Prism way.
Im trying to implement delete button in GRID, same as with CRUD. I found dialogOK (http://agiletoolkit.org/blog/introduction-to-dialog-integration/), but guess i don't know how to use it right.
My code:
$gridC=$this->add('Grid');
$gridC->setModel('Campaign');
$gridC->addcolumn('Button', 'Delete')->js('click', $this->js()->univ()->dialogOK('Yey','Some custom javascript action here',$this->delete()));
//test only
$gridC->addcolumn('Button', 'Deletex')->js('click')->univ()->dialogOK('Are you sure?','This will take you to other page',$this->js()->univ()->page($this->api->getDestinationURL('admin')));
...
function delete(){
...
}
When i click on the button the delete() function starts right away, before i click ok. Also modal window is started :(
Any suggestions, i searched but couldn't find any good example..
NEXT DAY:
I checked the thing again, im almost shure i did it the right way, but i think i found a bug i dialogOK (http://agiletoolkit.org/blog/introduction-to-dialog-integration/)
I i re-create this example on any normal page:
$button = $this->add('Button');
$button->js('click')->univ()->dialogOK('Are you sure?','This will take you to other page',
$button->js()->univ()->page($this->api->getDestinationURL('index'))
);
The page redirects to index page, it doen't wait for OK button clicked. Insted it opens the dialogOK, but in the background redirects to index page..
I'm using atk 4.2.5 from master branch..
OK, that webpage has some bugs :( I would really appreciate if you could edit it and send in pull request in Github atk4-web.
Some tips to get you on road:
Try to use dialogConfirm() method not dialogOK(). Is it working then?
Try to add ->_enclose() after ->page(). That'll enclose JS expression in function.
If dialogConfirm() works and similar dialogOK() does not work, then I guess there is small bug in dialogOK() method. There should be close: if(fn)fn(), instead of close: fn, in atk4_univ.js file dialogOK method.
Can you try these tips and tell me what works for you? Sorry I didn't do that myself - I'm really out of time now :(
i got a simple scenario where i have an administrative list of DB-Entries. On click i call the remote-attribute and display the data.
Now the Modal Dialog contains Action-Buttons like "Delete", "Approve", "Nothing".
So whenever i click one of those buttons, i'd like to get the ID of the DB-Entry.
Going by this PullRequest on GitHub on Bootstrap 2.3 there was a relatedTarget attribute on the event. Apparently on v3 this has been removed. So i'm really wondering on how i should implement this kind of feature.
//Syntax Bootstrap v2.3
$('#modal').on('show.bs.modal', function(e){
console.log(e.relatedTarget);
});
//Syntax Bootstrap v3.0
????
A fiddle shouldn't really help to understand the question, but here's one anyways
Since i have identified buttons on the modal dialog, a functionality like this works. Though for some reason i feel for this to be a little messy and I'm still wondering if there's a different solution to this:
// Button to open the Modal Dialog
Foo
// Button inside the Modal view
delete
And then the JS to get the article ID on Delete-Button-Click:
$('#delete-article').on('click', function(){
var articleId = $('#modalDiv').data('bs.modal').options.articleId;
// artticleId = 1
});
Since i have to make another "query" onto the DOM, i feel for this method to be quite dirty. If there's any other way to get the data in a more performant way, I'd gladly take that information :)
I have a problem.
My app is a tab bar controller and its first view controller is a split view controller.
This seems to be not ok for Apple because documents say a split voew controller must be the root, so perhaps that is the reason of my problems.
The problem is that sometimes, willHideViewController from UISplitViewControllerDelegate is not called, so, for this reason, the upper/left button sometimes is not created, which is anoying.
I realised, to reproduce this error, try several times this:
-Landscape mode.
-Select a tab different to split view controller tap.
-Move the iPad to portrait in that tab.
-Go to the split view controller tab, and sometimes, willHideViewController is not called so you will not see the upper button. However if I rotate my iPad to landscape and after that to portrait, it's fixed.
I tried to force manually several rotations to work around this problem, but no luck.
I still have to try any split view controller clone class from github or similar.
Do you have idea what's going on or any work around?
Here I show you two examples working properly.
Thanks a lot for your help.
Where do you set the splitViewControllers delegate? Perhaps you can set the delegate when you load the tab. It sounds like you set it only when you have rotated once?
Otherwise, see this example
Here they have the TableViewController be the delegate of the splitviewcontroller. Perhaps you could do the same with the TabBarController?
I've concluded that this can't be done in any way that I consider 'sufficiently' legitimate. It's possible to get frustratingly close, but the issue of having the willShow..., willHide disseminated to the split view controllers under each tab remains.
The solution that seems most likely to work is,
https://github.com/grgcombs/IntelligentSplitViewController/blob/master/IntelligentSplitViewController.m
Though this code is undoubtedly clever, it's a bit too 'side door' for me. I suspect (but don't know) that just invoking the delegate methods is not sufficient. Surely the UISplitViewController itself needs to change it's internal state as well as calling the delegate methods? This method 'just' invokes the delegate methods when there's an orientation change.
So... I've decided on a more legitimate solution, which is to use the new method introduced in iOS 5.
- (BOOL) splitViewController:(UISplitViewController *)svc
shouldHideViewController:(UIViewController *)vc
inOrientation:(UIInterfaceOrientation)orientation
{
return NO;
}
So, the master menu is never hidden, and therefore the problem of managing the popover doesn't arise.
Of course, this is still not totally 'legit' as it still includes UISplitViewControllers that are not at the top level (the UITabViewController is at the top level, and the split views are on each tab)
Good luck with whichever solution you choose.
I'll update this reply when I've confirmed Apple will approve an app using this solution.
I`m really new to Flex and ActionScript so please be patient with me.
I want to implement this script: tinyurl.com/yafqrqb
...that is doing this "magic" : tinyurl.com/y9qg32r
...but I want to tweak it a little on InfoWindowTabbedComponent. To be more precisely I`m trying to insert links in that tabs, and when you click one the state will change.
You can see my custom InfoWindowTabbedComponent at the end of the post As you can see, right now I have 2 functions that open url`s.
What I`m trying to do is to change this:
var adobeURL:URLRequest = new URLRequest("http://www.microsoft.com" );
navigateToURL(adobeURL, "_self");
Into something that change the current state.
Can you please help me?
Here`s my custom InfoWindowTabbedComponent: http://pastebin.com/f387bc3b9
I'm not sure I understand what you want to do. If you just want to set the selected Tab, instead of calling navigateToURL() set myTabNavigator.selectedIndex (or selectedChild)
If you really want to change the state, each component has a currentState property, but then you would have to define the states first (via the tag)
And if you really want to navigateToURL() you could navigate to javascript:somefunction() and then set the application state via ExternalInterface, but that would be horribly circumstantial.
Cheers,
Jörg