【问题标题】:AlertController view is not in the window hierarchyAlertController 视图不在窗口层次结构中
【发布时间】:2021-06-20 16:33:45
【问题描述】:

我是 swift 的初学者,我试图使用 UIAlertController 但我遇到了一个错误,UiAlertController 没有出现,我可以看到一个错误在控制台中显示

2021-06-20 18:16:28.494162+0200 Bicycall[50670:543648] [Presentation] Attempt to present <UIAlertController: 0x7fbaca034e00> on <Bicycall.login: 0x7fbabb01d800> (from <Bicycall.login: 0x7fbabb01d800>) whose view is not in the window hierarchy.
2021-06-20 18:16:28.494339+0200 Bicycall[50670:543648] [Presentation] Attempt to present <UIAlertController: 0x7fbac9862800> on <Bicycall.login: 0x7fbabb01d800> (from <Bicycall.login: 0x7fbabb01d800>) whose view is not in the window hierarchy.

这是我尝试过的:

import UIKit
import CoreData
import AVKit
import AVFoundation
import TKSubmitTransition

class login: UIViewController {

    
    @IBOutlet weak var passwordView: UIView!
    @IBOutlet weak var emailView: UIView!
    var id: Int?
    var name: String?
    var lastname: String?
    var email:String?
    var password:String?
    var phone:String?
    
    var u = ConnectedUser()
    var BR = BaseUrl.baseUrl
    
    var player: AVPlayer?
        let videoURL: NSURL = Bundle.main.url(forResource: "Bikers", withExtension: "mp4")! as NSURL
    
    


    func getTopMostViewController() -> UIViewController? {
        var topMostViewController = UIApplication.shared.keyWindow?.rootViewController

        while let presentedViewController = topMostViewController?.presentedViewController {
            topMostViewController = presentedViewController
        }

        return topMostViewController
    }

    
    
    func presentTestAlert(_ title: String, _ message: String){
        let alert = UIAlertController(title: title , message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: "Default action"), style: .default, handler: { _ in
        NSLog("The \"OK\" alert occured.")
        }))
        DispatchQueue.main.async {
            self.getTopMostViewController()?.present(alert, animated: true, completion: nil)
        }

    }
 
    override func viewDidLoad() {
        super.viewDidLoad()

        self.DeleteAllData()
        
        
        player = AVPlayer(url: videoURL as URL)
                player?.actionAtItemEnd = .none
                player?.isMuted = true
                
                let playerLayer = AVPlayerLayer(player: player)
                playerLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
                playerLayer.zPosition = -1
                playerLayer.frame = view.frame
                view.layer.addSublayer(playerLayer)
                player?.play()
                NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: self.player?.currentItem, queue: .main) { [weak self] _ in
                                    self?.player?.seek(to: CMTime.zero)
                                    self?.player?.play()
        
        
        // Do any additional setup after loading the view.
    }
        
        
                emailView.layer.cornerRadius = 30.0
                emailView.layer.borderWidth = 0.5
        emailView.layer.borderColor = UIColor.white.cgColor
                
                passwordView.layer.cornerRadius = 30.0
                passwordView.layer.borderWidth = 0.5
                passwordView.layer.borderColor = UIColor.white.cgColor
    }
    
    
    
    //widgets
    
    @IBOutlet weak var txtEmail: UITextField!
    
    
    @IBOutlet weak var txtPassword: UITextField!
    
    
    
    //Actions
    @IBAction func btnLogin(_ sender: Any){

         //get
       /*
        guard let url = URL(string: "http://localhost:3000/bikes") else {
        return
        }
        let session = URLSession.shared
        session.dataTask(with: url)  { ( data , response ,error) in
            if let response = response {
                print(response)
            }
            
            if let data = data {
                print(data)
                do
                {
                    let json = try JSONSerialization.jsonObject(with: data, options: [])
                    print(json)
                }catch{
                    print(error)
                }
            }
            
        }.resume()
        */
        
        //post
    
        guard let url = URL(string: BR+"/login") else {
        return
        }
        
        let bodyparameters = ["email": txtEmail.text, "password": txtPassword.text]
       
        if (txtEmail.text!.isEmpty || txtPassword.text!.isEmpty ){
            
            self.presentTestAlert("Wrong credentials","Email and Password must not be empty")
            
        }else{

            
            var request = URLRequest(url: url)
            request.httpMethod = "POST"
            request.addValue("application/json", forHTTPHeaderField: "Content-Type")
            guard let httpBody = try? JSONSerialization.data(withJSONObject: bodyparameters, options: []) else{
                return
                }
            request.httpBody = httpBody
            let session = URLSession.shared
            session.dataTask(with: request) { (data,response,error) in
                let status = (response as! HTTPURLResponse).statusCode
                //print(response)
                print(status)
                if let response = response {
                    let status = (response as! HTTPURLResponse).statusCode
                    //print(response)
                    print(status)
                }
                
                if((status) == 200){
                    self.presentTestAlert("Connection Success", " internet connection")
                    print(" Connection Successssssssssssssss")
                    
                    if let data = data {
                        do {
                            //let json = try JSONSerialization.jsonObject(with: data, options: [])
                           // print(json);
                            print(data)
                            let user = try JSONDecoder().decode(User.self, from: data)
                           
                            DispatchQueue.main.async {
                                
                                self.id = user.user_id
                                self.name = user.name
                                self.lastname = user.lastname
                                self.email = user.email
                                self.password = user.password
                                self.phone = user.phone
                                
                                print(self.id!)
                                print(self.email!)
                                
                                
                                if(user.user_id != 0){
                                   
                                    self.saveUser()
                                    self.DisplayConnectedUser()
                                   self.performSegue(withIdentifier: "HomeSegue", sender: "nil")
                                    
                                }else{
                                    self.presentTestAlert("Login Failed","Wrong credentials")
                                  
                                }
                            
                            }
                            
                        }catch{
                            print(error)
                        }
                        
                    }
                    
                }else {
                    self.presentTestAlert("No Connection", "No internet connection")
                    print(" Connection Nooooooooooooooooooooooooo")
                }
                
       
                
            }.resume()

            
            
        }
        
        
    }
    
    
    func DeleteAllData(){

        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        let managedContext = appDelegate.persistentContainer.viewContext
        let DelAllReqVar = NSBatchDeleteRequest(fetchRequest: NSFetchRequest<NSFetchRequestResult>(entityName: "Users"))
        do {
            try managedContext.execute(DelAllReqVar)
        }
        catch {
            print(error)
        }
    }

    

    func saveUser() {
        
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        //represente l'ORM
        let persistentContainer = appDelegate.persistentContainer
        let managedContext = persistentContainer.viewContext
        
        let entityDescription = NSEntityDescription.entity(forEntityName: "Users" ,  in: managedContext)
        let object = NSManagedObject(entity: entityDescription! , insertInto: managedContext )
        object.setValue(id!  ,  forKey: "user_id"  )
        object.setValue(email!  ,  forKey: "email"  )
        object.setValue(password!  ,  forKey: "password"  )
        object.setValue(name!  ,  forKey: "name"  )
        object.setValue(lastname!  ,  forKey: "lastname"  )
        object.setValue(phone!  ,  forKey: "phone"  )
        
                  do {
                  
                 try managedContext.save()
                   print("INSERT SUCCESSFULLY")
                print(id!)
                   }
                   catch  {
                   print("INSERT ERROR")
                   }
        
    }
    

    
    
    @IBAction func btnSignup(_ sender: Any) {
        performSegue(withIdentifier: "signupSegue", sender: "nil")
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
      
    }

    
    
    func DisplayConnectedUser() {
            
             let appDelegate = UIApplication.shared.delegate as! AppDelegate
                //represente l'ORM
                let persistentContainer = appDelegate.persistentContainer
                
                let managedContext = persistentContainer.viewContext     //retourne NSManagedObject toujours
                
                //la requete retourne un NSManagedObject
                let request = NSFetchRequest<NSManagedObject>(entityName :   "Users")
                
                //execution de la requete
                do {
                
                    let result = try  managedContext.fetch(request)
                for item in result {
                    print(item.value(forKey: "user_id") as! Int )
                    print(item.value(forKey: "email")  as! String)
                    self.u.user_id  = (item.value(forKey: "user_id")  as! Int)
                    self.u.email = (item.value(forKey: "email")  as! String)
                    self.u.password = (item.value(forKey: "password")  as! String)
                    self.u.name = (item.value(forKey: "name")  as! String)
                    self.u.lastname = (item.value(forKey: "lastname")  as! String)
                    self.u.phone = (item.value(forKey: "phone")  as! String)
                   
                    print(self.u.user_id!)
                    print(self.u.email!)
                    print(self.u.password!)
                    print(self.u.name!)
                    print(self.u.lastname!)
                    print(self.u.phone!)
                  
                }
                
                   }
                   catch {
                   print("NO DATA FOUND , Error")
                   }


        }
    
    
    

}

让我烦恼的是,我的警报都不起作用!我在 stackoverflow 中阅读了其他一些答案,但这些解决方案对我不起作用

我正在尝试让我的警报正常工作

任何帮助将不胜感激

【问题讨论】:

    标签: swift xcode


    【解决方案1】:

    您似乎想在视频播放器 (playerLayer) 上显示警报,但您在 playerLayer 后面的图层上调用警报,它会给您带来您遇到的错误。

    参考Swift 4 Attempt to present ViewController whose view is not in the window hierarchy

    在你的代码中添加这个函数

    func getTopMostViewController() -> UIViewController? {
        var topMostViewController = UIApplication.shared.keyWindow?.rootViewController
    
        while let presentedViewController = topMostViewController?.presentedViewController {
            topMostViewController = presentedViewController
        }
    
        return topMostViewController
    }
    

    并替换(第 33 行)

    self.present(alert, animated: true, completion: nil)
    

    DispatchQueue.main.async {
        getTopMostViewController()?.present(alert, animated: true, completion: nil)
    }
    

    【讨论】:

    • 嗨,谢谢你的回答,但它不能正常工作,因为在我执行检查电子邮件或密码是否在我添加代码之前工作时停止工作的条件之后,就像当添加代码后,我单击该应用程序忽略 if 条件的按钮,我更新了我的帖子
    • 是的,但是在所有情况下都执行了 segue,它在您的代码之前没有发生
    • 您能否检查一下您的 else 块中的电子邮件和密码是否为空?
    • 不,在你的代码之后,else块不能正常工作
    • 我不知道为什么if; else 块不起作用。警报的问题我想已经解决了,您需要查看if; else 块中出了什么问题
    猜你喜欢
    • 2015-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多