每当用户重新点击选定的段时,我都会尝试以编程方式从Xamarin中取消选择UISegmentedControl。我创建了一个继承的类,它将确定是否需要这个,但每当我尝试将SelectedSegment
设置为-1时,应用程序就会爆炸,抛出一个超出范围的异常。
public class UIDeselectableSegmentedControl : UISegmentedControl
{
private int previouslySelectedIndex = -1;
private bool isIOS7
{
get
{
return UIDevice.CurrentDevice.CheckSystemVersion(7, 0);
}
}
public UIDeselectableSegmentedControl()
{
this.ValueChanged += UIDeselectableSegmentedControl_ValueChanged;
}
void UIDeselectableSegmentedControl_ValueChanged(object sender, EventArgs e)
{
if (previouslySelectedIndex == this.SelectedSegment)
{
this.SelectedSegment = -1;
}
previouslySelectedIndex = this.SelectedSegment;
}
public override void TouchesBegan(NSSet touches, UIEvent evt)
{
int initialIndex = this.SelectedSegment;
base.TouchesBegan(touches, evt);
//Pre-iOS7 Segment Changes are present in Touches Began
if (!isIOS7) CheckSelectedSegment(initialIndex, this.SelectedSegment);
}
public override void TouchesEnded(NSSet touches, UIEvent evt)
{
int initialIndex = this.SelectedSegment;
base.TouchesEnded(touches, evt);
//Post-iOS7 Segment Changes are present in Touches Ended
if (isIOS7) CheckSelectedSegment(initialIndex, this.SelectedSegment);
}
/// <summary>
/// Compare the SelectedSegment with the Current Index value. If it is the same, raise the Value Changed event.
/// </summary>
/// <param name="index">Currently Selected Segment</param>
private void CheckSelectedSegment(int oldIndex, int newIndex)
{
if (oldIndex == newIndex)
{
this.SendActionForControlEvents(UIControlEvent.ValueChanged);
}
}
}
如果我将其更改为this.SelectedSegment = 0
,则只要您重新点击另一个选定项目,控件就会成功强制SegementedControl到第一个项目,但如果我将其设置为-1
,那么它抛出以下异常:
*由于未捕获的异常'NSRangeException'而终止应用程序,原因:'* - [__ NSArrayM objectAtIndex:]:索引4294967295超出边界[0 .. 1]'
我应该以不同的方式取消选择细分吗?根据{{3}}回答,这是Objective-C中的正确方法,而对SelectedSegment的元数据注释表明这是正确的:
//
// Summary:
// The index of the selected segment.
//
// Remarks:
// Set to -1 to turn off the currently selected segment. If MonoTouch.UIKit.UISegmentedControl.Momentary
// == true the SelectedSegment property is ignored.
答案 0 :(得分:0)
在典型的形式中,我认为我已经解决了自己的问题。我不确定为什么(也许有人可以澄清这一点),但这似乎与尝试更改SelectedSegment
事件中的ValueChanged
有关。可能是某种突变异常。
我已经重新编写了代码,因此在TouchesEnded / Began中调用的方法只是直接进行更改,而不是强制调用ValueChanged并自行更改它。在某种程度上,这更有意义,因为ValueChanged正在对变化作出反应 - 它可能不应该负责进行变更:
public class UIDeselectableSegmentedControl : UISegmentedControl
{
private bool isIOS7
{
get
{
return UIDevice.CurrentDevice.CheckSystemVersion(7, 0);
}
}
public override void TouchesBegan(NSSet touches, UIEvent evt)
{
int initialIndex = this.SelectedSegment;
base.TouchesBegan(touches, evt);
//Pre-iOS7 Segment Changes are present in Touches Began
if (!isIOS7) DeselectSegmentIfApplicable(initialIndex, this.SelectedSegment);
}
public override void TouchesEnded(NSSet touches, UIEvent evt)
{
int initialIndex = this.SelectedSegment;
base.TouchesEnded(touches, evt);
//Post-iOS7 Segment Changes are present in Touches Ended
if (isIOS7) DeselectSegmentIfApplicable(initialIndex, this.SelectedSegment);
}
/// <summary>
/// Compare the SelectedSegment with the Current Index value. If it is the same, raise the Deselect the Segment.
/// </summary>
/// <param name="oldIndex">the previously selected segment</param>
/// <param name="newIndex">The newly selected segment</param>
private void DeselectSegmentIfApplicable(int oldIndex, int newIndex)
{
if (oldIndex == newIndex)
{
this.SelectedSegment = -1;
}
}
}