【问题标题】:MonoTouch: UISegmentedControl Select a segment that is already selectedMonoTouch: UISegmentedControl 选择一个已经被选中的段
【发布时间】:2012-01-02 15:47:46
【问题描述】:

我正在尝试使用UISegmentedControl 来控制我的表格的排序顺序,特别是我想在已经选择的段上注册一个点击(以反转我的排序)。因此,每当点击任何段时,我都会尝试引发 UIControlEvent.ValueChanged 事件。

我已经从UISegmentedControl 覆盖了SelectedSegment,并在xcode 中为我的元素使用了这个自定义类,但是,当点击Segment 控件时,似乎没有调用此代码(它是 在视图加载时调用(尽管 =S)。

[Register("ReselectableSegment")]
public class ReselectableSegment : UISegmentedControl
{
    static Selector selInit       = new Selector("init");  

    [Export("init")]  
    public ReselectableSegment()  
        : base(NSObjectFlag.Empty)  
    {  
        Handle = Messaging.IntPtr_objc_msgSend(this.Handle,  
            selInit.Handle);  
    }  

    public ReselectableSegment (IntPtr handle) : base(handle){}

    public override int SelectedSegment
    {
        [Export ("SelectedSegment:")]
        set { 
            if(this.SelectedSegment == value)
                this.SendActionForControlEvents(UIControlEvent.ValueChanged);

            base.SelectedSegment = value;
        }
    }
}

这个问题之前已经在UISegmentedControl register taps on selected segment 提出过,但是这个问题是针对 ObjC 的,而这个问题是针对 C#/Monotouch 的。

【问题讨论】:

    标签: c# iphone ios xamarin.ios uisegmentedcontrol


    【解决方案1】:

    您提供的问题link 的最后一个答案包含最佳(工作良好)答案(我赞成它,您也应该;-)。

    注意:从 cmets 看来,以前的答案(可能)适用于 iOS4,但不适用于 iOS5。

    这是执行您要查找的操作的代码。我使用RectangleF .ctor 对其进行测试,如果您使用其他东西,您可能必须添加自己的.ctor(但它不像您的原始代码那么复杂,例如不需要选择器来继承它)。

        class MyUISegmentedControl : UISegmentedControl {
    
            public MyUISegmentedControl (RectangleF r) : base (r) {}
    
            public override void TouchesBegan (NSSet touches, UIEvent evt)
            {
                int current = SelectedSegment;
                base.TouchesBegan (touches, evt);
                if (current == SelectedSegment)
                    SendActionForControlEvents (UIControlEvent.ValueChanged);
            }
        }
    

    【讨论】:

    • 谢谢 poupou。抱歉,我花了这么长时间才将其标记为答案,我被转移到做不同的事情上。您的回复帮了大忙!
    • 自我注意......“问题链接的最后答案”是模棱两可的,并且是一个移动的目标。最好提供答案的链接,而不是问题的链接。
    【解决方案2】:

    提供的链接对 iOS7 有很好的答案,但使用的是 Objective C/Swift,特别是当再次按下当前选定的段时取消选择段。

    这里是需要使用 TouchesEnded 事件而不是 TouchesBegan 的 C# 版本。使用 TouchesBegan 为我触发了两次 UISegmentedControl.ValueChanged 事件,这导致了不正确的行为。

    此代码包括处理何时触摸该段并将其拖离控件以取消事件。

     class OptionalSegmentedControl : UISegmentedControl
    {
    
    
        public override void TouchesEnded(NSSet touches, UIEvent evt)
        {
    
            // Getting touch information to work out whether segment has been pressed, then dragged off to cancel the event
            // Comment these lines out if you don't care about handling this
            CGPoint locationPoint = ((UITouch)touches.AnyObject).LocationInView(this);
            CGPoint viewPoint = this.ConvertPointFromView(locationPoint, this);
    
            // Save the selected segment first
            nint current = this.SelectedSegment;
    
            // then fire the event
            base.TouchesEnded(touches, evt);
    
    
            // Check if the touch point is still on the control when the touch has ended, 
            // as well as comparing the current and new selected segment values 
            // and then fire the ValueChanged event if the same segment is pressed
    
    
            // Use this line and comment the second if statement if you don't care about handling click and drag to cancel the event 
            //if (current == this.SelectedSegment)
            if ((this.PointInside(viewPoint, evt)) && (current == this.SelectedSegment))
            {
                this.SelectedSegment = -1;
                SendActionForControlEvents(UIControlEvent.ValueChanged);
            }
        }
    
    
    }
    

    然后在 ValueChanged 事件中,您使用 UISegmentedControl 执行您需要执行的操作:

                // cell.SegmentedControl for me was a UISegmented control in a UITableViewCell
                cell.SegmentedControl.ValueChanged += (s, e) =>
                {
                    OptionalSegmentedControl osc = (OptionalSegmentedControl)s;
    
                   // continue with your code logic.....
    
                };
    

    需要注意的一点是,我从 TouchesBegan void 开始,但是当我意识到 iOS7 及更高版本需要它时,我将名称更改为 TouchesEnded。直到我意识到我还必须更改线路时仍然没有工作:

    base.TouchesEnded(touches, evt);
    

    因此,如果您从 TouchesBegan 转换为 TouchesEnded,请不要忘记更改它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-19
      相关资源
      最近更新 更多