选择一个已经被选中的段
本文关键字:一个 选择 | 更新日期: 2023-09-27 18:15:27
我试图使用UISegmentedControl
来控制表的排序顺序,特别是我想在已经选择的段上注册一个tap(以逆我的排序)。因此,每当任何段被点击时,我都试图引发UIControlEvent.ValueChanged
事件。
我已经从UISegmentedControl
中重写了SelectedSegment
,并且在xcode中为我的元素使用了这个自定义类,但是,当段控件被选中时,似乎没有调用此代码(当视图加载时,它是调用=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寄存器点击选定段时被问过,但是那个问题是针对ObjC的,这个问题是针对c#/Monotouch的。
您提供的问题链接的最后一个答案包含了最好的(工作良好)答案(我支持它,你也应该;-)。
注意:从评论来看,前面的答案(可能)适用于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);
}
}
提供的链接对于iOS7有很好的答案,但是使用Objective C/Swift,特别是当当前选择的段再次被按下时取消选择。
这是c#版本需要使用TouchesEnded事件而不是TouchesBegan。使用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不要忘记修改这个