UIView
을 UIViewController
에서 대리인 메서드로 업데이트하고 싶습니다.대리자 함수에서 UIControllerView를 업데이트 할 수 없습니다.
사용자가 UIViewController
에서 다운로드를 다운로드하고, 다운로드가 UploadAsyncData
이 완료되면 다운로드가 다른 클래스에 처리 된 응답을 전달할 때 클래스에 의해 관리됩니다. 이 클래스는받은 데이터를 로컬 데이터베이스에 씁니다.
사용자에게 프로세스 진행 상황 인 UIViewController
을 던지라고 알려 드리고 싶습니다.
다음 UIViewController
에서
내가 그것에 일부 메시지와 함께
Overlay
을 나타내는UIView
을 얻었다.UIView
도 외부에서 참조 할 수 있도록 정적 도우미 클래스로 설정됩니다.사용자가 다운로드 버튼을 누르면
Overlay
이 나타나고 사용자에게 조치가 취해 졌음을 알립니다.조치는
Overlay
텍스트가 업데이트됩니다 다운로드 클래스에 전달됩니다 다운로드는 응답이Overlay
텍스트를 업데이트 처리 다운로드 클래스의 메소드를 완료"다운로드가 진행 중입니다" "다운로드 완료, 수신 된 데이터 처리 중 ..."
받는 데이터가 C# 개체이므로이 개체에서 SaveToDatabase 메서드를 호출합니다.
SaveToDatabase 메서드는 진행률 표시기로
Overlay
을 업데이트합니다.
지금까지 모든 단계를 올바르게 SaveToDatabase
단계를 제외하고 Overlay
메시지를 업데이트하고 있습니다. 디버깅 할 때마다 Overlay
텍스트가 각 단계에서 호출되고 있지만 UIView
텍스트는 업데이트되지 않습니다.
SaveToDatabase가 UIViewController
이 아니므로 InvokeOnMainThread
을 사용할 수 없습니다. 모든 단계가 올바르게 UIView가 마지막으로 업데이트되는 이유는 무엇인지 이해할 수 없습니다.
다음은이 단계의 일부 코드입니다.서버 응답을 처리 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 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);
}
}
}
방법
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.
{...}
}
}
}
{...}
}
}
헬퍼 클래스
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);
}
}
}
편집을 업데이트하지 않는 것이 : 어떤 흔적에 대한 호출에서 로그인 돕는 사람.
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 : 는
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);
});
}
}
, 정적 클래스는 Object에서 파생 할 수 없습니다
하는 UI를 업데이트하는 경우 : 주요 방법에서
: 그래서 도우미 클래스는 같은 개선 될 수 . 그래서 클래스 모델을 다시 생각해야합니다, 나는 이미 내 애플 리케이션과 메모리 문제가있어 개체 사이에 강한 참조를 만들 수있는 패턴을 피하기 위해 싶습니다. – SunLiker67
아, 정적 클래스가 NSObject에서 상속받을 수 없기 때문에 Singleton 패턴을 사용하여이를 수행 할 수 있습니다. 내 대답에 그것을 업데이 트하려고합니다. –
이 업데이트에서는 DoRequest에서 오버레이 업데이트를 중지합니다. – SunLiker67