Im having an odd issue with dismissing my achievements and leaderboard viewcontrollers.
The viewcontrollers display correctly and can be dismissed using the done button but only if you press it within about 15 secs of it being displayed, if you press done anytime after that my app just crashes. In the debugger i get a "unrecognized selector sent to instance" error.
I was guessing maybe the viewcontrollers are being garbage collected or something? I'd really appreciate any advice.
heres my code
public void checkAchievements(UIViewController view)
{
GKAchievementViewController gkview = new GKAchievementViewController();
view.PresentModalViewController(gkview,true);
gkview.Delegate = new gkviewdelegate();
}
public class gkviewdelegate : GKAchievementViewControllerDelegate
{
public override void DidFinish (GKAchievementViewController viewController)
{
viewController.DismissModalViewControllerAnimated(true);
Console.WriteLine("Dismiss Leaderboard");
}
}
Your gkview is getting garbage collected. Change it to an instance variable instead in your class to keep a reference to it.
So your code should look a little like;
GKAchievementViewController gkview;
public void checkAchievements(UIViewController view)
{
gkview = new GKAchievementViewController();
view.PresentModalViewController(gkview,true);
gkview.Delegate = new gkviewdelegate();
}
Related
I'm trying to get the active tab's page information to be displayed in a popover. I'm able to get it to show the URL or Title of the page currently, but it requires opening and closing the extension popover twice.
I believe it's because to get that information, the below code relies on completionHandler which makes it async.
SFSafariApplication.getActiveWindow { (window) in
window?.getActiveTab { (tab) in
tab?.getActivePage(completionHandler: { (page) in
page?.getPropertiesWithCompletionHandler( { (properties) in
self.pageTitle = properties?.title ?? "Unknown"
self.ActivePageTitle.stringValue = self.pageTitle
})
})
}
}
The first time you open the popover it shows a blank text region, but the second time it will have loaded in the information before and shows it correctly.
I've tried running it in viewDidLoad() but that only fires the first time the popover is opened.
When running it in viewWillAppear() I get the below error:
pid(17738)/euid(501) is calling TIS/TSM in non-main thread environment,
ERROR : This is NOT allowed. Please call TIS/TSM in main thread!!!
I thought maybe switching the extension to use a command instead would work but then realized you can't programatically open the popover window.
Do I have to switch to UITableView or something that has a reloadData() function to run once the async request for data is complete?
MacOS 10.14.4 | Safari 12.1 | Xcode 10.2
Try updating your UI code on the main thread. Wrap the page title updates in DispatchQueue. I had almost the exact same issue, and this worked for me.
SFSafariApplication.getActiveWindow { (window) in
window?.getActiveTab { (tab) in
tab?.getActivePage(completionHandler: { (page) in
page?.getPropertiesWithCompletionHandler( { (properties) in
DispatchQueue.main.async {
self.pageTitle = properties?.title ?? "Unknown"
self.ActivePageTitle.stringValue = self.pageTitle
}
})
})
}
}
To give proper credit, I found the answer while digging through this code on GitHub (check out the updateDataLabels() method):
https://github.com/otzbergnet/tabCount/blob/master/tabCount%20Extension/SafariExtensionViewController.swift
You can get SFSafariPageProperties object in SafariExtensionHandler and use this object in SafariExtensionViewController.
- (void)popoverWillShowInWindow:(SFSafariWindow *)window {
[window getActiveTabWithCompletionHandler:^(SFSafariTab *activeTab) {
[activeTab getActivePageWithCompletionHandler:^(SFSafariPage *page) {
[page getPagePropertiesWithCompletionHandler:^(SFSafariPageProperties *properties) {
// Now you can use "properties" in viewController using shareObject
}];
}];
}];
}
Now need to get properties of SFSafariPage again in viewWillAppear.
I want to present a view Controller after the user Authenticates with Touch ID, here is my code and the error i am getting, I have no idea how to solve it
and the console Shows
Looks like you need to access main thread.try this.
For Swift 2.3
dispatch_async(dispatch_get_main_queue()) {
//place your code to push viewController
}
For Swift 3
DispatchQueue.main.async {
//place your code to push viewController
}
I'm doing some MonoTouch development, and I really can't figure out an problem I've run into
I'm having an ViewController containing a UIButton. I have added a delegate to the TouchDown event of this button. In this delegate I'm calling a WebService and trying to change the colour and title of the button. However nothing happens to the button before the entire delegate have been executed. The thing is that the webservice is rather slow, so I want to give the users a waiting message by changing the colour and title of the button.
The code:
public override void ViewDidLoad ()
{
View.BackgroundColor = UIColor.Black;
bookButton = new UIButton( new RectangleF(10,100,this.View.Frame.Width-10 ,40) );
bookButton.BackgroundColor = UIColor.Clear;
setButton();
bookButton.TouchDown += delegate {
gymClass.book();
setButton();
tableView.ReloadData();
NavigationController.PopViewControllerAnimated( true );
};
this.View.AddSubview( bookButton );
}
Anyone, please?
The delegate is executed on the main thread which is responsible for rendering, so you are blocking the renderer until you return.
I want to open a document on my iphone app written in monotouch
- i.e. launch a PDF file in the default PDF viewer.
I think I should be using UIDocumentInterationController?
Anyone have any Ideas on this..
I have put together the following on a viewcontroller ( with a toolbar)
but it doesnt work :-( It does nothing!!
string s = string.Format("{0}",strFilePath);
NSUrl ns = NSUrl.FromFilename (s);
UIDocumentInteractionController PreviewController =
UIDocumentInteractionController.FromUrl(ns);
PreviewController.Delegate = new UIDocumentInteractionControllerDelegateClass();
PreviewController.PresentOpenInMenu(btnOpen,true);
public class UIDocumentInteractionControllerDelegateClass : UIDocumentInteractionControllerDelegate
{
public UIViewController FileViewController = new UIViewController();
public UIDocumentInteractionControllerDelegateClass ()
{
}
public override UIViewController ViewControllerForPreview (UIDocumentInteractionController controller)
{
return FileViewController;
}
public override UIView ViewForPreview (UIDocumentInteractionController controller)
{
return FileViewController.View;
}
}
First thing I would try, is ensuring when you present the options menu, that it is taking place on the main thread:
InvokeOnMainThread(delegate{
PreviewController.PresentOpenInMenu(btnOpen,true);
});
If that alone doesn't work, another thing I noticed is that you're creating a new view controller in the delegate class. It doesn't appear to be added to the stack anywhere in your code, so maybe thats why it's not showing. Code I've used is as follows:
PreviewController.Delegate = new UIDocumentInteractionControllerDelegateClass(this);
...
...
public class UIDocumentInteractionControllerDelegateClass : UIDocumentInteractionControllerDelegate
{
UIViewController viewC;
public UIDocumentInteractionControllerDelegateClass(UIViewController controller)
{
viewC = controller;
}
public override UIViewController ViewControllerForPreview (UIDocumentInteractionController controller)
{
return viewC;
}
public override UIView ViewForPreview (UIDocumentInteractionController controller)
{
return viewC.View;
}
public override RectangleF RectangleForPreview (UIDocumentInteractionController controller)
{
return viewC.View.Frame;
}
}
This will then use the current viewcontroller to present the preview in. The only other change I can think of using is rather than presenting from a UIBarButtonItem try:
PreviewController.PresentOpenInMenu(new RectangleF(320,320,0,500), this.View, true);
I hope this helps!
I'm a newbie. I can't figure out how and where to call ResignFirstResponder to get rid of the keyboard when the user finished entering the text in an UITextField. I'm a bit confused by the UIResponder class. Mono documentation says: "To dismiss the keyboard, send the UIResponder.ResignFirstResponder message to the text field that is currently the first responder." How to do so? Can someone post a simple working example? There are many examples in Obj-C but none in C#. Many thanks.
Here's an example I've done recently:
private UITextField _textField;
public override void ViewDidLoad()
{
_textField = new UITextField();
_textField.Text = "King Alfonso III";
_textField.Bounds = bounds;
_textField.Placeholder = "Username";
_textField.ShouldReturn = delegate
{
_textField.ResignFirstResponder();
return true;
};
View.AddSubview(_textField);
}
Also if you are submitted a form with a button, make sure you resign all the textfields in the button click, to avoid getting responder errors.
public void ButtonClick(object sender, EventArgs e)
{
_textField.ResignFirstResponder();
// All other textboxes
// Other button logic
}