MonoTouch: UISegmentedControl Выберите сегмент, который уже выбран - PullRequest
3 голосов
/ 21 ноября 2011

Я пытаюсь использовать UISegmentedControl для управления порядком сортировки моей таблицы, в частности, я хочу зарегистрировать нажатие на сегмент, который уже выбран (для инвертирования сортировки).Таким образом, я пытаюсь вызвать событие UIControlEvent.ValueChanged при каждом касании любого сегмента.

Я переопределил SelectedSegment из UISegmentedControl и использую этот пользовательский класс для своего элемента в 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.

Ответы [ 2 ]

2 голосов
/ 21 ноября 2011

Последний ответ на вопрос ссылка , которую вы предоставили, содержит лучший (хорошо работающий) ответ (я проголосовал за него, вы тоже должны ;-).

примечание: из комментариев видно, что предыдущие ответы (возможно) работали на 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);
        }
    }
0 голосов
/ 13 февраля 2017

Предоставленные ссылки имеют хорошие ответы для 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, но затем изменил имя на TouchesEnded, когда понял, что это то, что нужно для iOS7 и выше. Все еще не работал, пока я не понял, что мне нужно было также изменить строку:

base.TouchesEnded(touches, evt);

Так что не забудьте изменить это, если вы конвертируете из TouchesBegan в TouchesEnded.

...