I'm using NavigationController for navigation in my app. When the PushViewController starts(someUIViewController,true), it change view with default animation(move from right to left for child controller). How can i change this animation ? Now i'm using this:
this.NavigationController.PushViewController(someUIViewController,true);
UIView.BeginAnimations(null);
UIView.SetAnimationDuration(0.4);
UIView.SetAnimationTransition(UIViewAnimationTransition.FlipFromRight, NavigationController.View,true);
UIView.CommitAnimations();
But I'm limited to four UIViewAnimationTransition types.I found what I needed(the appearance of the view from the bottom to up):
this.NavigationController.PushViewController(someUIViewController,true);
var theAnimation = CABasicAnimation.FromKeyPath("transform.translation.y");
theAnimation.Duration = 0.3f;
theAnimation.From = NSNumber.FromFloat(this.View.Frame.Height);
theAnimation.To = NSNumber.FromFloat(0f);
NavigationController.View.Layer.AddAnimation(theAnimation, "animate");
NavigationController.View.Layer.AnimationForKey("animate");
But when CABasicAnimation starts, default animation (move from left to right to parent controller) starts too.The result is a wrong combination.How can I run only one(translation on y) or make custom animation?
I believe you need to change the call to PushViewController to not animate to avoid the default animation kicking in.
this.NavigationController.PushViewController(someUIViewController,true);
Should be
this.NavigationController.PushViewController(someUIViewController,false);
Was same problem. There is no normal solution for this. PushViewController is limited by the standard animation(type of UIViewAnimationTransition). If you want to change them, try this:
NavigationController.PushViewController(screen, false);
var theAnimation = CABasicAnimation.FromKeyPath("transform.translation.x");
theAnimation.Duration = 0.6f;
theAnimation.From = NSNumber.FromFloat(-NavigationController.View.Frame.Width);
theAnimation.To = NSNumber.FromFloat(0f);
NavigationController.View.Layer.AddAnimation(theAnimation, "animate");
NavigationController.View.Layer.AnimationForKey("animate");
But it is not perfect, try and u see why. Also u can use PresentViewController. It have some other standart animations in UIModalTransitionStyle:
this.NavigationController.PresentViewController(new UINavigationController(screen){
ModalTransitionStyle= UIModalTransitionStyle.CoverVertical,
}, true,null);
//Allows a UINavigationController to push using a custom animation transition
public static void PushControllerWithTransition(this UINavigationController
target, UIViewController controllerToPush,
UIViewAnimationOptions transition)
{
UIView.Transition(target.View, 0.75d, transition, delegate() {
target.PushViewController(controllerToPush, false);
}, null);
}
//Allows a UINavigationController to pop a using a custom animation
public static void PopControllerWithTransition(this UINavigationController
target, UIViewAnimationOptions transition)
{
UIView.Transition(target.View, 0.75d, transition, delegate() {
target.PopViewControllerAnimated(false);
}, null);
}
// With these extensions in scope, moving between controllers with a flip animation is now as trivial as this:
//Pushing someController to the top of the stack
NavigationController.PushControllerWithTransition(someController,
UIViewAnimationOptions.TransitionFlipFromLeft);
//Popping the current controller off the top of the stack
NavigationController.PopControllerWithTransition(
UIViewAnimationOptions.TransitionFlipFromRight);
Related
To change the TitleBarTextColor so far I tried a lot and my code now does change the back button color and the area on the very top of the screen, but the title!
in my AppDelegate FinishedLaunching function (it's after Forms.Init() and before LoadApplication()):
UINavigationBar.Appearance.SetTitleTextAttributes(new UITextAttributes
{
TextColor = UIColor.White
});
In my ViewModel:
(App.Current.MainPage as NavigationPage).BarBackgroundColor = Color.FromHex("#990000");
(App.Current.MainPage as NavigationPage).BarTextColor = Color.White;
And this is how I'm navigating between the pages (not all the pages):
await _navigationService.NavigateAsync(new Uri("http://wwww.x.com/NavigationPage/TabbedNavigationPage?selectedTab=XPage/Document", UriKind.Absolute));
I even try to call the ViewModel code after the Prism navigation but it doesn't work... I'm a beginner and don't fully comprehend Prism and or Xamarin Forms.
[EDIT] -> I also tried to create a new class and inherit it from NavigationPage, set the BarTextColor in its constructor and use that class in the navigation like this: await _navigationService.NavigateAsync(new Uri("http://wwww.x.com/NEWCLASSCREATED/TabbedNavigationPage?selectedTab=XPage/Document", UriKind.Absolute)); But, as you may know, it is still not working.
Here's a Image ;)
imageToSeeThatImNotLying
Thank you for your support!
So I finnaly managed to work this out...
What I had to do was to create a custom Content Page because all the other solutions wasn't working. So I created this custom renderer only in my iOS project:
[assembly: ExportRenderer(typeof(ContentPage), typeof(CustomContentPageRenderer))]
namespace TestProject.iOS.Bll.Utils.Renderers
{
public class CustomContentPageRenderer : PageRenderer
{
public override void DidMoveToParentViewController(UIViewController parent)
{
base.WillMoveToParentViewController(parent);
var titleView = new UITextView();
var page = this.Element as ContentPage;
try
{
if (!string.IsNullOrEmpty(page.Title))
{
titleView.Text = page.Title;
titleView.TextColor = UIColor.White;
titleView.Font = UIFont.SystemFontOfSize(17, UIFontWeight.Regular);
var bgColor = page.BackgroundColor;
titleView.BackgroundColor = UIColor.FromRGBA((int)bgColor.R, (int)bgColor.G, (int)bgColor.B, 0);
parent.NavigationItem.TitleView = titleView;
parent.NavigationItem.TitleView.ContentMode = UIViewContentMode.ScaleAspectFit;
}
}
catch (Exception e)
{
}
}
}
}
And I also removed all the code that I puted before in my AppDelegate file and in the App.xaml.cs file as well. I left the codes from the ViewModels because it was changing the back button to white, and I deleted the new NagivationPage class that I created before.
I'm going to explain why I did some of the things that you saw there:
To change the Title I created a UITextView() and set it to my NavigationItem.TitleView of the parent page. I set titleView.Text = page.Title; because my original page already have a title, so I'm just reusing it. And the backgroundcolor I had to do all of that so the backgroundcolor property works just in the way that I wanted.
And this DidMoveToParentViewController function was just so it can do all that before NavigationAsync from Prism.
I'm using iOS/Xamarin
When the user clicks a button, I'd like to change the background color of my view controller's main view (View).
In the button click event, I tried this:
partial void MyButton_TouchUpInside(UIButton sender)
{
InvokeOnMainThread(() =>
{
SetBackgroundColor(View);
});
}
but it doesn't work. I tried a few other main thread/uithread things but no luck.
If I call SetBackgroundColor(View) from the ViewDidLoad of course it works. I suspect this is a UI thread issue.
Any advice?
Thanks!
You can use the BackgroundColor property on the UIViewController's View property.
partial void MyButton_TouchUpInside(UIButton sender)
{
View.BackgroundColor = UIColor.Red;
}
Turns out the above code is good - somewhere else in the code someone was setting another layer on top of the background so I never saw it =/
Wanting to achieve a consistent look for my Xamarin Forms app, I need to know how to change the font for the tabbed page tab bar icons. Using UITabBarItem.Appearance as the iOS API would suggest does not appear to have any effect. What's necessary to do this?
U need to write a custom renderer like this one , take a clue from below code ! it has what u r seeking
[assembly: ExportRenderer(typeof(ExtendedTabbedPage), typeof(TabbedPageCustom))]
namespace App.iOS
{
public class TabbedPageCustom : TabbedRenderer
{
public TabbedPageCustom ()
{
TabBar.TintColor = UIKit.UIColor.White;
TabBar.BarTintColor = UIKit.UIColor.White;
TabBar.BackgroundColor = UIKit.UIColor.Red;
}
protected override void OnElementChanged (VisualElementChangedEventArgs e)
{
base.OnElementChanged (e);
// Set Text Font for unselected tab states
UITextAttributes normalTextAttributes = new UITextAttributes();
normalTextAttributes.Font = UIFont.FromName("ChalkboardSE-Light", 20.0F); // unselected
normalTextAttributes.TextColor = UIKit.UIColor.Blue;
UITabBarItem.Appearance.SetTitleTextAttributes(normalTextAttributes, UIControlState.Normal);
}
public override UIViewController SelectedViewController {
get {
UITextAttributes selectedTextAttributes = new UITextAttributes();
selectedTextAttributes.Font = UIFont.FromName("ChalkboardSE-Bold", 20.0F); // SELECTED
if (base.SelectedViewController != null)
{
base.SelectedViewController.TabBarItem.SetTitleTextAttributes(selectedTextAttributes, UIControlState.Normal);
}
return base.SelectedViewController;
}
set {
base.SelectedViewController = value;
foreach (UIViewController viewController in base.ViewControllers)
{
UITextAttributes normalTextAttributes = new UITextAttributes();
normalTextAttributes.Font = UIFont.FromName("ChalkboardSE-Light", 20.0F); // unselected
normalTextAttributes.TextColor = UIKit.UIColor.Blue;
viewController.TabBarItem.SetTitleTextAttributes(normalTextAttributes, UIControlState.Normal);
}
}
}
}
}
This was a particularly interesting problem. I tried:
UITabBarItem.Appearance
Using the UITabBarItem.Appearance.SetTitleTextAttributes method to update the UITextAttribute to my font (size 9.0f) for UIControlState.Normal. This didn't appear to make any difference.
UINavigationBar.Appearance
I found out that setting UINavigationBar.Appearance.SetTitleTextAttributes would update both the UINavigationBar text appearance as well as the UITabBarItem text appearance.
Which was a problem because the tabbed page item font size was far too large.
Customizing the TabbedRenderer
Inspired by a sample I saw somewhere, I subclassed TabbedRenderer in the iOS project.
I tried overriding the settor for TabbedRenderer.SelectedViewController property and loop through the ViewControllers property to set their items. The icons would display with the standard font, but once the user changed the tab they would all update to the desired font. Almost there!
I then tried overriding AddChildViewController and updating that controller's TabBarItem after it was added which ended up having no effect. The TabBarItem for the added page was being updated at some point after the controller was added.
Eventually I found out that overriding ViewWillAppear and setting the appearance for all the tab bar items at that time seemed to do the job I desired.
I've included a sample in this gist.
I am creating a tableview where I will have an UIImageViewinside a UITableViewCell that I would like to allow the user to zoom into. I have been able to create this effect inside a UIScrollView but have struggled to get it right for zooming into a single UITableViewCell.
At the bottom I have included the code that has worked for me for the UIScrollView. The challenge starts with what to return for the viewForZoomingInScrollView. If I try to give this method the UIImageView from the cell It throws an errors as it appears the viewForZoomingInScrollView is called before the table is loaded thus it can not find the cell I am referencing. If I pass the entire view itself self.view I can scroll but the entire tableview is zoomed (where I would like to zoom just the UIImageView inside the cell) and when I release the zoom I get an error Terminating app due to uncaught exception 'CALayerInvalidGeometry', reason: 'CALayer bounds contains NaN: [nan nan; 375 667] which is clearly not the correct path to take.
Any help or guidance here would be appreciated.
- (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return self.imageView;
}
- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
[self centerScrollViewContents];
}
- (void)centerScrollViewContents {
CGSize boundsSize = zoomTable.bounds.size;
CGRect contentsFrame = self.imageView.frame;
if (contentsFrame.size.width < boundsSize.width) {
contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width) / 2.0f;
} else {
contentsFrame.origin.x = 0.0f;
}
if (contentsFrame.size.height < boundsSize.height) {
contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height) / 2.0f;
} else {
contentsFrame.origin.y = 0.0f;
}
self.imageView.frame = contentsFrame;
}
It sounds to me as though you want something like what Facebook or Twitter have, where you tap on an image and it zooms to fit the screen.
What you need to do is to consider that as a navigational step -- i.e. conceptually similar to what happens if you select a row in a standard table view and it pushes a new view controller onto the navigation controller stack, except that you probably want to present modally using a custom transition.
In the simple case, this would mean adding a tap gesture recogniser to the cell's image view; for the full effect you would add a pinch gesture recogniser to make an interactive transition.
I'd recommend watching the following WWDC videos:
2013 Session 218 "Custom Transitions Using View Controllers"
2014 Session 214 "View Controller Advancements in iOS 8"
2014 Session 228 "A Look Inside Presentation Controllers"
From your question What I understand is that you wanted to implement the functionality of Zoom in and Zoom out for ImageView. You first implemented that in a sample where you had a ScrollView Inside a ViewController and then ImageView inside that ScrollView. Things worked for you as expected. But then when you wanted the same functionality inside the TableViewCell, things didn't work for you.
So, I am suggesting you to use a View inside ScrollView as a ZoomView, and that ZoomView should have the ImageView as subview. And return that ZoomView in the method:
- (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView { return self.ZoomView; }
I have two canvas's in a Grid, full scene "images" that I want to transition, I wonder how I would go about transitioning between these two Canvas controls.
Programatically I add the first canvas to the grid, then I add the second canvas to the grid, and remove the first, what I really want to do is transition between them.
Any suggestions on how I might achieve this programatically?
Thanks.
Edit: I have implemented this method, but am having problems, anyone able to tell me if I'm using it wrong?
private void doTransitionIn(Canvas slide)
{
SlideTransition slideLeft = new SlideTransition();
slideLeft.Mode = SlideTransitionMode.SlideDownFadeIn;
ITransition transition = slideLeft.GetTransition(slide);
transition.Completed += delegate { transition.Stop(); }; transition.Begin();
}
private void doTransitionOut(Canvas slide)
{
SlideTransition slideLeft = new SlideTransition();
slideLeft.Mode = SlideTransitionMode.SlideDownFadeOut;
ITransition transition = slideLeft.GetTransition(slide);
transition.Completed += delegate { transition.Stop(); }; transition.Begin();
}
And here is how I use it:
SceneGrid.Children.Add(nextCanvas);
doTransitionIn(nextCanvas);
doTransitionOut(currentCanvas);
SceneGrid.Children.Remove(currentCanvas);
The problem with this is that the animation only seems to start from part way down the screen, as in, i only see it slide the last 20 or so pixels, it doesn't slide all the way.
Depending on what you mean by "transition" I'd look at creating a StoryBoard to animate the hiding/showing of each canvas.
I would recommend using the TransitioningContentControl which is part of the Silverlight Toolkit. To use this control, make your first Canvas the Content of this control. To transition, simply change the Content to your next Canvas and the TransitioningContentControl does the rest!
There are a number of blog posts that provide tutorials for this control:
http://blogs.academicclub.org/uidev/2010/06/12/transitioning-content-in-silverlight/