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;

完全に動作します... Interface Builder のボタンにコンセントを接続した後。

BackgroundImage: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

上記のアプローチを使用した 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;
        });
    });
};
于 2013-11-24T02:36:17.503 に答える
0

別の方法があります...画像を使用したくない場合、および押されたボタンの効果が必要な場合は、ボタンをサブクラス化できます。ここに私のコードがあります:

.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 に答える