- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我想通过委托(delegate)方法更新 UIViewController
中的 UIView
。
有草图:用户从 UIViewController
触发下载,下载由类管理,当 UploadAsyncData
完成时,下载方法将处理的响应传递给另一个类。此类将接收到的数据写入本地数据库。
我想通知用户将 UIViewController
从流程进度中扔到哪里。
我现在做了什么:
在 UIViewController
中,我得到了一个 UIView
,它代表一个带有一些消息的 Overlay
。 UIView
也设置为静态帮助器类,以帮助从外部引用它。
当用户按下下载按钮时,Overlay
会出现并通知用户操作已被触发。
当操作传递给下载类时,Overlay
文本更新为“您的下载正在进行中”
下载完成后,下载类中处理响应的方法将 Overlay
文本更新为“下载完成,正在处理收到的数据...”
由于接收到的数据是一个 C# 对象,我从该对象调用 SaveToDatabase 方法。
SaveToDatabase 方法使用进度指示器更新 Overlay
。
到目前为止,除了 SaveToDatabase
步骤之外,所有步骤都正确地更新了 Overlay
消息。调试时我可以看到更新 Overlay
文本的方法在每一步都被调用,但是 UIView
文本没有更新。
我不能使用 InvokeOnMainThread
因为 SaveToDatabase 不是 UIViewController
我不明白的是为什么所有步骤都正确更新 UIView 但最后一个不是.
这里是所有这一步的一些提取代码。
主要方法
public class Program:UIViewController
{
{...}
public override void ViewDidLoad()
{
base.ViewDidLoad();
AddOverlay();
}
public void AddOverlay()
{
var bounds = UIScreen.MainScreen.Bounds;
bounds.Size = new CGSize(bounds.Size.Width, bounds.Size.Height);
loadingOverlay = new LoadingOverlay(bounds);
loadingOverlay.Hidden = true;
View.Add(loadingOverlay);
System.Diagnostics.Debug.WriteLine(this.GetType().Name + loadingOverlay.GetHashCode());
Helpers.LoadingOverlay = loadingOverlay;
}
public void DisplayOverlay(string text)
{
if(loadingOverlay != null){
View.BringSubviewToFront(loadingOverlay);
System.Diagnostics.Debug.WriteLine(this.GetType().Name + loadingOverlay.GetHashCode());
loadingOverlay.Hidden = false;
loadingOverlay.SetLoadingLabel( text );
}
}
void Tablesource_OnRowSelected(object sender, eConversion5.DownloadTableSource.RowSelectedEventArgs e)
{
bool isReacheable = myParameters.IsReachable();
if (isReacheable) {
DisplayOverlay("Your download is about to start...");
Request request = new Request(url, myParameters);
request.CanBeSaved = false;
request.Action = "display";
httpCommunication.DoRequest(request);
}
}
}
处理 downloadAction 的方法
public class HttpCommunication
{
{...}
public HttpCommunication(Parametrage parameters, HttpResponseAction responseAction)
{
client = new XSWebClient();
client.UploadDataCompleted += OnUploadDataCompleted;
}
public void DoRequest(Request JRequest)
{
{...}
SendRequest();
}
void SendRequest()
{
{...}
client.UploadDataAsync(Request.Uri, "POST", bytes);
{...}
}
void OnUploadDataCompleted(object sender, UploadDataCompletedEventArgs e)
{
Helpers.UpdateOverlayMessage("Processing recieved response...");
{...}
HandleResponse handler = new HandleResponse(myParameters, e.Result);
{...}
}
}
处理服务器响应的类
public class HttpResponseAction
{
{...}
public void ExecuteAction(HandleResponse handled, Request request)
{
{...}
Helpers.UpdateOverlayMessage("Processing response...");
{...}
HandleTrainings(queryId, action, JsonConvert.DeserializeObject<List<TrainingContainer>>(json, Settings));
{...}
}
void HandleFormation(string queryId, string action, object nestedResult)
{
{...}
if (action == "display") {
result.SaveToDatabase();
{...}
}
{...}
}
}
最后一步,不更新 UIView(之前的所有步骤都正确更新它)
public class TrainingContainer
{
{...}
public void SaveToDatabase()
{
if(SignList != null){
Helpers.UpdateOverlayMessage("Updating sign list in progress, may be take a while...");
int updated = 0;
int total = SignList.Count();
if(total > 0){
foreach (Training training in SignList) {
updated++;
float progress = (float) updated / total;
Helpers.UpdateProgressValue(progress); //From debbuging, i can see that this method is called, and Overlay object is the same throw all class calls from the starting point.
{...}
}
}
}
{...}
}
}
Helper 类
public static class Helpers
{
public static LoadingOverlay LoadingOverlay;
{...}
public static void UpdateOverlayMessage(string message)
{
if(LoadingOverlay != null){
StackTrace stackTrace = new StackTrace();
System.Diagnostics.Debug.WriteLine(typeof(Helpers).Name + " (called from " + stackTrace.GetFrame(1).GetMethod().Name + ")" + LoadingOverlay.GetHashCode());
LoadingOverlay.SetLoadingLabel(message);
}
}
public static void UpdateProgressValue(float progessValue)
{
if (LoadingOverlay != null) {
StackTrace stackTrace = new StackTrace();
System.Diagnostics.Debug.WriteLine(typeof(Helpers).Name + " (called from " + stackTrace.GetFrame(1).GetMethod().Name + ")" + LoadingOverlay.GetHashCode());
LoadingOverlay.UpdateProgress(progessValue);
}
}
}
编辑:一些跟踪记录来自对 Helper 的调用。
Helpers <UpdateOverlayMessage> :Transmitting request to the server...(called from Apply) -2037862263
Helpers <UpdateOverlayMessage> :Processing recieved response...(called from Apply) -2037862263
Helpers <UpdateOverlayMessage> :Processing response...(called from Apply) -2037862263
Helpers <UpdateOverlayMessage> :Updating sign list in progress, may be take a while...(called from Apply) -2037862263
Helpers <UpdateProgressValue> (called from Apply)-2037862263
Helpers <UpdateProgressValue> (called from Apply)-2037862263
Helpers <UpdateProgressValue> (called from Apply)-2037862263
Helpers <UpdateProgressValue> (called from Apply)-2037862263
Helpers <UpdateProgressValue> (called from Apply)-2037862263
Helpers <UpdateProgressValue> (called from Apply)-2037862263
Helpers <UpdateProgressValue> (called from Apply)-2037862263
Helpers <UpdateProgressValue> (called from Apply)-2037862263
Helpers <UpdateProgressValue> (called from Apply)-2037862263
Helpers <UpdateProgressValue> (called from Apply)-2037862263
Helpers <UpdateProgressValue> (called from Apply)-2037862263
Helpers <UpdateProgressValue> (called from Apply)-2037862263
Helpers <UpdateProgressValue> (called from Apply)-2037862263
Helpers <UpdateProgressValue> (called from Apply)-2037862263
更新 2:忘记显示 Overlay 类
public class LoadingOverlay : UIView {
// control declarations
UIActivityIndicatorView activitySpinner;
UILabel loadingLabel;
UIProgressView progressView;
public LoadingOverlay (CGRect frame) : base (frame)
{
// configurable bits
BackgroundColor = UIColor.Black;
Alpha = 0.55f;
AutoresizingMask = UIViewAutoresizing.All;
nfloat labelHeight = 22;
nfloat labelWidth = Frame.Width - 20;
// derive the center x and y
nfloat centerX = Frame.Width / 2;
nfloat centerY = Frame.Height / 2;
// create the activity spinner, center it horizontall and put it 5 points above center x
activitySpinner = new UIActivityIndicatorView(UIActivityIndicatorViewStyle.WhiteLarge);
activitySpinner.Frame = new CGRect (
centerX - (activitySpinner.Frame.Width / 2) ,
centerY - activitySpinner.Frame.Height - 20 ,
activitySpinner.Frame.Width,
activitySpinner.Frame.Height);
activitySpinner.AutoresizingMask = UIViewAutoresizing.All;
AddSubview (activitySpinner);
activitySpinner.StartAnimating ();
// create and configure the "Loading Data" label
loadingLabel = new UILabel(new CGRect (
centerX - (labelWidth / 2),
centerY + 20 ,
labelWidth ,
labelHeight
));
loadingLabel.BackgroundColor = UIColor.Clear;
loadingLabel.TextColor = UIColor.White;
loadingLabel.Text = "Wait a moment...";
loadingLabel.TextAlignment = UITextAlignment.Center;
loadingLabel.AutoresizingMask = UIViewAutoresizing.All;
AddSubview (loadingLabel);
progressView = new UIProgressView();
progressView.Progress = 0.0f;
var screenParts = Frame.Width / 3;
progressView.Frame = new CGRect(new CGPoint(screenParts,loadingLabel.Frame.Y + loadingLabel.Frame.Height + 20), new CGSize(screenParts,40));
progressView.Hidden = true;
AddSubview(progressView);
}
/// <summary>
/// Fades out the control and then removes it from the super view
/// </summary>
public void Hide ()
{
progressView.Progress = 0.0f;
InvokeOnMainThread(() => {
UIView.Animate(
0.5, // duration
() => { Alpha = 0; },
() => { RemoveFromSuperview(); }
);
});
}
public void SetLoadingLabel(String text)
{
InvokeOnMainThread(() => {
loadingLabel.Text = text;
});
}
public void UpdateProgress(float progressValue){
if(progressView.Hidden){
progressView.Hidden = false;
}
if(progressValue > 1){
progressValue = 1;
}
InvokeOnMainThread(() => {
progressView.SetProgress(progressValue, true);
});
}
}
最佳答案
更新 UI 时,请确保它在主线程上运行。 InvokeOnMainThread 方法是在 NSObject 上定义的,因此使 Helper 类继承自 NSObject。所以 Helper 类可以改进为:
public sealed class Helpers:NSObject
{
public LoadingOverlay LoadingOverlay;
private static readonly Helpers instance = new Helpers();
private Helpers(){}
public static Helpers Instance
{
get
{
return instance;
}
}
public void UpdateOverlayMessage(string message)
{
InvokeOnMainThread ( () => {
if(LoadingOverlay != null){
StackTrace stackTrace = new StackTrace();
System.Diagnostics.Debug.WriteLine(typeof(Helpers).Name + " (called from " + stackTrace.GetFrame(1).GetMethod().Name + ")" + LoadingOverlay.GetHashCode());
LoadingOverlay.SetLoadingLabel(message);
}
});
}
//So does the method "UpdateProgressValue".
}
在主要方法中:
Helpers.Instance.LoadingOverlay = loadingOverlay;
更新用户界面时:
Helpers.Instance.UpdateOverlayMessage("...");
关于c# - UIControllerView 不会从委托(delegate)函数更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43386614/
尝试使用集成到 QTCreator 的表单编辑器,但即使我将插件放入 QtCreator.app/Contents/MacOS/designer 也不会显示。不过,相同的 dylib 文件确实适用于独
在此代码示例中。 “this.method2();”之后会读到什么?在返回returnedValue之前会跳转到method2()吗? public int method1(int returnedV
我的项目有通过gradle配置的依赖项。我想添加以下依赖项: compile group: 'org.restlet.jse', name: 'org.restlet.ext.apispark', v
我将把我们基于 Windows 的客户管理软件移植到基于 Web 的软件。我发现 polymer 可能是一种选择。 但是,对于我们的使用,我们找不到 polymer 组件具有表格 View 、下拉菜单
我的项目文件夹 Project 中有一个文件夹,比如 ED 文件夹,当我在 Eclipse 中指定在哪里查找我写入的文件时 File file = new File("ED/text.txt"); e
这是奇怪的事情,这个有效: $('#box').css({"backgroundPosition": "0px 250px"}); 但这不起作用,它只是不改变位置: $('#box').animate
这个问题在这里已经有了答案: Why does OR 0 round numbers in Javascript? (3 个答案) 关闭 5 年前。 Mozilla JavaScript Guide
这个问题在这里已经有了答案: Is the function strcmpi in the C standard libary of ISO? (3 个答案) 关闭 8 年前。 我有一个问题,为什么
我目前使用的是共享主机方案,我不确定它使用的是哪个版本的 MySQL,但它似乎不支持 DATETIMEOFFSET 类型。 是否存在支持 DATETIMEOFFSET 的 MySQL 版本?或者有计划
研究 Seam 3,我发现 Seam Solder 允许将 @Named 注释应用于包 - 在这种情况下,该包中的所有 bean 都将自动命名,就好像它们符合条件一样@Named 他们自己。我没有看到
我知道 .append 偶尔会增加数组的容量并形成数组的新副本,但 .removeLast 会逆转这种情况并减少容量通过复制到一个新的更小的数组来改变数组? 最佳答案 否(或者至少如果是,则它是一个错
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
noexcept 函数说明符是否旨在 boost 性能,因为生成的对象中可能没有记录异常的代码,因此应尽可能将其添加到函数声明和定义中?我首先想到了可调用对象的包装器,其中 noexcept 可能会产
我正在使用 Angularjs 1.3.7,刚刚发现 Promise.all 在成功响应后不会更新 angularjs View ,而 $q.all 会。由于 Promises 包含在 native
我最近发现了这段JavaScript代码: Math.random() * 0x1000000 10.12345 10.12345 >> 0 10 > 10.12345 >>> 0 10 我使用
我正在编写一个玩具(物理)矢量库,并且遇到了 GHC 坚持认为函数应该具有 Integer 的问题。是他们的类型。我希望向量乘以向量以及标量(仅使用 * ),虽然这可以通过仅使用 Vector 来实现
PHP 的 mail() 函数发送邮件正常,但 Swiftmailer 的 Swift_MailTransport 不起作用! 这有效: mail('user@example.com', 'test
我尝试通过 php 脚本转储我的数据,但没有命令行。所以我用 this script 创建了我的 .sql 文件然后我尝试使用我的脚本: $link = mysql_connect($host, $u
使用 python 2.6.4 中的 sqlite3 标准库,以下查询在 sqlite3 命令行上运行良好: select segmentid, node_t, start, number,title
我最近发现了这段JavaScript代码: Math.random() * 0x1000000 10.12345 10.12345 >> 0 10 > 10.12345 >>> 0 10 我使用
我是一名优秀的程序员,十分优秀!