Сохранение UIButton, выбранного после прикосновения
после того, как мой пользователь нажимает кнопку, Я бы хотел, чтобы эта кнопка оставалась нажатой во время выполнения сетевой операции. Когда сетевая операция будет завершена, я хочу, чтобы кнопка вернулась в состояние по умолчанию.
Я звонила -[UIButton setSelected:YES]
сразу после нажатия кнопки (с соответствующим вызовом -[UIButton setSelected:NO]
после завершения моей сетевой операции), но он, похоже, ничего не делает. То же самое, если я позвоню setHighlighted:
.
Я полагаю, что я мог бы попробовать поменять фон изображение для обозначения выбранного состояния на время работы сети op, но это похоже на взлом. Есть предложения получше?
вот как выглядит мой код:
- (IBAction)checkInButtonPushed
{
self.checkInButton.enabled = NO;
self.checkInButton.selected = YES;
self.checkInButton.highlighted = YES;
[self.checkInActivityIndicatorView startAnimating];
[CheckInOperation startWithPlace:self.place delegate:self];
}
- (void)checkInCompletedWithNewFeedItem:(FeedItem*)newFeedItem wasNewPlace:(BOOL)newPlace possibleError:(NSError*)error;
{
[self.checkInActivityIndicatorView stopAnimating];
self.checkInButton.enabled = YES;
self.checkInButton.selected = NO;
self.checkInButton.highlighted = NO;
}
9 ответов:
как вы устанавливаете изображения для различных
UIControlStates
на кнопку? Вы устанавливаете фоновое изображение дляUIControlStateHighlighted
а такжеUIControlStateSelected
?UIImage *someImage = [UIImage imageNamed:@"SomeResource.png"]; [button setBackgroundImage:someImage forState:UIControlStateHighlighted]; [button setBackgroundImage:someImage forState:UIControlStateSelected];
если вы устанавливаете выбранное состояние на событии касания кнопки, а не касаетесь внутри, ваша кнопка фактически будет находиться в выделенном+выбранном состоянии, поэтому вы тоже захотите установить это.
[button setBackgroundImage:someImage forState:(UIControlStateHighlighted|UIControlStateSelected)];
Edit:
чтобы подвести итог моим замечаниям в комментариях и обратиться к коду вы размещенный...вам нужно установить фоновые изображения для полного
UIControl
заявить, что вы находитесь внутри. Согласно вашему фрагменту кода, это состояние управления будет отключено + выделено + выделено на время работы сети. Это означает, что вам нужно будет сделать это:[button setBackgroundImage:someImage forState:(UIControlStateDisabled|UIControlStateHighlighted|UIControlStateSelected)];
если убрать
highlighted = YES
, тогда вам понадобится это:[button setBackgroundImage:someImage forState:(UIControlStateDisabled|UIControlStateSelected)];
получите картину?
у меня есть более простой способ. Просто используйте "performSelector" с задержкой 0 для выполнения
[button setHighlighted:YES]
. Это позволит выполнить повторное выделение после завершения текущего runloop.- (IBAction)buttonSelected:(UIButton*)sender { NSLog(@"selected %@",sender.titleLabel.text); [self performSelector:@selector(doHighlight:) withObject:sender afterDelay:0]; } - (void)doHighlight:(UIButton*)b { [b setHighlighted:YES]; }
"все становится лучше, когда вы включаете питание"
button.selected = !button.selected;
работает отлично... после того, как я подключил розетку к кнопке в Построителе интерфейса.
вам не нужно setBackgroundImage:forState:, построитель позволяет указать фон (при необходимости изменяется размер) или/и передний план (без изменения размера) изображения.
попробуйте использовать NSOperationQueue для достижения этой цели. Попробуйте код следующим образом:
[[NSOperationQueue mainQueue] addOperationWithBlock:^{ theButton.highlighted = YES; }];
надеюсь, что это помогает.
использовать блок, так что вам не придется строить целый отдельный метод:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0), dispatch_get_main_queue(), ^{ theButton.highlighted = YES; });
обновление
чтобы быть ясным, вам все равно нужно установить фон (или обычное изображение) для состояний комбинации, а также обычные, такие как sbrocket, говорит в принятом ответе. В какой-то момент ваша кнопка будет выбрана и выделена, и у вас не будет изображения для этого, если вы не сделаете что-то вроде этого:
[button setBackgroundImage:someImage forState (UIControlStateHighlighted|UIControlStateSelected)];
в противном случае ваша кнопка может вернуться к UIControlStateNormal изображение для краткого выбранного + выделенного состояния, и вы увидите вспышку.
в swift я делаю это следующим образом.
Я создаю подкласс
UIButton
и реализовано пользовательское свойствоstate
class ActiveButton: UIButton { private var _active = false var active:Bool { set{ _active = newValue updateState() } get{ return _active } } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) self.addTarget(self, action: #selector(ActiveButton.touchUpInside(_:)), forControlEvents: .TouchUpInside) } func touchUpInside(sender:UIButton) { active = !active } private func updateState() { NSOperationQueue.mainQueue().addOperationWithBlock { self.highlighted = self.active } } }
отлично работает для меня.
у меня была аналогичная проблема, когда я хотел, чтобы кнопка оставалась выделенной после щелчка. Проблема в том, если вы пытаетесь использовать
setHighlighted:YES
внутри вас нажмите действие он будет сброшен сразу после нажатия кнопки действие,- (IBAction)checkInButtonPushed
я решил это с помощью NSTimer, как это
NSTimer *timer; timer = [NSTimer scheduledTimerWithTimeInterval: 0.01 target: self selector: @selector(selectCurrentIndex) userInfo: nil repeats: NO];
а потом позвоните
setHighlighted:YES
от меняselectCurrentIndex
метод. Я использую обычныйUIButtonTypeRoundedRect
кнопки.
у меня есть другой способ ...если вы не хотите использовать изображения, и вы хотите эффект нажатой кнопки, вы можете подкласс кнопки и вот мой код:
in the .H-файл:
@interface reservasButton : UIButton { BOOL isPressed; } @end
In the .файл м:
#import <QuartzCore/QuartzCore.h> @implementation reservasButton -(void)setupView { //This is for Shadow self.layer.shadowColor = [UIColor blackColor].CGColor; self.layer.shadowOpacity = 0.5; self.layer.shadowRadius = 1; self.layer.shadowOffset = CGSizeMake(2.0f, 2.0f); //comment // self.layer.borderWidth = 1; self.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; self.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter; // [self setBackgroundColor:[UIColor whiteColor]]; // self.opaque = YES; } -(id)initWithFrame:(CGRect)frame{ if((self = [super initWithFrame:frame])){ [self setupView]; } return self; } -(id)initWithCoder:(NSCoder *)aDecoder{ if((self = [super initWithCoder:aDecoder])){ [self setupView]; } return self; } //Here is the important code -(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ if (isPressed == FALSE) { self.contentEdgeInsets = UIEdgeInsetsMake(1.0,1.0,-1.0,-1.0); self.layer.shadowOffset = CGSizeMake(1.0f, 1.0f); self.layer.shadowOpacity = 0.8; [super touchesBegan:touches withEvent:event]; isPressed = TRUE; } else { self.contentEdgeInsets = UIEdgeInsetsMake(0.0,0.0,0.0,0.0); self.layer.shadowOffset = CGSizeMake(2.0f, 2.0f); self.layer.shadowOpacity = 0.5; [super touchesEnded:touches withEvent:event]; isPressed = FALSE; } } `
вот C# / MonoTouch (Xamarin.iOS) реализация с использованием подходов, представленных выше. Он предполагает, что вы уже установили состояние выделенного изображения и настраиваете выбранные и выбранные|выделенные состояния для использования одного и того же изображения.
var selected = button.BackgroundImageForState(UIControlState.Highlighted); button.SetBackgroundImage(selected, UIControlState.Selected); button.SetBackgroundImage(selected, UIControlState.Selected | UIControlState.Highlighted); button.TouchUpInside += delegate { NSTimer.CreateScheduledTimer(TimeSpan.FromMilliseconds(0), delegate { button.Highlighted = true; NSTimer.CreateScheduledTimer(TimeSpan.FromMilliseconds(200), delegate { button.Highlighted = false; }); }); };