我正在尝试使用UISegmentedControl
来控制我的表的排序顺序,特别是我想在已经选择的段上注册一个点击(以反转我的排序)。因此,我会尝试在点击任何细分时引发UIControlEvent.ValueChanged
事件。
我已从SelectedSegment
覆盖了UISegmentedControl
并且正在使用此自定义类作为xcode中的元素,但是,当点击Segment控件时,似乎没有调用此代码(It <虽然= S)加载视图时调用strong> 。
[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。
答案 0 :(得分:2)
你提供的问题link的最后一个答案包含最好的(工作良好)答案(我赞成它,你也应该;-)。
注意:从评论看来,以前的答案似乎(可能)在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);
}
}
答案 1 :(得分:0)
提供的链接对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无效,但当我意识到iOS7及以上版本需要的时候,我将名称更改为TouchesEnded。在我意识到我还必须改变这条线之前,仍然没有工作:
base.TouchesEnded(touches, evt);
如果您从TouchesBegan转换为TouchesEnded,请不要忘记更改。