I have pursued the internet for an answer and following steps in apple documentation but to no avail.
I have two view controllers. One which contains a list of favourite items (FavouriteTableViewController), another which contains the details of the item being added to the list of favourites (ExplorationDetailViewController).
I have a save button on the navigation bar (from a navigation controller scene) in the ExplorationDetailViewController that I want to click to kick off the unwind segue. I have carried out the following steps, but when I click on the save button, it is completely unresponsive. I am including the most relevant code for the unwind.
I have created prepareforsegue function in ExplorationResultViewController from where I will be passing data for an image and a label to the other ViewController as part of the unwind segue
class ExplorationResultViewController: UIViewController {
var exploration_result: Favourites?
#IBOutlet weak var ExplorationLabel: UILabel!
#IBOutlet weak var ExplorationPhoto: UIImageView!
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Pass the selected object to the new view controller.
super.prepare(for: segue, sender: sender)
let photo = ExplorationPhoto.image
let name = ExplorationLabel.text ?? ""
exploration_result = Favourites(name: name, photo: photo)
}
Then in the FavouriteTableViewController, I have added an unwindtoHere method which adds image and label to the list.
class FavouritesTableViewController: UITableViewController {
// MARK: Properties
var favourites = [Favourites]()
// MARK: Actions
#IBAction func unwindToFavouriteList(sender: UIStoryboardSegue) {
if let sourceViewController = sender.source as? ExplorationResultViewController, let favourite = sourceViewController.exploration_result{
// Add a new meal.
let newIndexPath = IndexPath(row: favourites.count, section: 0)
favourites.append(favourite)
tableView.insertRows(at: [newIndexPath], with: .automatic)
}
Then going into my storyboard, I control+drag the Save button in the ExplorationDetailViewController and connect it to the exit item at the top of the scene. My unwind method appears in the pop up as: 'unwindToFavouriteListWithSender'. I select this.
I should be good to go now, but when I run the simulator and click the Save button, it is absolutely unresponsive. See StoryBoard Design
Please help
From your comments, I'm guessing that the problem is that there is no FavouritesTableViewController in the view controller hierarchy at the time that the Save button is pressed. You cannot unwind to something that isn't already present: "unwind" means go back to something that was instantiated earlier and remains present, above the current view controller in the view controller hierarchy.
For example, let's say we have
UINavigationController -> (root view controller) -> FavouritesTableViewController
-> (push) ExplorationResultViewController
Now we can unwind from the Exploration controller to the Favourites controller, because the Favorites controller is already in the hierarchy before the Exploration controller. It sounds like maybe you are not appreciating that fact.
Related
I try the new Shell of Xamarin Form 4 for a small project.
I have a list of order, then someone chooses an order and start picking some inventory for this order with barcode. To be simple, I use 2 views and 2 viewmodel.
The process is:
1. User select an order the click a button "pickup"
2. I use ViewModelLocator (TinyIoc) to resolve the correct ViewModel of the pickup view
3. I call Initialize on the new ViewModel and pass some parameters needed. Like a list of items needed to be pickup.
4. Open the view in modal state.
I don't understand that if I change some qty in the list I pass on the second viewmodel, then hit the back button (modal view close). The quantity changed is now in the original viewmodel. How this is possible? I was thinking that passing parameter to a function do not share the same variable but just copy it??
Viewmodel of the first view (look at the Initialize function the List passed and the JobEnCours object)
private async Task GoPickup()
{
Device.BeginInvokeOnMainThread(async () =>
{
if (this.CodeJob != null && this.CodeJob != "")
{
this.IsBusy = true;
PrepChariotSP3ViewModel vm = ViewModelLocator.Resolve<PrepChariotSP3ViewModel>();
await vm.InitializeAsync(this._jobEnCours, this.ComposantesPick.ToList()) ;
await Shell.Current.Navigation.PushAsync(new PrepChariotSP3Page(vm));
this.IsBusy = false;
}
});
}
the the Initialize code on the second Viewmodel (look I set the JobEnCours.Description=Test)
public async Task InitialiseAsync(Job jobEnCours, List<ComposantePick> composantePick)
{
Title = "Ceuillette: " + jobEnCours.CodeProd;
this._jobEnCours = jobEnCours;
this.ComposantesPick = new ItemsChangeObservableCollection<ComposantePick>();
foreach(ComposantePick c in composantePick)
{
this.ComposantesPick.Add(c);
}
jobEnCours.Description = "test";
So, If I do the back button, then in the first VM the JobEnCours.Description is now set to "test" how this is possible?!
Any idea?
I went through some documentations here and here and found that gluon dialogs Can* have a generic type which will be the generic type of the object to be returned when you call showAndWait(). But gluon alerts (com.gluonhq.charm.glisten.control.Alert which is a subclass of com.gluonhq.charm.glisten.control.Dialog) does not seem to have a generic type and does not also seem to allow you to give it a generic type.
The problem occured when I tried to call setOnHidden as:
boolean shown;
String report = "";
Alert al = new Alert(AlertType.ERROR);
al.setContentText(report);
al.setAutoHide(false);
al.setOnHidden(e->{
shown = false;
});
shown = true;
al.showAndWait();
and I got the following warning on the setOnHidden() Call:
The method setOnHidden(EventHandler) belongs to the raw type Dialog. References to generic type Dialog should be parameterized
Any clarifications about gluon dialogs or ways to get rid of the warning are most welcome.
Like in the built-in JavaFX Alert control, the implicit type of the Gluon's Alert control is the same: the JavaFX built-in ButtonType, so if you click the OK button, it will return ButtonType.OK.
As you can see at the Alert JavaDoc, the control has one or two default buttons: an OK button for all of them, and a Cancel button for the Confirmation alert. Each of these buttons has as default result ButtonType.OK and ButtonType.CANCEL.
So this works for both Alert controls:
alert.showAndWait().ifPresent(result -> {
if (result == ButtonType.OK) {
// do something;
}
});
One of the things you will notice with both OK and Cancel buttons: the alert will be dismissed, so you don't have to do it.
You can also provide your custom buttons. Then you'll need to take care of calling hide():
final Button myYesButton = new Button("Yes");
myYesButton.setOnAction(event -> {
alert.setResult(ButtonType.YES);
alert.hide();
});
alert.getButtons().add(myYesButton);
About the setOnHidden, see Javadoc. It requires a LifecycleEvent:
alert.setOnHidden((LifecycleEvent event) -> System.out.println("alert hidden"));
but you can use just:
alert.setOnHidden(event -> System.out.println("alert hidden"));
Finally, make sure you are importing the right control:
import com.gluonhq.charm.glisten.control.Alert;
...
Alert alert = new Alert(javafx.scene.control.Alert.AlertType.ERROR);
I have an activity indicator on xaml page. Initially its IsVisible property is false. I have a button on page. When user click on button it calls a web service to get data. I change the value of IsVisible property to true before calling the service so that activity indicator starts to display on page and after successful calling of service I change its value to again false so that it doesn't show any more on page.
But it is not working. I know the actual problem. When we call the web service the UI thread gets block and it doesn't show the activity indicator.
How I can enable the UI thread when web service gets called so that activity indicator can show on page until we get the data?
Try making your webservice call into an async and await it.
Depending on how you've structured things you may have to use a TaskCompletionSource as the following example demonstrates.
In this example when the button is clicked, the button is made invisible, and the ActivityIndicator is set to IsRunning=True to show it.
It then executes your long running task / webservice in the function ExecuteSomeLongTask using a TaskCompletionSource.
The reason for this is that in our button click code, we have the final lines:-
objActivityIndicator1.IsRunning = false;
objButton1.IsVisible = true;
That stop the ActivityIndicator from running and showing, and also set the button back to a visible state.
If we did not use a TaskCompletionSource these lines would execute immediately after calling the ExecuteSomeLongTask if it was a normal async method / function, and would result in the ActivityIndicator not running and the button still being visible.
Example:-
Grid objGrid = new Grid()
{
};
ActivityIndicator objActivityIndicator1 = new ActivityIndicator();
objGrid.Children.Add(objActivityIndicator1);
Button objButton1 = new Button();
objButton1.Text = "Execute webservice call.";
objButton1.Clicked += (async (o2, e2) =>
{
objButton1.IsVisible = false;
objActivityIndicator1.IsRunning = true;
//
bool blnResult = await ExecuteSomeLongTask();
//
objActivityIndicator1.IsRunning = false;
objButton1.IsVisible = true;
});
objGrid.Children.Add(objButton1);
return objGrid;
Supporting function:-
private Task<bool> ExecuteSomeLongTask()
{
TaskCompletionSource<bool> objTaskCompletionSource1 = new TaskCompletionSource<bool>();
//
Xamarin.Forms.Device.StartTimer(new TimeSpan(0, 0, 5), new Func<bool>(() =>
{
objTaskCompletionSource1.SetResult(true);
//
return false;
}));
//
return objTaskCompletionSource1.Task;
}
You need to do your work in an asynchronous way. Or in other words: Use Asnyc & Await to ensure, that you UI works well during the call.
You can find more informations in the Xamarin Docs.
async and await are new C# language features that work in conjunction
with the Task Parallel Library to make it easy to write threaded code
to perform long-running tasks without blocking the main thread of your
application.
If you need further asistance, please update your question and post your code or what you have tried so far.
Fist of all, I'm really sorry for my bad English and I pretty new to game maker .
I have 2 object in the game : obj_apple and obj_door( I unchecked visible box)
my question is
how can I make an obj_door visible in the room when all the obj_apple are destroyed?
Object obj_door, Step event, place code (Add event -> Step -> Step -> tab Control -> section Code, first icon (Execute code)):
if !instance_exists(obj_apple) visible = true;
Another option, so you aren't making a check in every step event, is to put the check for the number of obj_apple in the destroy event of obj_apple.
For example, in the destroy event of obj_apple you would have:
if (instance_number(object_index) == 0) {
with (obj_door) {
visible = true;
}
}
I am trying to switch to a New window which gets displayed when I click on the Debt Pricing Template. But I am unable to do that as a result of which I am not able to proceed with further scripting... The problem is I am not able to know what should I pass in the switchTo.window() because Pricing Approval Gateway window displays and following is the HTML for the new window:
<*h1 class="pageType noSecondHeader">Pricing Approval Gateway<*/h1>
Following is the code:
LoginPage2.driver.findElement(By.linkText("TEST ORG")).click();
System.out.println("3.Select Dept pricing template button from the organization detail page.");
if(LoginPage2.driver.findElement(By.name("debt_pricing_template")).isDisplayed())
System.out.println("User should able to navigate to Dept pricing template and template display few question, user have answer these question for further navigation.");
LoginPage2.driver.findElement(By.name("debt_pricing_template")).click();
LoginPage2.driver.manage().timeouts().implicitlyWait(100, TimeUnit.SECONDS);
LoginPage2.driver.switchTo().window("bPageTitle");
Please advise what needs to be added?
I never used it because in my tests I am not using any new windows, but this should help:
Set<string> handlers = driver.getWindowHandles();
if (driver.getWindowHandles().size()>= 1){
for(String handler : handlers){
driver.switchTo().window(handler);
if (driver.getElement(By.tagName("h1")).contains("Pricing")){
System.out.println("Get focus on Popup window");
break;
}
}
}
else System.out.println("No windows founded!");
I am not quite sure with the h1 approach. So if it does not help, try before opening new window storing current window to String:
String mainWindow = driver.getWindowHandle();
Then click the link (or do something else as you are doing now) to open new window. Then to switch to the new window:
Set<string> handlers = driver.getWindowHandles();
for (String handler : handlers){
if (!handler.equals(mainWindow)){
driver.switchTo(handler);
break;
}
}
And then to switch back to original window just do:
driver.switchTo(mainWindow);
Ofcourse the driver variable is expected live instance of
WebDriver
driver.findElement(By.linkText("Go to Billing Summary")).click();
driver.findElement(By.linkText("01 Mar 2016")).click();
Thread.sleep(5000);
driver.findElement(By.linkText("AMS TAX")).click();
driver.findElement(By.linkText("00842")).click();
Set<String> instancewindow= driver.getWindowHandles();
Iterator<String> it = instancewindow.iterator();
String parent =it.next();
String child = it.next();
driver.switchTo().window(child);
driver.switchTo().frame("modalSubWindow");
driver.findElement(By.linkText("View More Vehicle Details>>")).click();
driver.switchTo().window(parent);