I have a Grid with Buttons and will change the background color if the user swipe over them. I created a custom Button class:
public class TouchscreenTestButton : UIButton
{
public override void TouchesBegan(NSSet touches, UIEvent evt)
{
base.TouchesBegan(touches, evt);
this.BackgroundColor = UIColor.Green;
}
public override void TouchesMoved(NSSet touches, UIEvent evt)
{
base.TouchesMoved(touches, evt);
UITouch touch = touches.AnyObject as UITouch;
if (touch != null)
{
this.BackgroundColor = UIColor.Green;
SetNeedsDisplay();
}
}
public override void TouchesEnded(NSSet touches, UIEvent evt)
{
base.TouchesEnded(touches, evt);
UITouch touch = touches.AnyObject as UITouch;
if (touch != null)
{
this.BackgroundColor = UIColor.Green;
}
}
}
Also a Button Renderer for replace the normal UIButtons of iOS to my TouchscreenTestButton.
public class TouchscreenTestButtonRenderer : ButtonRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
{
int columnIndex = Grid.GetColumn(e.NewElement);
int rowIndex = Grid.GetRow(e.NewElement);
TouchscreenTestButton button = new TouchscreenTestButton();
button.TouchDown +=(sender, evt) => Control.BackgroundColor=UIColor.Green;
base.SetNativeControl(button);
base.OnElementChanged(e);
}
}
That doesnt work, only the first button I touch will get a green backgroundcolor. After that I create a Renderer for the Grid:
public class GridRenderer : ViewRenderer
{
public override void TouchesMoved(NSSet touches, UIEvent evt)
{
base.TouchesMoved(touches, evt);
var touch = touches.AnyObject as UITouch;
for (int i = 0; i < touch.View.Subviews.Length; i++)
{
var test = touch.LocationInView(this);
if (PointInside(touch.LocationInView(this), evt))
{
this.Subviews[i].TouchesBegan(touches, evt);
this.Subviews[i].BackgroundColor = UIColor.Green;
SetNeedsDisplay();
}
}
}
}
But also this doesnt work. I see that the event is fired and the backgroundcolor of the subview will be changed but the view doesnt update.
Can please somebody help? Thanks a lot!
I have test with the following code on my side , it works.
[assembly: ExportRenderer(typeof(Grid), typeof(GridRenderer))]
namespace Slide.iOS
{
class GridRenderer :ViewRenderer
{
public override void TouchesBegan(NSSet touches, UIEvent evt)
{
base.TouchesBegan(touches, evt);
var touch = touches.AnyObject as UITouch;
for (int i = 0; i < touch.View.Subviews.Length; i++)
{
var test = touch.LocationInView(this);
var buttonView = touch.View.Subviews[i];
CGRect frame = buttonView.Frame;
if (frame.Contains(test))
{
//pay attention
var button = buttonView.Subviews[0];
button.BackgroundColor = UIColor.Green;
}
}
}
public override void TouchesMoved(NSSet touches, UIEvent evt)
{
base.TouchesMoved(touches, evt);
var touch = touches.AnyObject as UITouch;
for (int i = 0; i < touch.View.Subviews.Length; i++)
{
var test = touch.LocationInView(this);
var buttonView = touch.View.Subviews[i];
CGRect frame = buttonView.Frame;
if (frame.Contains(test)) {
//pay attention
var button = buttonView.Subviews[0];
button.BackgroundColor = UIColor.Green;
}
}
}
}
}
Result :
1.Disable the button in Portable, since the click event will be conflict with the touch event of Grid.
<Button BackgroundColor="Red" Grid.Row="0" Grid.Column="0" IsEnabled="False"/>
2.Determine whether the point you moved to is in the frame of that subview(button).
if (frame.Contains(test))
3. Look at the buttonView, pay attention it was not the button!! I set the backgroundcolor on it at the beginning but it didn't work. When we layout control in a Grid, it will auto generate subviews according to its columns and rows,and then put the controls on the subviews.
e.g
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
The Grid above will have 4 subviews ,and four corresponding buttons on that subviews.