Swift 4 Odd 意外跳回之前的故事板

Posted

技术标签:

【中文标题】Swift 4 Odd 意外跳回之前的故事板【英文标题】:Swift 4 Odd unexpected jump back to earlier storyboard 【发布时间】:2018-10-20 07:00:17 【问题描述】:

我是 Swift 和 Xcode 的新手,我构建了一个简单的两个故事板应用程序,它有一个欢迎屏幕和一个触发第二个故事板的按钮(为此我创建了自己的基于 UIVIewController 的类。第二个故事板有几个 UIPickerView 对象和几个 UIDatePickerView 对象和一个按钮。我在 didSelectRow 函数下有一些基本操作。但是,当我构建和运行应用程序时,我得到一个奇怪且看似随机的行为,在第一个选择器视图将我带回欢迎屏幕(展开序列?)。我没有输入任何代码来执行此操作!有什么想法吗?

import UIKit
class SecondViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource 
    @IBOutlet weak var cityPicker: UIPickerView!
    @IBOutlet weak var fromDatePicker: UIDatePicker!
    @IBOutlet weak var toDatePicker: UIDatePicker!
    @IBOutlet weak var nextThirdViewButton: UIButton!
    // temporay array for tsting - Populate with sqlite db extract
    var cityData = ["Please select city", "Beijing", "Calcutta", "Detroit", "Edinburgh", "Glasgow", "London", "Manchester", "New  York", "Rio de Janerio", "Washington"]
    // key variables and flags
    var cityPicked = false
    var fromTimePicked = false
    var toTimePicked = false
    var citySelected: String?
    var fromDate: Date?
    var toDate: Date?
    override func viewDidLoad() 
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        fromDatePicker.minimumDate = Date()
        toDatePicker.minimumDate = Date()
        fromDate = Date()
        nextThirdViewButton.layer.cornerRadius = 15
        nextThirdViewButton.layer.masksToBounds = true
        cityPicker.delegate = self
        cityPicker.dataSource = self
    
    //PickerView functions
    func numberOfComponents(in pickerView: UIPickerView) -> Int 
        return 1
    
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int 
        return cityData.count
    
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? 
        return cityData[row]
    
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) 
        //check user has selcted a city from pickerview and set flags accordingly
        if self.cityData[row] != "Please select city" 
            self.citySelected = self.cityData[row]
            self.cityPicked = true
         else 
            self.citySelected = "Please select city"
            self.cityPicked = false
        
    
    @IBAction func fromDatePicked(_ sender: Any) 
        fromDate = fromDatePicker.date
        if toTimePicked == true 
            checkDates(fromDate: fromDate!, toDate: toDate!)
        
        fromTimePicked = true
    
    @IBAction func toDatePicked(_ sender: Any) 
        toDate = toDatePicker.date
        checkDates(fromDate: fromDate!, toDate: toDate!)
    
    //Function to check if 'to date' is earlier than 'from date' and issue alert
    func checkDates (fromDate: Date, toDate: Date) 
        switch toDate.compare(fromDate) 
        case .orderedDescending:
            toTimePicked = true
        case .orderedAscending:
            presentAlert(title: "Date Alert", message: "You can't travel back in time!")
            toTimePicked = false
        default: return
        
    
    // Function to move to third storyboard
    @IBAction func nextThirdViewButton(_ sender: Any) 
        if !(cityPicked && fromTimePicked && toTimePicked) 
            presentAlert(title: "You're not ready yet", message: "Please complete choices")
         else 
            performSegue(withIdentifier: "thirdViewSeque", sender: nil)
        
    
    //reusable alert function
    func presentAlert(title: String, message: String) 
        let presentAlert = UIAlertController(title: title, message: message, preferredStyle: .alert)
        let dismissButton = UIAlertAction (title: "Dismiss", style: .cancel, handler: 
            (dateAlert: UIAlertAction) -> Void in
        )
        presentAlert.addAction(dismissButton)
        self.present(presentAlert, animated: true, completion: nil)
    

【问题讨论】:

感谢莫里茨的指导。标签已被编辑。 嗨,我已经缩小了上述问题的症状范围。当我将选择器视图更改一行时,它似乎只会触发意外行为。向上或向下移动两行不会导致问题,但在列表中向上或向下移动一项会导致问题。奇怪和任何关于我所做的事情的线索最受欢迎! 嗨,马特,很好的挑战和公平的观点 :-) 我显然做了一些愚蠢的事情(该死的新手!)。无论如何,经过多次努力,我设法将我的代码发布在主要问题区域。对于上下文,这是代码的第二个故事板由当前模态序列调用,用户按下欢迎屏幕上的开始按钮(第一个故事板)。目前第三个故事板只是一个空白的视图控制器。希望这有助于分析我做错了什么。干杯罗伯 对不起,应该澄清但我删除了我的原始项目并重新开始(简化设计)但问题仍然存在一个pickerview。基本上,当我登陆第二个故事板时,我从选择器视图中选择一个城市,并从日期选择器中选择两个日期(我访问的开始和结束)。如果我向后或向前移动超过一排的城市选择器,那似乎很好。但是,如果我只将城市更改一排(向前或向后),那么我的欢迎屏幕会以模态方式呈现,我必须点击开始才能回到第二个故事板。希望这是有道理的? 顺便说一句,我昨晚在想这种行为就像解雇一样,所以我注释掉了按钮的代码并添加了一个 self.dismiss 命令,构建了应用程序,当我点击按钮,我回到欢迎屏幕。因此,如果我只在选择器中移动一行,UI PickerView 似乎会以某种方式关闭第二个视图控制器。这有帮助吗? 【参考方案1】:

问题是您使用的是.partialCurl 呈现的视图控制器。不。您偶然发现了一个可怕的错误,即呈现的视图控制器有一个不可见区域,如果点击该区域,则会关闭视图控制器。

虽然最简单的解决方案是完全避免.partialCurl,但我有一个精心设计且非常老套的解决方法。这里是;将此代码放入您呈现的视图控制器中:

override func viewDidAppear(_ animated: Bool) 
    super.viewDidAppear(animated)
    // workaround for curl bug
    if let grs = self.view.gestureRecognizers 
        for g in grs 
            if NSStringFromClass(type(of:g)).hasSuffix("CurlUpTapGestureRecognizer") 
                g.isEnabled = false
            
        
    

【讨论】:

哇,干得好!很惭愧,因为我喜欢这种过渡,但我会改变为交叉溶解并接受它。那个讨厌的小虫子!非常感谢 - 这让我彻夜难眠:-) 好吧,我已经添加了我的 hacky 解决方法,所以试试看它是否能解决它。我也喜欢这种转变,所以我很同情。 非常感谢!我猜这个错误并不为人所知,因为我在谷歌上找不到任何东西。向 Apple 报告? 多年来我每年都报告它。在我的书中(这是解决方法的来源)大声呼唤它,所以这是我在为拯救人类而进行的永无止境的斗争中能做的最好的事情。 哈哈。好吧,你救了我 - 我今晚可以睡得更好 :-) 现在我可以梦想我的下一个故事板 :-)

以上是关于Swift 4 Odd 意外跳回之前的故事板的主要内容,如果未能解决你的问题,请参考以下文章

在故事板之间保持导航控制器(swift)

在 Swift 中连接多个故事板

你如何摆脱swift中主要故事板的代码?

Swift 4:将数据从集合视图单元传递到另一个没有故事板的视图控制器

故事板视觉继承

使用 Swift 故事板进行神经拟态设计