【问题标题】:Out of Bounds Error when Deselecting Segment取消选择段时出现越界错误
【发布时间】:2014-03-20 19:07:05
【问题描述】:

每当用户重新点击选定的段时,我都会尝试以编程方式从 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]'

我应该以其他方式取消选择该细分吗?根据this的回答,这是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.

【问题讨论】:

    标签: ios xamarin.ios xamarin uisegmentedcontrol


    【解决方案1】:

    以典型的形式,我想我已经解决了我自己的问题。我不确定为什么(也许有人可以澄清这一点),但这似乎与尝试在ValueChanged 事件中更改SelectedSegment 有关。本质上可能是某种突变异常。

    我重新编写了我的代码,因此在 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;
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-01-19
      • 1970-01-01
      • 2020-11-08
      • 1970-01-01
      • 1970-01-01
      • 2016-02-12
      • 1970-01-01
      • 2015-09-23
      • 2020-07-26
      相关资源
      最近更新 更多