gpt4 book ai didi

iphone - 在方法中运行时,从 nib 加载的 View 不会更新 UILabel 的内容

转载 作者:搜寻专家 更新时间:2023-10-30 19:47:20 26 4
gpt4 key购买 nike

我在更新我创建的要在某些后台进程完成时显示的“myInfoBox”对象的内容时遇到问题。

在委托(delegate)方法中我创建了一个新的 viewController:

-(void)loadMainView
{
myFirstViewController = [[MyFirstViewController alloc] initWithNibName:@"MyFirstView" bundle:nil];
navigationController = [[UINavigationController alloc] initWithRootViewController:myFirstViewController];
// myFirstViewController was retained again by the controller, release one
[myFirstViewController release];
navigationController.navigationBar.hidden = YES;
[window addSubview:navigationController.view];
[window makeKeyAndVisible];
// the next method is run after the "viewDidLoad" is finished loading
[myFirstViewController loadAlertViewForNewUser];
}

下面是我对“myFirstViewController”的实现,它创建了一个“infoBox”类的实例(稍后我会展示它的代码):

- (void)viewDidLoad {

self.navigationController.navigationBar.frame = CGRectMake(0, 0, 0, 0);
self.navigationController.navigationBar.bounds = CGRectMake(0, 0, 0, 0);

self.myInfoBox = [[InfoBoxController alloc] initWithNibName:@"InfoBox" bundle:[NSBundle mainBundle]];
CGRect infoBoxFrame;
infoBoxFrame = CGRectMake(60, 120, 200, 200);
myInfoBox.view.frame = infoBoxFrame;

myInfoBox.i_statusLabel.text = @"Downloading Account Updates";
myInfoBox.i_titleLabel.text = @"Updating";
// disabled for testing
//myInfoBox.view.hidden = YES;
[self.view addSubview:myInfoBox.view];
[super viewDidLoad];
}

// this method is called after the view has been loaded by the delegate
- (void)loadAlertViewForNewUser
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Welcome!" message:@"Connect to download stuff from your account?"
delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil];
alert.tag = 0;
[alert show];
}

// implementation of the alertview delegate
- (void)alertView:(UIAlertView *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (actionSheet.tag == 0)
{
if (buttonIndex == 0)
{ NSLog(@"button 0 was pressed"); }
if (buttonIndex == 1)
{
// this is the button that is pressed
[actionSheet removeFromSuperview];
[actionSheet release];

// tried using this also
//[self performSelectorOnMainThread:@selector(userInitialSetupMainThread) withObject:nil waitUntilDone:NO];
// do stuff and update the infobox about it
[self loadInfoBoxInitialUserSetup];
// tried using this as well
//[self performSelectorInBackground:@selector(loadInfoBoxInitialUserSetup) withObject:nil];
}
return;
}
}

- (void)loadInfoBoxInitialUserSetup
{
[self performSelectorOnMainThread:@selector(userInitialSetupMainThread) withObject:nil waitUntilDone:NO];
}

- (void)userInitialSetupMainThread
{
// fetch JSON data
NSDictionary *responseJSON = [NSDictionary dictionaryWithDictionary:[self getUserstuff]];

self.myInfoBox.i_statusLabel.text = @"Processing Recieved information";
// breakpoint - nothing changes in the view on the simulator
[myInfoBox.view setNeedsLayout];
// breakpoint - nothing changes in the view on the simulator
[myInfoBox.view setNeedsDisplay];
// breakpoint - nothing changes in the view on the simulator
[myInfoBox.parentViewController.view setNeedsLayout];
// breakpoint - nothing changes in the view on the simulator
[myInfoBox.parentViewController.view setNeedsDisplay];
// breakpoint - nothing changes in the view on the simulator
[myInfoBox performSelectorOnMainThread:@selector(updateValuesForTitle:) withObject:@"test" waitUntilDone:YES];
// breakpoint - nothing changes in the view on the simulator
[self.view setNeedsLayout];
// breakpoint - nothing changes in the view on the simulator
[self.view setNeedsDisplay];
// breakpoint - nothing changes in the view on the simulator
self.myInfoBox.i_statusLabel.text = @"Reloading...";
// breakpoint - nothing changes in the view on the simulator
[self readStuffFromDB];
sleep(2);
//disabled view removal for testing..
//[self.myInfoBox.view removeFromSuperview];
// breakpoint - nothing changes in the view on the simulator
}

我在测试中发生的事情是,当 -(void)loadMainView 方法完成时,myInfoBox 对象在屏幕上创建,然后我可以在屏幕上看到背景中的“myInfoBox”,而前面的 alertView(对于testing...) 此时屏幕有响应,我可以选择 YES,一旦我选择 Yes,委托(delegate)方法就会被调用。正如我在源文件中评论的那样,我正在使用断点监视模拟器并遵循代码,但当我仍在 - (void)userInitialSetupMainThread 方法中时,更改的标签值不会反射(reflect)出来,但是一旦它完成 View 更新使用最新设置的 .text 值!!咕噜..

此外,myInfoBox 类的源代码:

@interface InfoBoxController : UIViewController {
IBOutlet UILabel* i_titleLabel;
IBOutlet UILabel* i_statusLabel;
IBOutlet UIImageView* i_loadingImage;
IBOutlet UIImageView* i_background;
IBOutlet UIActivityIndicatorView* i_activityIndicator;
}

@property(nonatomic, retain) IBOutlet UILabel* i_titleLabel;
@property(nonatomic, retain) IBOutlet UILabel* i_statusLabel;
@property(nonatomic, retain) IBOutlet UIImageView* i_loadingImage;
@property(nonatomic, retain) IBOutlet UIImageView* i_background;
@property(nonatomic, retain) IBOutlet UIActivityIndicatorView* i_activityIndicator;

//- (void)updateValuesForTitle:(NSString *)title Label:(NSString *)label;
- (void)updateValuesForTitle:(NSString *)title;

@end

@implementation InfoBoxController

@synthesize i_titleLabel, i_statusLabel, i_loadingImage, i_background;
@synthesize i_activityIndicator;

//-(void)updateValuesForTitle:(NSString *)title Label:(NSString *)label
-(void)updateValuesForTitle:(NSString *)title
{
self.i_titleLabel.text = title;
self.i_statusLabel.text = title;
[self.i_titleLabel setNeedsDisplay];
[self.i_statusLabel setNeedsDisplay];
}

抱歉发了 LOONG 帖子 :)请协助!

最佳答案

冒着听起来毫无帮助的风险,这就是它的工作原理。如果您在主事件循环中有长时间运行的代码(即,您没有显式创建线程或类似线程),操作系统将无法更新 UI。

要在代码运行时更新 UI,您需要使用线程、NSOperationQueue 等在后台运行复杂的操作,或者只是将其分解为更小的步骤并将控制权返回给偶尔主循环,以便可以更新 UI。

关于iphone - 在方法中运行时,从 nib 加载的 View 不会更新 UILabel 的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1119458/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com