【问题标题】:How to change background image of a button and get it updated instantly?如何更改按钮的背景图像并立即更新?
【发布时间】:2010-06-24 17:34:55
【问题描述】:

我正在开发一个记忆游戏。当我单击一个按钮时,我希望背景切换。当我第二次点击卡片时,我希望背景切换一秒钟,然后回到原来的状态(如果它不是正确的卡片)。但是在我从方法(buttonPressed)返回之前,按钮的背景不会改变。为什么不立即更改?请帮我! :)

这是我正在使用的课程:

#import "Button.h"
#import <UIKit/UIKit.h>
#import <AVFoundation/AVAudioPlayer.h>

@class ZogajAppDelegate;

@interface PairPlayPlayViewController : UIViewController <AVAudioPlayerDelegate> {
    ZogajAppDelegate *appDelegate;
    AVAudioPlayer *av;
    Boolean isPairActive;
    Button *firstButton;
    Button *secondButton;

}
@property (nonatomic, retain) AVAudioPlayer *av;
@property (nonatomic, retain) Button *firstButton;
@property (nonatomic, retain) Button *secondButton;
- (void)buttonPressed:(id)sender;
- (void)secondCard;

@end

和 .m 文件:

#import "PairPlayPlayViewController.h"
#import "ZogajAppDelegate.h"
#import "Button.h"
#import "AVFoundation/AVAudioPlayer.h"



@implementation PairPlayPlayViewController
@synthesize av, firstButton, secondButton;

/*
 // The designated initializer.  Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
        // Custom initialization
    }
    return self;
}
*/


// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];

    NSString *newAudioFile = [[NSBundle mainBundle] pathForResource:@"double_card" ofType:@"mp3"];
    NSString *newAudioFile2 = [[NSBundle mainBundle] pathForResource:@"right_sound" ofType:@"mp3"];

    av = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:newAudioFile] error:NULL];
    [av prepareToPlay];
    [av initWithContentsOfURL:[NSURL fileURLWithPath:newAudioFile2] error:NULL];
    [av prepareToPlay];
    //av = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:newAudioFile] error:NULL];
    //[av prepareToPlay];
    isPairActive = FALSE;


    appDelegate = (ZogajAppDelegate *)[[UIApplication sharedApplication] delegate];
    int position;

    for(int i = 0; i < ((appDelegate.numberOfPairs*2)/5); i++){

        for (int j = 0; j<5 ;j++){


            Button *button = [[Button alloc] init];

            //Sätter bild nummer..
            position = (arc4random() % [appDelegate.cardsInPlay count]);
            button.picNumber = [[appDelegate.cardsInPlay objectAtIndex:position]intValue];
                        NSLog(@"%d", button.picNumber);
            [appDelegate.cardsInPlay removeObjectAtIndex:position];

            button.frame = CGRectMake( 3 + (65 * j), 5 + (65 * i), 55, 55);
            button.imageView.contentMode = UIViewContentModeScaleAspectFit;
            button.imageView.clipsToBounds = YES;
            [button setBackgroundImage:[UIImage imageNamed:@"back.png"] forState:UIControlStateNormal];
            [button addTarget:self action:@selector(buttonPressed:)
             forControlEvents:UIControlEventTouchUpInside];
            [self.view addSubview:button];
        }
    }
    for (int j = 0; j<((appDelegate.numberOfPairs*2) % 5) ;j++){


        Button *button = [[Button alloc] init];

        //Sätter bild nummer..
        position = (arc4random() % [appDelegate.cardsInPlay count]);
        button.picNumber = [[appDelegate.cardsInPlay objectAtIndex:position]intValue];
        NSLog(@"%d", button.picNumber);
        [appDelegate.cardsInPlay removeObjectAtIndex:position];

        button.frame = CGRectMake( 3 + (65 * j), 5 + (65 * ((appDelegate.numberOfPairs*2)/5) + 1), 55, 55);
        //button.imageView.contentMode = UIViewContentModeScaleAspectFit;
        //button.imageView.clipsToBounds = YES;
        [button setBackgroundImage:[UIImage imageNamed:@"back.png"] forState:UIControlStateNormal];
        [button addTarget:self action:@selector(buttonPressed:)
         forControlEvents:UIControlEventAllTouchEvents];

        [self.view addSubview:button];
    }
}


/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/

-(void)buttonPressed:(id)sender {
    Button *button = [[Button alloc] init];
    button = sender;
    NSLog(@"%d och spela upp ljud", button.picNumber);
    NSString *newAudioFile = [[NSBundle mainBundle] pathForResource:@"double_card" ofType:@"mp3"];
    [av initWithContentsOfURL:[NSURL fileURLWithPath:newAudioFile] error:NULL];
    [av play];
    [button setBackgroundImage:[UIImage imageNamed:[NSString stringWithFormat:@"%d.png",button.picNumber]] forState:UIControlStateNormal];
    [self.view addSubview:button];
    [NSThread sleepForTimeInterval:1.0];

    if(isPairActive == FALSE){
        isPairActive = TRUE;
        firstButton = button;
    }
    else {
        secondButton = button;
        [self secondCard];
    }

    return;
}

- (void)secondCard {
    [NSThread sleepForTimeInterval:1.0];
    NSString *newAudioFile = [[NSBundle mainBundle] pathForResource:@"double_card" ofType:@"mp3"];
    isPairActive = FALSE;
    if([appDelegate.dictionary objectForKey:[NSString stringWithFormat:@"%d",secondButton.picNumber]] == [NSString stringWithFormat:@"%d",firstButton.picNumber]){
        NSString *newAudioFile2 = [[NSBundle mainBundle] pathForResource:@"right_sound" ofType:@"mp3"];
        [av initWithContentsOfURL:[NSURL fileURLWithPath:newAudioFile2] error:NULL];
        [av play];
    }
    else {
        [firstButton setBackgroundImage:[UIImage imageNamed:@"back.png"] forState:UIControlStateNormal];
        [secondButton setBackgroundImage:[UIImage imageNamed:@"back.png"] forState:UIControlStateNormal];
        [av initWithContentsOfURL:[NSURL fileURLWithPath:newAudioFile] error:NULL];
        [av play];
    }
    return;
}

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}


- (void)dealloc {
    [super dealloc];
    [av release];
    [firstButton release];
    [secondButton release];
}


@end

【问题讨论】:

  • 我认为你应该使用 NSTimer 而不是弄乱 NSThread。

标签: iphone objective-c image background uibutton


【解决方案1】:

buttonPressed: 中更改背景,设置一个 NSTimer 回调你,然后返回。在 NSTimer 回调中,将背景设置回你想要的。

绘图不会在您请求的那一刻发生。那会给你带来可怕的表现。所有绘图都合并到运行循环的绘图部分。在您从此 IBAction 方法返回之前,您不会到达该部分。

【讨论】:

    【解决方案2】:

    如你所知,从方法返回后图像会发生变化。就是这样。

    您必须从方法返回,因此您必须更改图像,执行选择器来执行您想要执行的其余代码并从方法返回。

    UIKit 只能在主线程上运行,所以你必须从方法返回,这会阻塞它,然后它会执行 GUI 操作。

    编辑: 与其让 NSThread 休眠,不如延迟执行选择器。

    【讨论】:

      猜你喜欢
      • 2015-02-21
      • 2013-09-07
      • 2016-07-12
      • 2018-03-18
      • 2012-07-13
      • 2011-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多