【问题标题】:Navigate to a UIViewController from a UIAlertView in Swift 2.3从 Swift 2.3 中的 UIAlertView 导航到 UIViewController
【发布时间】:2017-04-05 19:28:17
【问题描述】:

我是 Swift 和 iOS 开发的新手。我一直在尝试为互联网连接创建一个应用程序范围的检查,允许用户重试(重新加载当前视图)。下面的checkInternetConnection() 函数在我的BaseUIViewController 类中的viewWillAppear() 期间被调用。

Reachability.isConnectedToNetwork() 连接检查工作正常。但到目前为止,我还没有找到一种在用户按下警报中的“重试”按钮后重新加载当前视图的方法。事实上,我还没有找到在任何情况下重新加载当前视图的方法。

我知道我在下面的尝试中做错了(因为有一个编译错误告诉我),是我在这一行传递了一个 UIViewController 对象而不是 string 作为参数: self.performSegueWithIdentifier(activeViewController, sender:self),但我怀疑这不是我唯一的错误。

func checkInternetConnection() {
    if (Reachability.isConnectedToNetwork()) {
    print("Internet connection OK")
} else {
    print("Internet connection FAILED")
    let alert = UIAlertController(title: NSLocalizedString("Error!", comment: "Connect: error"), message: NSLocalizedString("Could not connect", comment: "Connect: error message"), preferredStyle: UIAlertControllerStyle.Alert)
    alert.addAction(UIAlertAction(title: NSLocalizedString("Retry", comment: "Connect: retry"), style: .Default, handler: { action in
        print("Connection: Retrying")
        let navigationController = UIApplication.sharedApplication().windows[0].rootViewController as! UINavigationController
        let activeViewController: UIViewController = navigationController.visibleViewController!
        self.performSegueWithIdentifier(activeViewController, sender:self)
    }))
    self.presentViewController(alert, animated: true, completion: nil)
    }
}

【问题讨论】:

  • 它的 performSegueWithIdentifier 不是 performSegueWithViewController 所以你必须使用 segue 的标识符(字符串)(你可以在故事板上设置它),或者你可以简单地使用 presentViewController 来呈现它。
  • 谢谢,但我不能在这里输入字符串值,因为我不知道用户在哪个视图上收到了警报(因此,我不知道当他们按“重试”)。它需要是动态的。
  • 然后根据你拥有的下一个 vc 创建一个动态字符串并放在那里...?
  • 调用 self.presentViewController(activeViewController, animated: true, completion: nil) 而不是 self.performSegueWithIdentifier(activeViewController, sender:self) 在运行时崩溃。
  • @Tj3n 我想试试,但我可能需要一个例子。

标签: ios swift uiviewcontroller segue uialertcontroller


【解决方案1】:

BaseUIViewController 可以执行应用范围内的连接检查,因此您的所有 ViewController 都将继承自 BaseUIViewController

并且每个 ViewController 在连接检查后会有不同的行为。

您可以做的一件事是,在您的BaseUIViewController 中,您可以定义一个在连接检查失败后执行操作的块。

示例如下:

class BaseViewUIController: UIViewController {

    var connectivityBlock: (() -> Void)?

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        checkInternetConnection()
    }


    func checkInternetConnection() {
        if Reachability.isConnectedToNetwork() {
            print("Internet connection OK")
        } else {
            if let b = connectivityBlock {
                b()
            }
        }
    }
}

在你继承的 ViewControllers 中:

class MyViewController: BaseUIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        connectivityBlock = {
            print("Do View Refresh Here.")
        }
    }
}

那么在BaseUIViewController中签入之后,connectivityBlock中的代码就会被执行,这样每个VC就可以不同的处理了。

您也可以在BaseUIViewController中定义一个函数,每个子类都会覆盖该函数,在连通性检查失败后,调用该函数。

【讨论】:

  • 感谢您的建议。我不确定每个 ViewController 需要不同的行为,但我想它不会受到伤害。但是,在我的testingViewController : BaseUIViewControllerconnectivityBlock() 的定义中,我收到编译错误无法将类型“testingViewController.Type”的值转换为预期的参数类型“UIViewController”。该定义包含单行:self.presentViewController(testingViewController, animated: false, completion: nil) 并直接写在super.viewDidLoad() 下方,如您的示例中所示
  • 所以简而言之,你的建议可能是合理的,但我原来的问题仍然存在。我需要重新加载当前的 ViewController。这应该在你写print("Do View Refresh Here.")的地方完成
  • 你是对的,你可以在块中重新加载你当前的 VC,就好像你在正常重新加载/刷新你的视图一样。
  • 对,如果我想重新加载整个当前的 VC,你能把它添加到你发布的代码中吗?
  • 抱歉,“重新加载整个当前 VC”我不太明白,您可以在代码块中重新加载 VC 的视图,即显示网络错误视图。
【解决方案2】:

尝试使用应用程序的窗口导航

let destinationVC  = UIApplication.shared.delegate?.window
destinationVC .present(activeViewController, animated: true, completion: nil)

【讨论】:

  • 几个问题...let destinationVC = UIApplication.shared.delegate?.window 给出编译错误 "Type 'UIApplication' has no member 'shared'"...这就是你的意思吗:@987654323 @?但是,destinationVC .present(activeViewController, animated: true, completion: nil) 给出编译错误 "Value of type 'UIWindows??'没有成员“在场””
  • 你用的是哪个swift版本?
  • 刚刚在标题中指定。斯威夫特 2.3
  • 和我在 swift 3.0 中的回答
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-19
  • 2012-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多