Display tooltip on touch with TeeChart Mobile iOS - xamarin.ios

I would like to display a tooltip when one touches a point in my graph.
I've tried SeriesHotspot, Annotations and Marks with no success.
Is there a way to achieve this on TeeChart Mobile?
Thanks for your help.

the MarksTip Tool still not available for the available version, but we're going to consider to add it in one of the next releases or maintenance releases.
In meantime the only way I can think of would be to make use of the Click_Series event, and to the work there. As you have all the necessary information, you should be able to display the info into the screen once the user tap over the Series point.
Code should look like :
Adding event for the series :
_controller.chart.ClickSeries += new Steema.TeeChart.TChart.SeriesEventHandler(series_clicked);
And here the method to call :
private void series_clicked(object sender, Steema.TeeChart.Styles.Series s, int valueIndex, UIGestureRecognizer e)
{
//Console.WriteLine("Series clicked");
_controller.chart.Tools.Clear();
_controller.chart.Tools.Add(new Steema.TeeChart.Tools.Annotation());
int i = _controller.chart.Tools.Count-1;
(_controller.chart.Tools[i] as Steema.TeeChart.Tools.Annotation).Text = _controller.chart.Series[0].YValues[valueIndex].ToString();
(_controller.chart.Tools[i] as Steema.TeeChart.Tools.Annotation).Top = 50;
(_controller.chart.Tools[i] as Steema.TeeChart.Tools.Annotation).Left = 50;
(_controller.chart.Tools[i] as Steema.TeeChart.Tools.Annotation).Shape.Font.Size = 20;
(_controller.chart.Tools[i] as Steema.TeeChart.Tools.Annotation).Shape.Font.Color = UIColor.Red.CGColor;
(_controller.chart.Tools[i] as Steema.TeeChart.Tools.Annotation).Shape.Transparent = true;
}
Hope that it helps.
regards !
Pep

Related

iOS 13 Changes to UISearchBar tint's, can't achieve the same outcome

I've been experimenting all day and trying to figure out just how to get my UISearchBar to appear the same in iOS13 as it appears in iOS12/11
So the way the search bar is added is simply a new UISearchController.
var searchController = new UISearchController(searchResultsController: null);
searchController.SearchBar.Placeholder = "Search";
searchController.SearchResultsUpdater = this;
searchController.HidesNavigationBarDuringPresentation = false;
searchController.DimsBackgroundDuringPresentation = false;
NavigationItem.SearchController = searchController;
NavigationItem.HidesSearchBarWhenScrolling = false;
The results on iOS 11/12:
The results on iOS 13:
On iOS 13 I am using the new UINavigationBarAppearance code like this:
var appearance = new UINavigationBarAppearance();
appearance.ConfigureWithOpaqueBackground();
appearance.BackgroundColor = ColorPalette.TintColor;
appearance.TitleTextAttributes = new UIStringAttributes { ForegroundColor = UIColor.White };
NavigationItem.StandardAppearance = appearance;
On iOS 11/12 I am using legacy way to achieve it:
NavigationController.NavigationBar.BarStyle = UIBarStyle.Black;
NavigationController.NavigationBar.TintColor = UIColor.White;
NavigationController.NavigationBar.BarTintColor = ColorPalette.TintColor;
NavigationController.NavigationBar.Translucent = false;
I've tried a number of things, but can't seem to get the UISearchBar to tint by itself how iOS11/12 achieves it.
I know that the new UISearchBar now has access to the UITextField and I can configure the background color's etc.
searchBar.setSearchFieldBackgroundImage(UIImage(), for: .normal)
The code above has a side effect which removes corner radius of the text field.
Extension
extension UISearchBar {
  /// This solves iOS 13 issue which is a light gray overay covers the textField.
  /// - Parameter color: A color for searchField
  func setSearchFieldBackgroundColor(_ color: UIColor) {
    searchTextField.backgroundColor = color
    setSearchFieldBackgroundImage(UIImage(), for: .normal)
    // Make up the default cornerRadius changed by `setSearchFieldBackgroundImage(_:for:)`
    searchTextField.layer.cornerRadius = 10
    searchTextField.clipsToBounds = true
  }
}
There were several properties added in iOS 13, so you need to use them with the help of a conditional. For changing the background color, you have to use the BackgroundColor property of the SearchBar, like this
searchController.SearchBar.BackgroundColor = UIColor.Red;
Use a custom renderer and override the OnElementChanged method this way
protected override void OnElementChanged(ElementChangedEventArgs<SearchBar> e)
{
base.OnElementChanged(e);
if (Control != null)
{
if(UIDevice.CurrentDevice.CheckSystemVersion(13,0))
Control.SearchTextField.BackgroundColor = Element.BackgroundColor.ToUIColor();
}
}
later on, you don't have to do anything else and worked for me on ios 12 and ios 13+
On iOS 13, you have access to the internal UISearchTextField through the SearchTextField property, you can set it's background directly (in my case, I need the background to be white). Be sure to check the iOS version to avoid exceptions.
if(UIDevice.CurrentDevice.CheckSystemVersion(13,0))
{
searchController.SearchBar.SearchTextField.BackgroundColor = UIColor.White;
}
You can achieve desired result by adding couple of lines.
searchBar.barTintColor = UIColor.red
searchBar.searchTextField.backgroundColor = UIColor.white
Before you try this code please link IB Outlets for searchBar
#IBOutlet weak var searchBar: UISearchBar!

Could I Intercept Exit FullScreen event from octane.xam.VideoPlayer plugin (XAMARIN FORMS)?

My application works portait, ma i want fullscreen video playback even in landscape mode using the plugin mentionend above.
For this purpose I create a customrenderer to take access to native AVPlayerViewController Ios Control.
I tried in many many ways, but seems to be impossible to handle exit fullscreen event. In that method i want to force layout portrait. I have the code for reset orientation already implemented but the problem is to put the code in the right place.
Any other that faced the same issue??
I tried to search for something useful in AVPlayerView(not accessible), AVPlayerVideoController, AVPlayerCurrentItem etc
Any ideas?
Thanks you in advance.
I have translated the OC code to C# in this link for you, see the following codes:
using Foundation;
using CoreGraphics;
playerViewController = new AVPlayerViewController();
playerViewController.ContentOverlayView.AddObserver(this, new NSString("bounds"), NSKeyValueObservingOptions.New | NSKeyValueObservingOptions.Old , IntPtr.Zero);
public override void ObserveValue(NSString keyPath, NSObject ofObject, NSDictionary change, IntPtr context)
{
base.ObserveValue(keyPath, ofObject, change, context);
if(ofObject == playerViewController.ContentOverlayView)
{
if(keyPath == "bounds")
{
NSValue oldRect = change.ValueForKey(new NSString("NSKeyValueChangeOldKey")) as NSValue;
NSValue newRect = change.ValueForKey(new NSString("NSKeyValueChangeNewKey")) as NSValue;
CGRect oldBounds = oldRect.CGRectValue;
CGRect newBounds = newRect.CGRectValue;
bool wasFullscreen = CGRect.Equals(oldBounds, UIScreen.MainScreen.Bounds);
bool isFullscreen = CGRect.Equals(newBounds, UIScreen.MainScreen.Bounds);
if(isFullscreen && !wasFullscreen)
{
if(CGRect.Equals(oldBounds,new CGRect(0,0,newBounds.Size.Height, newBounds.Size.Width)))
{
Console.WriteLine("rotated fullscreen");
}
else
{
Console.WriteLine("entered fullscreen");
}
}
else if(!isFullscreen && wasFullscreen)
{
Console.WriteLine("exited fullscreen");
}
}
}
}

ListView with Groove like quick return header

When scrolling down, Groove moves the header up, outside of the viewable area just like a regular ListView header. When scrolling back up it moves the header back down into the viewable area right away, regardless of the current vertical scroll offset. The header seems to be part of the ListView content because the scrollbar includes the header.
How can this be implemented in a Windows 10 UWP app?
You can do this by utilizing the ListView's internal ScrollViewer's ViewChanged event.
First you got to obtain the internal ScrollViewer. This is the simplest version, but you might want to use one of the many VisualTreeHelper Extensions around to do it safer and easier:
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
var border = VisualTreeHelper.GetChild(MyListView, 0);
var scrollviewer = VisualTreeHelper.GetChild(border, 0) as ScrollViewer;
scrollviewer.ViewChanged += Scrollviewer_ViewChanged;
}
In the EventHandler, you can then change the visibility of your header depending on the scroll direction.
private void Scrollviewer_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
{
var sv = sender as ScrollViewer;
if (sv.VerticalOffset > _lastVerticalOffset)
{
MyHeader.Visibility = Visibility.Collapsed;
}
else
{
MyHeader.Visibility = Visibility.Visible;
}
}
This is the basic idea. You might wan't to add some smooth animations instead of just changing the visibility.
After looking around a bit and experimentation I can now answer my own question.
One can use an expression based composition animation to adjust the Y offset of the the header in relation to scrolling. The idea is based on this answer. I prepared a complete working example on GitHub.
The animation is prepared in the SizeChanged event of the ListView:
ScrollViewer scrollViewer = null;
private double previousVerticalScrollOffset = 0.0;
private CompositionPropertySet scrollProperties;
private CompositionPropertySet animationProperties;
SizeChanged += (sender, args) =>
{
if (scrollProperties == null)
scrollProperties = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(scrollViewer);
var compositor = scrollProperties.Compositor;
if (animationProperties == null)
{
animationProperties = compositor.CreatePropertySet();
animationProperties.InsertScalar("OffsetY", 0.0f);
}
var expressionAnimation = compositor.CreateExpressionAnimation("animationProperties.OffsetY - ScrollingProperties.Translation.Y");
expressionAnimation.SetReferenceParameter("ScrollingProperties", scrollProperties);
expressionAnimation.SetReferenceParameter("animationProperties", animationProperties);
var headerVisual = ElementCompositionPreview.GetElementVisual((UIElement)Header);
headerVisual.StartAnimation("Offset.Y", expressionAnimation);
};
The OffsetY variable in the animationProperties will drive the animation of the OffsetY property of the header. The OffsetY variable is updated in the ViewChanged event of the ScrollViewer:
scrollViewer.ViewChanged += (sender, args) =>
{
float oldOffsetY = 0.0f;
animationProperties.TryGetScalar("OffsetY", out oldOffsetY);
var delta = scrollViewer.VerticalOffset - previousVerticalScrollOffset;
previousVerticalScrollOffset = scrollViewer.VerticalOffset;
var newOffsetY = oldOffsetY - (float)delta;
// Keep values within negativ header size and 0
FrameworkElement header = (FrameworkElement)Header;
newOffsetY = Math.Max((float)-header.ActualHeight, newOffsetY);
newOffsetY = Math.Min(0, newOffsetY);
if (oldOffsetY != newOffsetY)
animationProperties.InsertScalar("OffsetY", newOffsetY);
};
While this does animate correctly, the header is not stacked on top of the ListView items. Therefore the final piece to the puzzle is to decrease the ZIndex of the ItemsPanelTemplate of the ListView:
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel Canvas.ZIndex="-1" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
Which gives this as a result:

How to find when a transition has finished

I've been playing with the code from this website
And now what I'm wanting to do is listen for when a transition has completed so that I can start another transition in sequence. For example...
import "dart:html";
num rotatePos = 0;
void main() {
query("#buttonRotate").onClick.listen(rotateElement);
}
void rotateElement(Event e) {
rotatePos += 360;
Element element = e.target;
element.style.transition = "1s";
element.style.transform = "rotate(${rotatePos}deg)";
//Thank you for the help, here is my code for anyone else having
//questions about this...
element.onTransitionEnd.listen(transitionFinished);
}
void transitionFinished(Event e) {
query("#text").text = "Event Finished!";
}
How would I then go about setting up a listen for when the transform, or transition is complete? Or am I simply going about this the wrong way? Basically what I ultimately want to do is play a series of transitions in sequence, and also be able to pause and continue the animation. I thought maybe the animationEvent class might be what I'm needing to use but so far the examples I've found seem to use this with the canvas, and I'm only wanting to animate dom elements.
use onwebkitTransitionEnd Event

Highlight the selected cell in a DataGridView?

In my code below, I'm showing a context menu when the user right-clicks on a cell in my DataGridView. I'd also like the cell that the user right-clicks on to change background color so that they can see the cell they've "right-click selected". Is there a way to add something to my code below so that this occurs?
private void dataGridView2_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
ContextMenu m = new ContextMenu();
MenuItem mnuCopy = new MenuItem("Copy");
mnuCopy.Click += new EventHandler(mnuCopy_Click);
m.MenuItems.Add(mnuCopy);
int currentMouseOverRow = dataGridView2.HitTest(e.X, e.Y).RowIndex;
m.Show(dataGridView2, new Point(e.X, e.Y));
}
}
So obviously you've hacked into my workstation and have seen some of the stuff I've worked on recently. I exaggerate a bit because I didn't do exactly what you're trying to do but with a little bit of tweaking I was able to.
I would modify your MouseClick event to get the DGV's CurrentCell. Once you have it, set the CurrentCell's Style property with the SelectionBackColor you want. Something like this:
// ...
DataGridView.HitTestInfo hti = dataGridView2.HitTest(e.X, e.Y);
if (hti.Type == DataGridViewHitTestType.Cell) {
dataGridView2.CurrentCell = dataGridView2.Rows[hti.RowIndex].Cells[hti.ColumnIndex];
dataGridView2.CurrentCell.Style = new DataGridViewCellStyle { SelectionBackColor = System.Drawing.Color.Yellow};
}
//...
The above is a bit 'air code-y' (in other words I haven't attempted to merge it with your code and run it) but I hope you get the idea. Notice that I check through the hit test that a cell was clicked; if you don't do this and the user does not click a cell you might have some problems.
Now there's the problem that this code will change the SelectionBackColor for the all the cells you right click. That's easy to restore this property in the DGV's CellLeave event:
private void dgvBatches_CellLeave(object sender, DataGridViewCellEventArgs e) {
dataGridView2.CurrentCell.Style = new DataGridViewCellStyle { SelectionBackColor = System.Drawing.SystemColors.Highlight };
}
I'll have to remember this visual affect; thanks for asking the question.

Resources