设计一个显示消息、returns 自定义对象并等待用户响应的对话框
Designing a dialogbox that displays message, returns a custom object and waits for user response
我正在尝试为所有平台上的运行时统一设计一个自定义对话框(在我的例子中是 Android 和网络播放器)。
我已成功显示对话框并获得用户响应并更新此响应。但是我不知道如何调用显示对话框并在它之前等待 return 从其他方法外部使用它时的值/class.
这是我显示对话框的代码:
public void ShowDialogBox(string title, string message, DialogBoxButtons buttons)
{
StartCoroutine(ShowDialogBoxHelper(title, message, buttons));
}
public void ShowDialogBox(string title, string message)
{
StartCoroutine(ShowDialogBoxHelper(title, message, DialogBoxButtons.OK));
}
public IEnumerator ShowDialogBoxHelper (string title, string message, DialogBoxButtons buttons)
{
Response = DialogResponse.NONE;
Title.text = title;
Message.text = message;
ButtonSet = buttons;
HandleButtonSet(ButtonSet);
_canvasGroup.alpha = 1;
_canvasGroup.interactable = true;
transform.SetAsLastSibling();
_apprearenceMode = ApprearenceMode.Shown;
yield return StartCoroutine(WaitForButtonResponse());
Debug.Log("user response : " + Response);
}
协程 "WaitForButtonResponse()" 声明如下:
IEnumerator WaitForButtonResponse()
{
Debug.Log("waiting in the enumerator, responded: " + Response);
yield return new waitForUserAction(() => Response != DialogResponse.NONE);
Debug.Log("done waiting in the enumerator, responded: " + Response);
}
而"waitForUserAction()"协程是自定义协程,继承自CustomYieldInstruction
[System.Serializable]
class waitForUserAction : CustomYieldInstruction
{
Func<bool> m_Predicate;
public override bool keepWaiting { get { return !m_Predicate(); } }
public waitForUserAction(Func<bool> predicate) { m_Predicate = predicate; }
}
当我调用 ShowDialogBox 方法时,对话框按预期出现,当我单击其中一个选项时,响应已正确更新。但是,如果我希望 ShowDialogBox return 响应并等待用户在 returning 之前单击对话框按钮,我该如何实现?
期望的行为:
public DialogResponse ShowDialogBox(string title, string message, DialogBoxButtons buttons)
{
StartCoroutine(ShowDialogBoxHelper(title, message, buttons));
return Response;
}
和这样的用法:
if (ShowDialogBox("test", "testing dialog box behaviour", DialogBoxButtons.YES_NO_CANCEL) == DialogResponse.YES)
{
//do something
}
现在的问题是,"return Response;" 不等待 "StartCoroutine(ShowDialogBoxHelper(title, message, buttons));" 更新用户的选择并且 return 是 Response 的旧值而不是用户当前选择的值.
提前感谢您在这方面的任何帮助!
干杯,
阿尼
您无需立即评估结果,而是需要实际等待并告诉例程在出现响应时该怎么做。
我会使用 Action<DialogResponse>
,例如:
// Here you can actually use an overload with optional parameter
// If you don't pass in the "buttons" it simply has the default value `OK`
// And additionally pass in the action to invoke once a response was given
// If you don't pass it then simply nothing happens ;)
public void ShowDialogBox(string title, string message, DialogBoxButtons buttons = DialogBoxButtons.OK, Action<DialogResponse> onResponse = null)
{
StartCoroutine(ShowDialogBoxHelper(title, message, buttons, onResponse));
}
public IEnumerator ShowDialogBoxHelper (string title, string message, DialogBoxButtons buttons, Action<DialogResponse> onResponse)
{
Response = DialogResponse.NONE;
Title.text = title;
Message.text = message;
ButtonSet = buttons;
HandleButtonSet(ButtonSet);
_canvasGroup.alpha = 1;
_canvasGroup.interactable = true;
transform.SetAsLastSibling();
_apprearenceMode = ApprearenceMode.Shown;
// Here rather use the Unity built-in
yield return new WaitWhile(() => Response == DialogResponse.NONE);
Debug.Log("user response : " + Response);
onResponse?.Invoke(Response);
}
您可以将其与 lambda 表达式一起使用,例如
ShowDialogBox("test", "testing dialog box behaviour", DialogBoxButtons.YES_NO_CANCEL, response =>
{
if(response == DialogResponse.YES)
{
// Do something
}
});
或相同但有一个方法
ShowDialogBox("test", "testing dialog box behaviour", DialogBoxButtons.YES_NO_CANCEL, HandleResponse);
private void HandleResponse(DialogResponse response)
{
if(response == DialogResponse.YES)
{
// Do something
}
}
我正在尝试为所有平台上的运行时统一设计一个自定义对话框(在我的例子中是 Android 和网络播放器)。
我已成功显示对话框并获得用户响应并更新此响应。但是我不知道如何调用显示对话框并在它之前等待 return 从其他方法外部使用它时的值/class.
这是我显示对话框的代码:
public void ShowDialogBox(string title, string message, DialogBoxButtons buttons)
{
StartCoroutine(ShowDialogBoxHelper(title, message, buttons));
}
public void ShowDialogBox(string title, string message)
{
StartCoroutine(ShowDialogBoxHelper(title, message, DialogBoxButtons.OK));
}
public IEnumerator ShowDialogBoxHelper (string title, string message, DialogBoxButtons buttons)
{
Response = DialogResponse.NONE;
Title.text = title;
Message.text = message;
ButtonSet = buttons;
HandleButtonSet(ButtonSet);
_canvasGroup.alpha = 1;
_canvasGroup.interactable = true;
transform.SetAsLastSibling();
_apprearenceMode = ApprearenceMode.Shown;
yield return StartCoroutine(WaitForButtonResponse());
Debug.Log("user response : " + Response);
}
协程 "WaitForButtonResponse()" 声明如下:
IEnumerator WaitForButtonResponse()
{
Debug.Log("waiting in the enumerator, responded: " + Response);
yield return new waitForUserAction(() => Response != DialogResponse.NONE);
Debug.Log("done waiting in the enumerator, responded: " + Response);
}
而"waitForUserAction()"协程是自定义协程,继承自CustomYieldInstruction
[System.Serializable]
class waitForUserAction : CustomYieldInstruction
{
Func<bool> m_Predicate;
public override bool keepWaiting { get { return !m_Predicate(); } }
public waitForUserAction(Func<bool> predicate) { m_Predicate = predicate; }
}
当我调用 ShowDialogBox 方法时,对话框按预期出现,当我单击其中一个选项时,响应已正确更新。但是,如果我希望 ShowDialogBox return 响应并等待用户在 returning 之前单击对话框按钮,我该如何实现?
期望的行为:
public DialogResponse ShowDialogBox(string title, string message, DialogBoxButtons buttons)
{
StartCoroutine(ShowDialogBoxHelper(title, message, buttons));
return Response;
}
和这样的用法:
if (ShowDialogBox("test", "testing dialog box behaviour", DialogBoxButtons.YES_NO_CANCEL) == DialogResponse.YES)
{
//do something
}
现在的问题是,"return Response;" 不等待 "StartCoroutine(ShowDialogBoxHelper(title, message, buttons));" 更新用户的选择并且 return 是 Response 的旧值而不是用户当前选择的值.
提前感谢您在这方面的任何帮助!
干杯,
阿尼
您无需立即评估结果,而是需要实际等待并告诉例程在出现响应时该怎么做。
我会使用 Action<DialogResponse>
,例如:
// Here you can actually use an overload with optional parameter
// If you don't pass in the "buttons" it simply has the default value `OK`
// And additionally pass in the action to invoke once a response was given
// If you don't pass it then simply nothing happens ;)
public void ShowDialogBox(string title, string message, DialogBoxButtons buttons = DialogBoxButtons.OK, Action<DialogResponse> onResponse = null)
{
StartCoroutine(ShowDialogBoxHelper(title, message, buttons, onResponse));
}
public IEnumerator ShowDialogBoxHelper (string title, string message, DialogBoxButtons buttons, Action<DialogResponse> onResponse)
{
Response = DialogResponse.NONE;
Title.text = title;
Message.text = message;
ButtonSet = buttons;
HandleButtonSet(ButtonSet);
_canvasGroup.alpha = 1;
_canvasGroup.interactable = true;
transform.SetAsLastSibling();
_apprearenceMode = ApprearenceMode.Shown;
// Here rather use the Unity built-in
yield return new WaitWhile(() => Response == DialogResponse.NONE);
Debug.Log("user response : " + Response);
onResponse?.Invoke(Response);
}
您可以将其与 lambda 表达式一起使用,例如
ShowDialogBox("test", "testing dialog box behaviour", DialogBoxButtons.YES_NO_CANCEL, response =>
{
if(response == DialogResponse.YES)
{
// Do something
}
});
或相同但有一个方法
ShowDialogBox("test", "testing dialog box behaviour", DialogBoxButtons.YES_NO_CANCEL, HandleResponse);
private void HandleResponse(DialogResponse response)
{
if(response == DialogResponse.YES)
{
// Do something
}
}