90

在我的用户单击一个按钮后,我希望该按钮在我执行网络操作期间保持按下状态。当网络操作完成后,我希望按钮恢复到默认状态。

我试过打电话 -[UIButton setSelected:YES]在按钮按下之后(相应的调用 -[UIButton setSelected:NO]在我的网络操作完成后),但它似乎没有做任何事情。如果我打电话也是一样setHighlighted:

我想我可以尝试在网络操作期间换出背景图像以表示选定状态,但这似乎是一种黑客行为。有更好的建议吗?

这是我的代码的样子:

- (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;
}
4

9 回答 9

74

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)];

编辑:

总结我在评论中的评论并解决您发布的代码......您需要为您所处的完整UIControl状态设置背景图片。根据您的代码片段,此控制状态将被禁用+选中+在网络运行期间突出显示。这意味着您需要这样做:

[button setBackgroundImage:someImage forState:(UIControlStateDisabled|UIControlStateHighlighted|UIControlStateSelected)];

如果您删除highlighted = YES,那么您将需要这个:

[button setBackgroundImage:someImage forState:(UIControlStateDisabled|UIControlStateSelected)];

得到图片?

于 2009-11-23T18:30:01.443 回答
30

我有一个更简单的方法。只需使用 0 延迟的“performSelector”来执行[button setHighlighted:YES]。这将在当前运行循环结束后执行重新突出显示。

- (IBAction)buttonSelected:(UIButton*)sender {
    NSLog(@"selected %@",sender.titleLabel.text);
    [self performSelector:@selector(doHighlight:) withObject:sender afterDelay:0];
}

- (void)doHighlight:(UIButton*)b {
    [b setHighlighted:YES];
}
于 2011-09-09T06:24:57.290 回答
28

“打开电源后一切都会好起来”

    button.selected = !button.selected;

完美运行......在我将插座连接到界面生成器中的按钮后。

您不需要 setBackgroundImage:forState:,构建器允许您指定背景(必要时调整大小)或/和前景(不调整大小)图像。

于 2011-10-20T17:20:14.437 回答
27

尝试使用 NSOperationQueue 来实现这一点。试一下代码如下:

[[NSOperationQueue mainQueue] addOperationWithBlock:^{
    theButton.highlighted = YES;
}];

希望这可以帮助。

于 2012-03-31T19:24:27.813 回答
8

使用一个块,这样您就不必构建一个完整的单独方法:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0), dispatch_get_main_queue(), ^{
    theButton.highlighted = YES;
});

更新

为了清楚起见,您仍然需要为组合状态设置背景(或正常图像)以及像 sbrocket 在接受的答案中所说的常规状态。在某些时候,您的按钮将被选中并突出显示,除非您执行以下操作,否则您将没有图像:

[button setBackgroundImage:someImage forState (UIControlStateHighlighted|UIControlStateSelected)];

否则,您的按钮可能会退回到 UIControlStateNormal 图像以获得简短的选择+突出显示状态,并且您会看到一个闪烁。

于 2012-04-05T23:49:20.993 回答
4

迅速我正在这样做,如下所示。

我创建了一个子类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
        }
    }

}

非常适合我。

于 2016-07-16T12:19:35.530 回答
1

我有一个类似的问题,我想要一个按钮在点击后保持突出显示。问题是如果您尝试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按钮。

于 2011-08-11T22:52:59.370 回答
0

我有另一种方法......如果您不想使用图像,并且想要按下按钮的效果,您可以将 Button 子类化,这是我的代码:

在 .h 文件中:

@interface reservasButton : UIButton {

BOOL isPressed;
}
 @end

在 .m 文件中:

#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;

     }


 } `
于 2012-03-30T14:39:23.773 回答
0

这是使用上述方法的 C#/MonoTouch (Xamarin.iOS) 实现。它假定您已经设置了 Highlighted 图像状态,并将 selected 和 selected|highlighted 状态配置为使用相同的图像。

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;
        });
    });
};
于 2013-11-24T02:36:17.503 回答