I am developing a custom keyboard using Swift. I want to get UIDeviceOrientationDidChangeNotification when Orientation changes; for that purpose, I am using:
NSNotificationCenter.defaultCenter().addObserver(self, selector: "changeOrientation:", name: UIDeviceOrientationDidChangeNotification, object: nil)
func changeOrientation(notification: NSNotification) { }
It works with a simple app, but doesn't work with custom keyboard extension.
To anyone new to Extensions
Select your extension target, Select 'play' it will ask you to chose an app to run. Select an appropriate app.
Then you are running with the debugger attached to your extension and can use breakpoints.
-Dan
What did you put in your changeOrientation function ?
Breakpoints aren't working for me in the keyboard swift file.
Related
Whenever the current page changes by scrolling the pdf view in PDFkit, apps can detect the change adding the observer with PDFViewPageChanged.
The related sample code is as below,
// Add page change observer
NotificationCenter.default.addObserver(self,
selector: #selector(pageDidChange(notification:)),
name: Notification.Name.PDFViewPageChanged,
object: nil)
#objc private func pageDidChange(notification: Notification) {
// pdfView is of type PDFView
let currentPageNumber = pdfView.document?.index(for: pdfView.currentPage!)
}
From
How to know when user swipes to next page in PDFView of PDFKit?
PDFViewPageChanged works well in iOS 15.0 and before.
However, in case of iOS 15.2 and 15.4 (or later, latest)a function bound to PDFViewPageChanged is not called when the page changes.
I googled tons of pages to solve it. I couldn't find any solution or hints.
Please help me.
It's a very essential and fundamental function. So it's very strange.
Apple iOS PDFKit's PDFViewPageChanged notification was not delivered because a scrollview was added on the pdfview and the methods of the scrollview's delegate were overrode.
Before iOS 15.2, even though methods of the delegate were overrode, PDFKit's observer worked correctly.
However, since 15.2, in this case, the observer does not work well.
I removed the added scollview and added gesture recognizers instead to handle some events like tapping and panning.
In my viewDidLoad, I add code to follow UIApplication.didBecomeActive notification as follows:
NotificationCenter.default.addObserver(self,
selector: #selector(ViewController.applicationDidBecomeActive),
name: UIApplication.didBecomeActiveNotification,
object: UIApplication.shared)
The question is whether it is a given that once the notification is subscribed in viewDidLoad, the notification callback will not fire before viewDidLayoutSubviews() is called? It so happens on all my iOS devices across all iOS versions but it seems to be the source of bug if this is not true. Trying to figure out sources of all unreproducible bugs, not sure if this can be one of them.
I am having a weird issue with a SpriteKit game. The app crashes when a user opens Notification center or Control Center. I want the worldNode layer to be paused and the menuNode layer to be presented when the applicationWillResignActive is called, which is working fine when the home button is pressed. I've tried pausing my game from within the AppDelegate functions applicationWillResignActive and I've tried pausing when applicationDidBecomeActive is called if the game has started. I've tried using the NotificationCenter approach from within the ViewController both work when the Home Button/Home Gesture is used. How Should I handle this? Or is this just a bug in iOS 11?
I have this in the viewDidLoad method of my ViewController
NotificationCenter.default.addObserver(self, selector: #selector(appWillResignActive), name: NSNotification.Name.UIApplicationWillResignActive, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(appDidBecomeActive), name: NSNotification.Name.UIApplicationDidBecomeActive, object: nil)
Then each one of those selectors
It crashes on both if trying to present the menu when the appDidBecomeActive and appWillResignActive
#objc func appDidBecomeActive() {
print("appDidBecomeActive")
if GameScene.sharedInstance != nil {
print("presentingMenu")
GameScene.sharedInstance.presentMenuNode()
}
}
#objc func appWillResignActive() {
print("appWillResignActive")
if GameScene.sharedInstance != nil {
print("presentingMenu")
GameScene.sharedInstance.presentMenuNode()
}
}
I feel like I may be trying to approach this the wrong way, but what I don't understand is why does it work when the Home button/Home gesture is fired?
Edit:
After more testing I found that everything works as expected when running on iOS 10 devices. However when I run the DemoBots app that apple provides from their sample code it doesn't crash on iOS 11 and basically does what I want to do, so there has got to be a better way to handle the transitions of the game state, any input is appreciated.
First I had a UIViewController listenning for the UIKeyboardWillShow notification to adjust the screen for the keyboard. But every time I changed to emoji keyboard, the notification wasn't called.
So, I changed to UIKeyboardWillChangeFrame notification like this
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardChanged(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
It seems to work fine if I just change to emoji by tapping keyboard type.
However, if I press and hold keyboard type to select (my keyboard have more than one language) and select the emoji keyboard, the notification is not fired.
Anyone had something like this before? Any suggestions?
This is a bug in iOS 11, but there is a hacky temporary solution:
You can listen language mode changes:
NotificationCenter.default.addObserver(self, selector: #selector(inputModeDidChange(_:)), name: .UITextInputCurrentInputModeDidChange, object: nil)
And check for emoji:
if([[UITextInputMode currentInputMode].primaryLanguage isEqualToString:#"emoji"]) // layout again
It's quite a simple issue. In my view controller I'm registering for a 'foreground' notification:
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(MyViewController.applicationDidEnterForeground(_:)),
name: UIApplicationWillEnterForegroundNotification, object: nil)
}
func applicationDidEnterForeground(notification: NSNotification) {
print("I'm not going crazy")
}
What I'd Expect
After foregrounding the app, the print statement should be executed and printed to the console.
But...
This never happens. I'm an experienced iOS developer, and I've been trying for an hour or so.
What on earth could I have missed? Is this working for other people? Have tried:
Different values for object, (self, nil,
UIApplication.sharedApplication())
Registering for UIApplicationDidEnterBackgroundNotification - which works fine
Restarting Xcode, Simulator
Running on a device and on the simulator
Cleaning the build folder
It looks like an extension on UIViewController was calling
NSNotificationCenter.defaultCenter().removeObserver(self)
at will, with no regard to any subclass. Not so helpful, and pretty hard to find since extensions could be somewhere completely unrelated to whatever it is you're working on, and not necessarily even part of the view controller's class heirachy.
If you're writing an extension... keep this is mind!!!