Подтвердить что ты не робот

UIControl не получает прикосновения

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

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

Этот подкласс UIControl создается в контроллере представления, затем он добавляется в качестве подсмотра к этому контроллеру представления. У меня есть точка останова при касании начала метода UIControl, и метод так и не вызван. Я делал некоторое чтение, и кажется, что контроллер View имеет некоторую логику, которая решает, передавать ли события касания к своим подзонам. Странно то, что у меня есть другой подкласс 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
4b9b3361

Ответ 1

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

Оригинальное сообщение

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

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

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

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

Ответ 2

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

Ответ 3

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

EDIT: Я вижу, что вы добавили больше кода выше. Вы проверили, что ваш ракурс имеет ширину и высоту больше нуля? Мне кажется, что вы вызываете "размер" непосредственно на объект из NSArray (который является "id" ). Я не знаю, как вы делаете это без приведения (возможно, скобки не вышли выше?), Но если вы каким-то образом оттянете ее, я не удивлюсь, если это неверное значение.

Ответ 4

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

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

Ответ 5

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

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

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

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

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

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

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

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

    Чтобы сделать это, переопределите один или все из следующих способов: beginTrackingWithTouch: withEvent:, continueTrackingWithTouch: withEvent:, endTrackingWithTouch: withEvent:.

Ответ 6

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

Ответ 7

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

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