Пользовательский рисунок UIButton - остается нажатым после прикосновений - PullRequest
1 голос
/ 20 сентября 2011

Я создал собственное нулевое изображение, базовую графику, нарисованную UIButton, на основе Обучающего руководства Рэя Вендерлиха (единственные модификации - метод CoolButton drawRect:, измененный код рисования), и он прекрасно работает в большинстве случаев.времени.Однако иногда, когда я нажимаю на него в течение короткого периода времени, он остается в подавленном состоянии и не возвращается в нормальное состояние.

Отсюда единственный способ вернуть его в нормальное состояние - это долгое нажатие.Простое нажатие означает, что оно остается подавленным.

Еще одна вещь, которую стоит отметить, это то, что я подключил Touch Up Inside к цепочке из нескольких длинных методов - я не думаю, что это займет более 0,1 секунды.,Я даже использовал dispatch_async в @selector, который подключен к Touch Up Inside, так что, думаю, не должно быть задержки при обновлении интерфейса.


Я поместил NSLog в drawRect:, который обычно срабатывает 3 раза за нажатие кнопки, и это зависит от того, какая UIControlState кнопка используется для каждого нажатия:

  • Для некоторых коротких нажатий он выделен, выделен, обычный
  • для более длинных нажатий, выделен, обычный, обычный

Однако для очень коротких нажатий онстреляет только дважды, Выделено -> Выделено.

Когда долгое нажатие возвращает его к нормальному состоянию, оно идет H, N, N.


Меня это озадачиваетНекоторое время, и я не смог понять, почему короткие нажатия только дважды запускают drawRect:, или почему touchesEnded:, кажется, не вызывает drawRect:.Возможно touchesEnded: не стреляет?

Я действительно надеюсь, что кто-то может помочь.

Ответы [ 5 ]

1 голос
/ 20 сентября 2011

Если вы действительно хотите генерировать изображения кнопок во время выполнения, генерируйте их при загрузке кнопки.Затем добавьте их для различных состояний, используя

[button setImage:btnImage forState:UIControlStateNormal];

. Вы всегда можете превратить вид в изображение, используя следующее: http://pastie.org/244916

Действительно, я бы порекомендовал просто сделать изображения заранее.Если вы не хотите получать фотошоп, есть много альтернатив.Предстоящее обновление pixelmator выглядит довольно изощренно, и это смехотворно дешево!

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

Другая дешевая, но эффективная альтернатива, которую я нашел, - это создать drawRect: он не делает никакого выделения, а просто изменяет свойство alpha подкласса кнопки, когда пользователь взаимодействует с кнопкой.

Например:

- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
    self.alpha = 0.3f;
    return [super beginTrackingWithTouch:touch withEvent:event];
}

- (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
    self.alpha = 1.0f;
    [super endTrackingWithTouch:touch withEvent:event];
}

- (void)cancelTrackingWithEvent:(UIEvent *)event
{
    self.alpha = 0.3f;
    [super cancelTrackingWithEvent:event];
}

- (void)drawRect:(CGRect)rect
{
    // Your drawing code here sans highlighting
}
0 голосов
/ 04 апреля 2012

Я тоже столкнулся с подобной проблемой с UIButton, который, кажется, придерживался одного состояния, когда я настраивал метод drawRect.Я догадываюсь, что состояние кнопки меняется несколько раз, прежде чем вызывается drawRect.Поэтому я просто добавил пользовательское свойство, которое будет устанавливаться только методами, вызываемыми во время событий touchDown и touchUpInside.Я должен был отправить потоки, чтобы сделать это из-за других операций, которые задерживали основной поток, вызывая задержку в методе redrawHighlighted.

Это может быть немного грязно, но вот что сработало для меня:

// CustomButton.h
@interface CustomButton : UIButton
@property (atomic) BOOL drawHighlighted;    

// CustomButton.m
@implementation CustomButton
@synthesize drawHighlighted = _drawHighlighted;

- (id)initWithFrame:(CGRect)frame
{
    if ((self = [super initWithFrame:frame]))
    {
        _drawHighlighted = NO;

        [self addTarget:self action:@selector(redrawHighlighted) forControlEvents:UIControlEventTouchDown];
        [self addTarget:self action:@selector(redrawNormal) forControlEvents:UIControlEventTouchUpInside];
        [self addTarget:self action:@selector(redrawNormal) forControlEvents:UIControlEventTouchDragExit];  
    }
    return self;
}

- (void)drawRect:(CGRect)frame
{
    // draw button here
}

- (void)redrawNormal
{
    [NSThread detachNewThreadSelector:@selector(redrawRectForNormal) toTarget:self withObject:nil];
}

- (void)redrawHighlighted
{
    [NSThread detachNewThreadSelector:@selector(redrawRectForHighlighted) toTarget:self withObject:nil];
}

- (void)redrawRectForNormal
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    _drawHighlighted = NO;  
    [self setNeedsDisplay];

    [pool release];
}

- (void)redrawRectForHighlighted
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    _drawHighlighted = YES; 
    [self setNeedsDisplay];

    [pool release];
}
0 голосов
/ 20 сентября 2011

Как уже говорилось, вы можете просто сгенерировать изображение и использовать его в качестве фона (если изображение статичное). Фотошоп не нужен, вы можете просто сгенерировать свое изображение один раз, а затем сделать снимок, затем вырезать изображение (с помощью Anteprima) и сохранить его в виде файла png:)

Однако, поскольку вы сказали, что кнопка подключена к некоторым длинным методам, возможно, причина в том, что кнопка остается нажатой: если вы не вызываете эти методы в фоновом режиме, то кнопка будет оставаться нажатой, поскольку все задачи завершены. Попробуйте (для теста) соединить кнопку одним простым способом (скажем, NSLog что-нибудь) и проверьте, остается ли она нажатой. Если нет, я предлагаю отключить ваши методы в фоновом режиме.

0 голосов
/ 20 сентября 2011

Ну, хорошо, это было легко. Задержка 0,15 секунд работает, 0,1 - нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...