Swift 视图控制器未显示,因为另一个显示的视图尚未完成。

Swift 视图控制器未显示,因为另一个显示的视图尚未完成。,swift,ios11,dismiss,unwind-segue,xcode9,Swift,Ios11,Dismiss,Unwind Segue,Xcode9,这是我的第一个问题,希望不要太愚蠢 这是我的应用程序: VC1 VC2-ChatTableViewController VC3-PopupPhotoSourceVC VC1-以模式显示VC2的按钮 VC2-一个条形按钮,用于将VC3演示模式设置为过流上下文,以显示VC3 VC2-设置展开顺序 VC3-中间的两个按钮,都设置为“通过使用故事板进行拖放和选择来展开序列” 在VC3内部,使用prepare for segue让VC2知道用户选择的内容 override func prepare(for

这是我的第一个问题,希望不要太愚蠢

这是我的应用程序: VC1 VC2-ChatTableViewController VC3-PopupPhotoSourceVC

VC1-以模式显示VC2的按钮 VC2-一个条形按钮,用于将VC3演示模式设置为过流上下文,以显示VC3 VC2-设置展开顺序

VC3-中间的两个按钮,都设置为“通过使用故事板进行拖放和选择来展开序列”

在VC3内部,使用prepare for segue让VC2知道用户选择的内容

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    let destChatViewController = segue.destination as! ChatTableViewController


    if segue.identifier == "library" // library Button
    {
        print("set cameraType to library from popupviewcontroller")
        let time = getCurrentTime()
        print("==== timer start ====== \(time.3):\(time.4):\(time.5)")

        destChatViewController.cameraType = "library"
    }
    else if segue.identifier == "newphoto" // newphoto Button
    {
        print("set cameraType to newphoto from popupviewcontroller")
        let time = getCurrentTime()
        print("==== timer start ====== \(time.3):\(time.4):\(time.5)")

        destChatViewController.cameraType = "newphoto"
    }

    // for unwind segue, no need to call dismiss
    print("not calling dismiss pop up")
    let time = getCurrentTime()
    print("==== timer start ====== \(time.3):\(time.4):\(time.5)")

    //dismiss(animated: true, completion: nil)
}
在VC2内部,attachPhotoButtonFinish将根据用户的选择尝试调用图像选择器控制器

func attachPhotoButtonFinish() {

    print("attachphotobutton start")
    let time = getCurrentTime()
    print("==== timer start ====== \(time.3):\(time.4):\(time.5)")


    let image = UIImagePickerController()
    image.delegate = self

    if cameraType == "library"{
        image.sourceType = UIImagePickerControllerSourceType.photoLibrary

    }
    else if cameraType == "newphoto"{
        image.sourceType = UIImagePickerControllerSourceType.camera
        image.cameraCaptureMode = .photo
    }
    else{
        print("Something wrong!!!")
        return
    }
    image.allowsEditing = false
    image.modalPresentationStyle = .overCurrentContext

    print("calling imagepicker")
    let time1 = getCurrentTime()
    print("==== timer start ====== \(time1.3):\(time1.4):\(time1.5)")

    self.present(image, animated: true, completion: nil)
}
我还尝试打印VC3的脱墨时间

deinit{
    print("===== \(self.classForCoder.description()) be deinit")
    let time = getCurrentTime()
    print("==== timer start ====== \(time.3):\(time.4):\(time.5)")

}
关于运行结果,有时十分之一的VC3在VC2显示图像选择器之前完成。所以我可以正确地看到它的显示

====计时器启动===18:34:58 不调用弹出窗口 ====计时器启动===18:34:58 展开到ChatTableViewController cameraType=库 ====计时器启动===18:34:58 附件照片按钮启动 ====计时器启动===18:34:58 调用图像选择器 ====计时器启动===18:34:58 ====PhotoStreamSourceTest.popupHotosourcevc被删除 ====计时器启动===18:34:59 2017-09-20 18:34:59.274464+0800 PhotoStreamSourceTest[14690:399530][AXRun PID]请求PID的客户端:14706名称: 2017-09-20 18:34:59.283271+0800 PhotoStreamSourceTest[14690:399463][MC]systemgroup.com.apple.configurationprofiles的系统组容器路径为/Users/uu/Library/Developer/CoreSimulator/Devices/54B3F249-2C6A-4C18-B2E1-c72711997cf/data/Containers/Shared/systemgroup/systemgroup.com.apple.configurationprofiles 2017-09-20 18:34:59.284012+0800 PhotoStreamSourceTest[14690:399463][MC]从私人有效用户设置读取

但大多数时候,我收到以下结果,图像选择器不显示

====计时器启动===18:35:48 不调用弹出窗口 ====计时器启动===18:35:48 展开到ChatTableViewController cameraType=库 ====计时器启动===18:35:48 附件照片按钮启动 ====计时器启动===18:35:48 调用图像选择器 ====计时器启动===18:35:48 2017-09-20 18:35:48.967515+0800 PhotoStreamSourceTest[14690:400836][AXRun PID]请求PID的客户端:14706名称: 2017-09-20 18:35:49.049357+0800 PhotoStreamSourceTest[14690:399463]警告:在演示过程中尝试在上演示! ====PhotoStreamSourceTest.popupHotosourcevc被删除 ====计时器启动===18:35:49


谢谢大家!

感谢@chirag90的链接

关键的一点是,在让VC2启动图像选择器之前,使用DISCLISE方法的完成块来确保VC3真正关闭

以下解决方案使用委托而不是展开序列。如果有人有其他方法,请让我知道!谢谢大家!

首先,在VC3上,从情节提要中删除两个按钮上的展开序列。然后在称为libraryButtonPressed和takePhotoButtonPressed的两个按钮上添加iAction

在VC3:PopupPhotoSourceVC上,添加一个协议

protocol PopupPhotoSourceVCDelegate {
func finishPassing(string: String)}
在VC3上还添加该类型的委托变量

var delegate: PopupPhotoSourceVCDelegate?
现在在VC2上,采用协议

class ChatTableViewController: UITableViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate, PopupPhotoSourceVCDelegate{
func finishPassing(string: String) {
    cameraType = string
    attachPhotoButtonFinish()
}
并实现finishPassing功能以遵守协议

class ChatTableViewController: UITableViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate, PopupPhotoSourceVCDelegate{
func finishPassing(string: String) {
    cameraType = string
    attachPhotoButtonFinish()
}
不要忘记将委托设置为self

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let destination = segue.destination as? PopupPhotoSourceVC{
        destination.delegate = self
    }
}
现在,回到VC3,让我们实现关键方法

@IBAction func libraryButtonPressed(_ sender: UIButton) {
    dismiss(animated: true) {
        self.delegate?.finishPassing(string: "library")
    }

}
@IBAction func takePhotoButtonPressed(_ sender: UIButton) {
    dismiss(animated: true) {
        self.delegate?.finishPassing(string: "newphoto")
    }
}
这两种方法将关闭VC3:popupHotosourcevc,在关闭实际完成后,在VC2:ChatTableViewController中调用finishPassing以启动图像选择器


希望能对您有所帮助,谢谢。

看看这个@chirag90谢谢您的及时回复。我只是想知道unwind segue是否适合这种情况。在打电话给图像选择器之前一定要确保VC3已经关闭。对不起,伙计,我只是帮你警告一下