如何在 ipad 应用程序的后台线程中显示 UIAlertView?
Posted
技术标签:
【中文标题】如何在 ipad 应用程序的后台线程中显示 UIAlertView?【英文标题】:How to show UIAlertView in background thread in ipad app? 【发布时间】:2013-06-26 11:59:48 【问题描述】:我需要在后台执行某些代码时显示警报视图。为此,我实现了以下代码。
//this is loading alert
-(void)showAlert:(NSString *)message
// UIAlertView *alert;
alert11 = [[UIAlertView alloc] initWithTitle:@"Updates" message:message delegate:self
cancelButtonTitle:@"OK" otherButtonTitles: nil];
#ifndef ios5_1
[alert11 autorelease];
#endif
[alert11 show];
-(void) showUpdates1:(NSString *)data
isUpdating = true;
VideoBrowserAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
[appDelegate initApplicationDefaults];
[self performSelectorOnMainThread:@selector(showAlert:)
withObject:@"Please wait while Updating the view...."
waitUntilDone:YES];
[appDelegate openExhibitView1];
//this is update completed alert
[VideoBrowserAppDelegate addUpdateLog:@"Update is completed" showLog:TRUE calledFrom:nil];
但是在执行SelectorOnMainThread(..) 时,会显示警报,但它会在第二秒内消失。之后openExhibitView1()
完全执行并再次正确显示更新警报。当我们再次单击更新警报的确定按钮时,会显示加载警报。但这不公平。我需要显示加载警报,直到openExhibitView1()
在后台执行,除非我们点击确定按钮。
【问题讨论】:
第一个消失可能是因为第二个出现。这是 alertView 属性..第一个隐藏第二个显示,然后当第二个取消然后第一个弹出。 你的问题也是错误的。你不能在后台线程上做 UI thibgs。 正如@rptwsthi 所说,因此您需要防止应用同时显示多个警报 UI 对象不是线程安全的,不应在除主线程之外的任何东西上使用。我不确定如果 Apple 发现 UI 对象在不是主线程的东西上运行,他们是否会拒绝您的应用,这是因为结果可能出乎意料,因此可能会发生崩溃。 嗨@rptewsthi,我需要在更新内容时显示警报消息,我需要显示“更新警报消息”,完成更新时我需要显示更新完成消息。我怎样才能做到这一点 【参考方案1】:我建议你写你自己喜欢的 AlertView。但是不要忘记在 iOS 上继承 alertView 是被禁止的。
我建议您创建自己的 UIView 子类并实现方法 showWithMessage、title 和其他。组合视图,然后显示它。
此外,如果您坚持使用警报 .. 这是一篇有趣的帖子,可能会有所帮助...
Multithreading iOS - performing alerts
但我的建议是使用自定义显示动画子类化 UIView。 动画示例:
- (void)animateShow
CAKeyframeAnimation *animation = [CAKeyframeAnimation
animationWithKeyPath:@"transform"];
CATransform3D scale1 = CATransform3DMakeScale(0.5, 0.5, 1);
CATransform3D scale2 = CATransform3DMakeScale(1.2, 1.2, 1);
CATransform3D scale3 = CATransform3DMakeScale(0.9, 0.9, 1);
CATransform3D scale4 = CATransform3DMakeScale(1.0, 1.0, 1);
NSArray *frameValues = [NSArray arrayWithObjects:
[NSValue valueWithCATransform3D:scale1],
[NSValue valueWithCATransform3D:scale2],
[NSValue valueWithCATransform3D:scale3],
[NSValue valueWithCATransform3D:scale4],
nil];
[animation setValues:frameValues];
NSArray *frameTimes = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:0.0],
[NSNumber numberWithFloat:0.5],
[NSNumber numberWithFloat:0.9],
[NSNumber numberWithFloat:1.0],
nil];
[animation setKeyTimes:frameTimes];
animation.fillMode = kCAFillModeForwards;
animation.removedOnCompletion = NO;
animation.duration = 0.2;
[self.layer addAnimation:animation forKey:@"show"];
- (void)animateHide
CAKeyframeAnimation *animation = [CAKeyframeAnimation
animationWithKeyPath:@"transform"];
CATransform3D scale1 = CATransform3DMakeScale(1.0, 1.0, 1);
CATransform3D scale2 = CATransform3DMakeScale(0.5, 0.5, 1);
CATransform3D scale3 = CATransform3DMakeScale(0.0, 0.0, 1);
NSArray *frameValues = [NSArray arrayWithObjects:
[NSValue valueWithCATransform3D:scale1],
[NSValue valueWithCATransform3D:scale2],
[NSValue valueWithCATransform3D:scale3],
nil];
[animation setValues:frameValues];
NSArray *frameTimes = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:0.0],
[NSNumber numberWithFloat:0.5],
[NSNumber numberWithFloat:0.9],
nil];
[animation setKeyTimes:frameTimes];
animation.fillMode = kCAFillModeForwards;
animation.removedOnCompletion = NO;
animation.duration = 0.1;
[self.layer addAnimation:animation forKey:@"hide"];
[self performSelector:@selector(removeFromSuperview) withObject:self afterDelay:0.105];
【讨论】:
不禁止,只是不支持。我已经成功地将 UIAlertView 子类化为支持块,所以这绝对是一个选择。 @Popeye:是的,他们这样做了,而且他们从不说这是不允许的。您甚至自己引用它:“不支持子类化”。这并不意味着它是不允许的。 “知名”...?举一个例子,有人的应用程序仅仅因为它是 UIAlertView 的子类而被拒绝。不是因为它修改了它的视图层次结构,只是因为它子类化了它。同样,我在商店中有几个应用程序使用了这个子类,它们都被接受了(包括这些应用程序的后续更新)。 @Popeye:我只想重复一遍,请你给我举一个例子,说明有人因为她/他继承了 UIAlertView 而被拒绝了一个应用程序。 “显然”无法阅读文档是您的问题,而不是我的问题,因为“不受支持”并不意味着“不允许”。另外,我还要重申我的另一句话,以防你错过它:Apple 批准了我的一些应用程序 + 更新,其中包含子类。对它进行子类化不等于错误地使用系统提供的项目。 @Popeye:你知道,我用过谷歌,但我在任何地方都没有看到任何提到应用被拒绝的消息。但无论如何,如果你想以艰难的方式做到这一点,那就把自己打晕。只要知道有一个更简单的方法。【参考方案2】:UIKit 不是线程安全的,这意味着最好不要尝试。我自己尝试从后台线程使用警报视图(我忘了在主线程上分派它们)并且行为是出乎意料的,有时是崩溃,有时它在-show
方法之后显示得非常多。
另一点是您不应一次显示多个警报,它们会排队。如果您在显示另一个时显示警报,则最后一个将覆盖第一个,但在解雇后它将再次显示第一个。
最好改变业务逻辑,UIKit + 后台线程是不行的。
【讨论】:
以上是关于如何在 ipad 应用程序的后台线程中显示 UIAlertView?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 iphone/ipad 停靠栏中显示播放项目的详细信息?
如何在我的 iPhone / iPad 的状态栏中显示播放图标