退出 UIViewController 时禁用“保存密码”操作表?

Posted

技术标签:

【中文标题】退出 UIViewController 时禁用“保存密码”操作表?【英文标题】:Disable "Save Password" action sheet when exiting UIViewController? 【发布时间】:2020-07-03 08:58:51 【问题描述】:

我的应用有一个“创建帐户”视图控制器(如下所示),提示用户输入用户名和密码。每当我转到另一个视图控制器时,我都会弹出一个操作表,提示将密码保存在钥匙串中。

如果用户成功创建新帐户,这是一个漂亮的小免费赠品。但是,如果用户点击导航栏中的取消(后退)按钮,如果他们选择使用 Facebook 登录而不是创建帐户的选项,或者离开此视图控制器的任何其他方式(见图下面)。

如何让此弹出窗口仅在用户成功创建新帐户时显示?

编辑:根据请求,这里是与导致“保存密码”操作表出现的 segues 相关的代码。

来自CreateAccountViewController.swift

class CreateAccountViewController : UIViewController

  // ... bunch of irrelevant code deleted ...

  // bound to "Connect with Facebook" button (see image below)
  @IBAction func switchToFacebook(_ sender : UIButton)
  
    performSegue(.SwitchToFacebookLogin, sender: sender)
  
  // ... bunch of irrelevant code deleted ...


extension CreateAccountViewController : GameServerAlertObserver

  // callback based on response from GameCenter after 
  //  submitting a "create new user" request
  func handleConnectionResponse(_ response:GameServerResponse )
  
    switch response
    
    // ... other response cases removed ...
    case .UserCreated:
      self.removeSpinner()
      performSegue(.CreateAccountToStartup, sender: self)

    default:
      response.displayAlert(over: self, observer: self)
      self.removeSpinner()
    
  

  // Functions defined in the GameServerAlertObserver protocol
  //   to handle user response to "User Exists Popup" (figure below)    
  func ok()
  
    // user chose to enter new  password... clear the existing username field
    usernameTextField.text = ""
  

  func cancel()
  
    // segue back to the startup view controller
    performSegue(.CreateAccountToStartup, sender: self)
  

  func goToLogin()
  
    // segue to the login view controller
    performSegue(.SwitchToAccountLogin, sender:self)
  

来自UIViewController_Segues

enum SegueIdentifier : String

  case LoserBoard             = "loserBoard"
  case CreateAccount          = "createAccount"
  case AccountLogin           = "accountLogin"
  case FacebookLogin          = "facebookLogin"
  case SwitchToFacebookLogin  = "switchToFacebookLogin"
  case SwitchToAccountLogin   = "switchToAccountLogin"
  case CreateAccountToStartup = "createAccountToStartup"
  case AccountLoginToStartup  = "accountLoginToStartup"
  case FacebookLoginToStartup = "facebookLoginToStartup"
  case UnwindToStartup        = "unwindToStartup"


extension UIViewController
 
  func performSegue(_ target:SegueIdentifier, sender:Any?)
  
    performSegue(withIdentifier: target.rawValue, sender: sender)
  

来自GameServerAlert.swift

protocol GameServerAlertObserver

  func ok()
  func cancel()
  func goToLogin()


extension GameServerResponse

  func displayAlert(over controller:UIViewController, observer:GameServerAlertObserver? = nil)
  
    var title   : String
    var message : String
    var actions : [UIAlertAction]

    switch self
    
    // ... deleted cases/default which don't lead to segue ...

    case .UserAlreadyExists:
      title = "User already exists"
      message = "\nIf this is you, please use the login page to reconnect.\n\nIf this is not you, you will need to select a different username."
      actions = [
        UIAlertAction(title: "Go to Login page",   style: .default, handler:  _ in observer?.goToLogin()  ),
        UIAlertAction(title: "Enter new username", style: .default, handler:  _ in observer?.ok()  ),
        UIAlertAction(title: "Cancel",             style: .cancel,  handler:  _ in observer?.cancel()  )
      ]
    

    let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
    actions.forEach  (action) in alert.addAction(action) 
    controller.present(alert,animated:true)
  

模拟器示例:

创建帐户 - (用户在此处输入新帐户的用户名和密码。)

Facebook 登录

如果用户决定使用 Facebook 登录而不是创建用户帐户,他们会被带到这个视图(我还没有充实)。请注意,“保存密码”操作表已弹出。

用户存在弹出窗口

如果用户尝试使用已存在的用户名创建帐户,他们将看到此弹出窗口。如果他们选择取消,他们将返回到启动屏幕(见下文)。如果他们选择输入新用户名,他们将保持在同一个屏幕上,用户名会被清除。如果他们选择登录,他们将被带到登录屏幕。

启动屏幕

如果用户在上面选择取消,他们会被带回到这里。再次注意,“保存密码”操作表已弹出。

【问题讨论】:

你找到解决办法了吗? 我最终重构了我的设计以解决这个问题......我从未真正解决它。但是......我相信 mitch10e 的回应(如下)可能是实际修复的关键。稍后我将在我的代码的早期版本中检查它。 【参考方案1】:

当用户:

关闭登录视图控制器; 弹出视图控制器; 使用交互式弹出手势。

=>

  override func viewWillAppear(_ animated: Bool) 
    super.viewWillAppear(animated)
      passwordTextField.textContentType = .password
    
  

  override func viewWillDisappear(_ animated: Bool) 
    super.viewWillDisappear(animated)
    if isMovingFromParent || isBeingDismissed || parent?.isBeingDismissed == true 
      passwordTextField.textContentType = nil
    
  

【讨论】:

我还必须清除 passwordTextField 文本才能完成这项工作。所以将passwordTextField.text = nil 添加到viewWillDisappear 另外,请确保仅在您不希望系统显示“保存密码”选项时执行此操作。如果用户确实更新了他们的凭据,则不应执行 viewWillDisappear 的内容。【参考方案2】:

对于简短的回答,我很抱歉,我通常不会在这个网站上发帖。这是创建用户屏幕关闭时在您的设备上发生的密码自动填充。

Apple 文档:https://developer.apple.com/documentation/security/password_autofill

这是一个很好地满足所有要求的网站的链接:https://developerinsider.co/ios12-password-autofill-automatic-strong-password-and-security-code-autofill/

【讨论】:

谢谢。为了规避这个问题,我最终对我的设计进行了显着更改。但是,我一定会查看您提供的链接,看看是否可以解决我的问题。 在第二个链接的大约 3/4 处,我找到了显示自动保存弹出窗口所需的条件。看起来如果我在关闭登录视图之前清除了密码字段,弹出窗口将不符合条件,并且不会显示自动保存弹出窗口。我现在要赞成这个答案。稍后,我将看看是否可以从 git 中恢复旧版本并进行测试。如果它成功了,我会将此标记为答案。谢谢。【参考方案3】:

在运行显示操作表的代码块之前添加一个条件。您可以使用if 语句简单地做到这一点。该语句必须检查帐户是否已成功创建。显示操作表的代码块必须仅在条件为真时运行。

【讨论】:

我没有明确显示操作表。在远离“创建帐户”视图控制器之后,它神奇地呈现了自己。它一定来自 UIKit 中的某个地方......但我找不到任何关于它的文档。 如果您可以在您的问题中分享相关代码,我们可以一起调查。不看代码不容易弄清楚原因。 在这种情况下,您会考虑哪些相关代码?我的问题的本质是,当我从“创建帐户”VC 切换到任何其他 VC 时,触发“保存密码”操作表的原因是什么。我添加了启动 segue 的代码,但我没有看看这会有什么帮助。

以上是关于退出 UIViewController 时禁用“保存密码”操作表?的主要内容,如果未能解决你的问题,请参考以下文章

删除子视图时如何修复触摸禁用?

我在用命令禁用驱动强制签名提示设置元素数据出错。该值受安全策略保

分析屏幕报告已禁用。 UIViewController 转换不会被记录

IOS。如何在每个 UIViewController 上启用和禁用旋转?

如何在 PyQt 应用程序退出时禁用清除剪贴板?

当应用程序在 iPhone 上退出活动时,计时器是不是会自动禁用?