UIControl не получает штрихи - PullRequest
16 голосов
/ 19 февраля 2012

У меня есть UIControl, который реализует метод начала касаний следующим образом:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesBegan:touches withEvent:event];
    //More code goes here

Этот подкласс UIControl создается в контроллере представления, а затем добавляется как подпредставление в этот контроллер представления.У меня есть точка останова при прикосновении начал метод UIControl, и метод никогда не вызывается.Я немного читал, и кажется, что у View Controller есть логика, которая решает, передавать ли сенсорные события своим подпредставлениям.Странно то, что у меня есть другой подкласс UIControl в том же контроллере представления, и сенсорные события передаются ему, когда пользователь касается его!Вот полный код:

.h

#import <UIKit/UIKit.h>

@interface CustomSegment : UIView
@property (nonatomic, strong) UIImageView *bgImageView;
@property (nonatomic, assign) NSInteger segments;
@property (nonatomic, strong) NSArray *touchDownImages;
@property (nonatomic, readonly, assign) NSInteger selectedIndex;
@property (nonatomic, weak) id delegate;


- (id)initWithPoint:(CGPoint)point numberOfSegments:(NSInteger)_segments andTouchDownImages:(NSArray *)_touchDownImages;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
@end

.m

#import "CustomSegment.h"

@implementation CustomSegment
@synthesize bgImageView, segments, touchDownImages, selectedIndex, delegate;

- (id)initWithPoint:(CGPoint)point
   numberOfSegments:(NSInteger)_segments
           andTouchDownImages:(NSArray *)_touchDownImages  
{  
    self = [super initWithFrame:CGRectMake(point.x, point.y, [[_touchDownImages     objectAtIndex:0] size].width, [[touchDownImages objectAtIndex:0] size].height)];
if (self)
{
    touchDownImages = _touchDownImages;
    segments = _segments;
    bgImageView = [[UIImageView alloc] initWithImage:[touchDownImages objectAtIndex:0]];
    [self addSubview:bgImageView];
}
return self;
}

- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
    return YES;  
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    //[super touchesBegan:touches withEvent:event];
    UITouch *touch = [touches anyObject];
    float widthOfSegment = [self frame].size.width / segments;
    float bottomPoint = 0;
    float topPoint = widthOfSegment;
    for (int i = 0; i < segments; i++)
    {
        if ([touch locationInView:self].x > bottomPoint && [touch locationInView:self].x < topPoint)
        {
            [bgImageView setImage:[touchDownImages objectAtIndex:i]];
            selectedIndex = i;
            return;
        }
        else
        {
            bottomPoint = topPoint;
            topPoint += topPoint;
        }
    }
}
@end

Ответы [ 7 ]

67 голосов
/ 16 мая 2012

tl; dr Установите все подпредставления UIControl на setUserInteractionEnabled:NO. UIImageView по умолчанию имеет значение true.

Оригинальный пост

Одна вещь, которую я недавно обнаружил, это то, что помогает, если у самого верхнего подпредставления UIControl есть setUserInteractionEnabled:NO. Я пришел к этому, потому что у меня был подкласс UIControl с UIImageView, так как это только подпредставление, и оно работало нормально. UIImageView имеет userInteractionEnabled по умолчанию NO.

У меня также был еще один UIControl с UIView, поскольку он является самым верхним подпредставлением (технически тот же UIControl в другом состоянии). Я полагаю, что UIView по умолчанию userInteractionEnabled == YES, что исключает обработку событий UIControl. Настройки UIView userInteractionEnabled для NO решили мою проблему.

Я не знаю, если это та же проблема, но, может быть, это поможет?

- Редактировать: Когда я говорю самый верхний вид ... вероятно, установите все подпредставления UIControl на setUserInteractionEnabled:NO

2 голосов
/ 19 февраля 2012

Проверьте frame всех родительских представлений. Правило состоит в том, что если суб-представление (или его часть) представления выходит за границы представления, оно не получает сенсорные события.

1 голос
/ 19 февраля 2012

Возможно, что другой вид покрывает ваш UIControl и не позволяет ему получать сенсорные события. Другая возможность состоит в том, что userInteractionEnabled где-то по ошибке установлен на NO.

РЕДАКТИРОВАТЬ: Я вижу, что вы добавили больше кода выше. Вы убедились, что рамка вашего вида имеет ширину и высоту больше нуля? Мне кажется, что вы вызываете «размер» непосредственно для объекта из NSArray (который является «id»). Я не знаю, как вы делаете это без приведения (возможно, скобки не были указаны выше?), Но если вы каким-то образом выполняете это, я не удивлюсь, если это недопустимое значение.

0 голосов
/ 15 ноября 2012

Экземпляры UIView не могут отвечать на события, поэтому нет способа, вплоть до вашей текущей конфигурации, вызвать ваш метод действия?

Попробуйте изменить класс представления, чтобы он был экземпляром UIControlкласс!

0 голосов
/ 08 июля 2012

Достаточно справедливо.Недавно повторно исследовал это (UIControl очень плохо документирован) и понял, что отслеживание касаний является заменой для касаний Began / Ended, а не дополнительным, так что извините.Я бы изменил голосование, но оно не позволило бы мне: (

0 голосов
/ 20 февраля 2012

Во-первых, почему вы звоните [super touchesBegan:touches withEvent:event];? Этот вызов перенаправляет событие следующему респонденту. Обычно вы делаете это только тогда, когда вы не хотите обрабатывать событие. Вы уверены, что знаете, что там делаете?

Идея, почему она не работает - может быть, у вас есть распознаватель жестов, который первым обрабатывает событие?

В любом случае, вам действительно нужно переопределить touchesBegan? UIControl предназначен для самостоятельного отслеживания сенсорных событий и вызова ваших обработчиков в ответ. И UIControl документы говорят, КАК его подкласс.

Примечания по подклассам

Возможно, вы захотите расширить подкласс UIControl по одной из двух причин:

  • Для наблюдения или изменения направления сообщений действий к целям для определенных событий

    Для этого переопределите sendAction: to: forEvent:, оцените переданный селектор, целевой объект или битовую маску UIControlEvents и выполните необходимые действия.

  • Для обеспечения пользовательского поведения отслеживания (например, для изменения внешнего вида подсветки)

    Для этого переопределите один или все из следующих методов: beginTrackingWithTouch: withEvent :, continueTrackingWithTouch: withEvent :, endTrackingWithTouch: withEvent:.

0 голосов
/ 19 февраля 2012

Возможности:

  • Возможно, вы забыли установить делегат для UIControl.
  • Другой UIControl, который получает касание, скрывает / закрывает UIControl.
...