Don't obscure "Unlock" button with keyboard

// FREEBIE
This commit is contained in:
Michael Kirk 2018-03-29 22:44:37 -04:00
parent 4890fe6303
commit 4eadd84abc
3 changed files with 47 additions and 0 deletions

View file

@ -323,6 +323,7 @@
45A6DAD61EBBF85500893231 /* ReminderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45A6DAD51EBBF85500893231 /* ReminderView.swift */; };
45AE48511E0732D6004D96C2 /* TurnServerInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45AE48501E0732D6004D96C2 /* TurnServerInfo.swift */; };
45B27B862037FFB400A539DF /* DebugUIFileBrowser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45B27B852037FFB400A539DF /* DebugUIFileBrowser.swift */; };
45B5360E206DD8BB00D61655 /* UIResponder+OWS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45B5360D206DD8BB00D61655 /* UIResponder+OWS.swift */; };
45B74A742044AAB600CD42F8 /* aurora-quiet.aifc in Resources */ = {isa = PBXBuildFile; fileRef = 45B74A5B2044AAB300CD42F8 /* aurora-quiet.aifc */; };
45B74A752044AAB600CD42F8 /* synth-quiet.aifc in Resources */ = {isa = PBXBuildFile; fileRef = 45B74A5C2044AAB300CD42F8 /* synth-quiet.aifc */; };
45B74A762044AAB600CD42F8 /* keys-quiet.aifc in Resources */ = {isa = PBXBuildFile; fileRef = 45B74A5D2044AAB400CD42F8 /* keys-quiet.aifc */; };
@ -925,6 +926,7 @@
45AE48501E0732D6004D96C2 /* TurnServerInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TurnServerInfo.swift; sourceTree = "<group>"; };
45B201741DAECBFD00C461E0 /* Signal-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Signal-Bridging-Header.h"; sourceTree = "<group>"; };
45B27B852037FFB400A539DF /* DebugUIFileBrowser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugUIFileBrowser.swift; sourceTree = "<group>"; };
45B5360D206DD8BB00D61655 /* UIResponder+OWS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "UIResponder+OWS.swift"; path = "util/UI Categories/UIResponder+OWS.swift"; sourceTree = "<group>"; };
45B74A5B2044AAB300CD42F8 /* aurora-quiet.aifc */ = {isa = PBXFileReference; lastKnownFileType = file; path = "aurora-quiet.aifc"; sourceTree = "<group>"; };
45B74A5C2044AAB300CD42F8 /* synth-quiet.aifc */ = {isa = PBXFileReference; lastKnownFileType = file; path = "synth-quiet.aifc"; sourceTree = "<group>"; };
45B74A5D2044AAB400CD42F8 /* keys-quiet.aifc */ = {isa = PBXFileReference; lastKnownFileType = file; path = "keys-quiet.aifc"; sourceTree = "<group>"; };
@ -2247,6 +2249,7 @@
45C0DC1D1E69011F00E04C47 /* UIStoryboard+OWS.swift */,
EF764C331DB67CC5000D9A87 /* UIViewController+Permissions.h */,
EF764C341DB67CC5000D9A87 /* UIViewController+Permissions.m */,
45B5360D206DD8BB00D61655 /* UIResponder+OWS.swift */,
);
name = "UI Categories";
path = ..;
@ -3197,6 +3200,7 @@
34B3F8821E8DF1700035BE1A /* NewContactThreadViewController.m in Sources */,
45D308AD2049A439000189E4 /* PinEntryView.m in Sources */,
340FC8B1204DAC8D007AEB0F /* BlockListViewController.m in Sources */,
45B5360E206DD8BB00D61655 /* UIResponder+OWS.swift in Sources */,
45F659821E1BE77000444429 /* NonCallKitCallUIAdaptee.swift in Sources */,
45AE48511E0732D6004D96C2 /* TurnServerInfo.swift in Sources */,
34B3F8771E8DF1700035BE1A /* ContactsPicker.swift in Sources */,

View file

@ -37,6 +37,9 @@ import LocalAuthentication
// Passcode-code only authentication process deactivates the app.
private var ignoreUnlockUntilActive = false
// We temporarily resign any first responder while the Screen Lock is presented.
var firstResponderBeforeLockscreen: UIResponder?
// MARK - Singleton class
@objc(sharedManager)
@ -169,6 +172,13 @@ import LocalAuthentication
return
}
// A popped keyboard breaks our layout and obscures the unlock button.
if let firstResponder = UIResponder.currentFirstResponder() {
Logger.debug("\(self.logTag) in \(#function) resigning first responder: \(firstResponder)")
firstResponder.resignFirstResponder()
self.firstResponderBeforeLockscreen = firstResponder
}
tryToVerifyLocalAuthentication(localizedReason: NSLocalizedString("SCREEN_LOCK_REASON_UNLOCK_SCREEN_LOCK",
comment: "Description of how and why Signal iOS uses Touch ID/Face ID/Phone Passcode to unlock 'screen lock'."),
completion: { (outcome: OWSScreenLockOutcome) in
@ -180,6 +190,16 @@ import LocalAuthentication
case .unexpectedFailure(let error):
unexpectedFailure(self.authenticationError(errorDescription: error))
case .success:
// It's important we restore first responder status once the user completes
// In some cases, (RegistrationLock Reminder) it just puts the keyboard back where
// the user needs it, saving them a tap.
// But in the case of an inputAccessoryView, like the ConversationViewController,
// failing to restore firstResponder could make the input toolbar disappear until
if let firstResponder = self.firstResponderBeforeLockscreen {
Logger.debug("\(self.logTag) in \(#function) regaining first responder: \(firstResponder)")
firstResponder.becomeFirstResponder()
self.firstResponderBeforeLockscreen = nil
}
success()
case .cancel:
cancel()

View file

@ -0,0 +1,23 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
// Based on https://stackoverflow.com/questions/1823317/get-the-current-first-responder-without-using-a-private-api/11768282#11768282
extension UIResponder {
private weak static var firstResponder: UIResponder?
public class func currentFirstResponder() -> UIResponder? {
firstResponder = nil
// If target (`to:`) is nil, the app sends the message to the first responder,
// from whence it progresses up the responder chain until it is handled.
UIApplication.shared.sendAction(#selector(setSelfAsFirstResponder(sender:)), to: nil, from: nil, for: nil)
return firstResponder
}
@objc
private func setSelfAsFirstResponder(sender: AnyObject) {
UIResponder.firstResponder = self
}
}