自定义 UIView 在 View Controller 中被解包为 nil

Posted

技术标签:

【中文标题】自定义 UIView 在 View Controller 中被解包为 nil【英文标题】:Custom UIView is being unwrapped as nil in View Controller 【发布时间】:2020-08-27 14:11:33 【问题描述】:

我正在尝试将自定义 UIView 添加到视图控制器。我以前做过,没有任何问题,所以我在这里很困惑。

我已正确配置文件所有者,已为自定义视图设置了所有必需的初始化方法等。对我来说,没有什么不合适的,所有配置都和以前一样。

当我运行代码时,没有调用任何自定义视图的 init 方法(在两者上都放置了断点)。当我将自定义视图作为 IBOutlet 添加到我的视图控制器中时,我收到一条错误消息:

“致命错误:在隐式展开可选值时意外发现 nil”。

这来自我的视图控制器中试图更改自定义视图颜色的一行。我假设是因为视图尚未初始化,所以它返回 nil。

那么关于为什么这个自定义视图没有被初始化的任何想法?

视图控制器:

class ProductSearchViewController: UINavigationController 
    
    @IBOutlet weak var mainSearchView: MainSearchView!
    
    override func viewDidLoad() 
        super.viewDidLoad()
        applyTheme()
        setupNavigationBar()
        // Do any additional setup after loading the view.
    
    
    func applyTheme() 
        self.view.backgroundColor = UIColor.init(named: "appPrimaryColour")
        self.mainSearchView.backgroundColor = UIColor.yellow
    
    
    func setupNavigationBar() 
        self.title = NSLocalizedString("product.search.tab.bar.item.title", comment: "")
        self.navigationBar.isHidden = true
    

自定义视图:

import UIKit

class MainSearchView: UIView 
    
    @IBOutlet var contentView: UIView!
    @IBOutlet weak var searchBar: UITextField!
    
    override init(frame: CGRect) 
        super.init(frame: frame)
        commonInit()
    
    
    required init?(coder aDecoder: NSCoder) 
        super.init(coder: aDecoder)
        commonInit()
    

    func commonInit() 
        let xib = UINib(nibName: "MainSearchView", bundle: nil)
        xib.instantiate(withOwner: self, options: nil)
        addSubview(contentView)
        contentView.frame = self.bounds
        contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        contentView.backgroundColor = UIColor.blue
    

【问题讨论】:

要么你的类和模块是错误的,请检查。在 ProductSearchViewController 故事板中 如果您真的在使用您显示的代码...您是否收到此行的错误self.mainSearchView.backgroundColor = UIColor.yellow @DonMag 是的,代码在这一行停止,虽然这是因为 mainSearchView 对象为 nil 造成的 【参考方案1】:

ProductSearchViewController 是从 UINavigationController 扩展而来的,如果它从 UIViewController 扩展而来,你的问题就会得到解决。

【讨论】:

这行得通 - 你能解释一下为什么吗?我希望这个屏幕成为导航视图控制器,因为它应该是应用程序这一部分的根视图控制器 @Dylan,UINavigationController 不能有子视图,因为它是视图控制器的容器,它定义了用于导航分层内容的基于堆栈的方案。来到您的解决方案,您可以使用以下代码 let sb = UIStoryboard(name: "YourStoryBoardName", bundle: nil) let VC = sb.instantiateViewController(withIdentifier: "ProductSearchViewController") as! ProductSearchViewController let navRootView = UINavigationController(rootViewController: VC) 啊抱歉,我现在明白了。所以我应该只使用那个导航视图控制器作为我的“基础”,然后在其中包含其他 VC,并在我认为合适的时候推送和弹出它们

以上是关于自定义 UIView 在 View Controller 中被解包为 nil的主要内容,如果未能解决你的问题,请参考以下文章

iOS开发之自定义View

MVC:我应该在 View Controller 或 UIView 的自定义子类中添加和实现触摸手势吗

IOS UIView 03- 自定义 Collection View 布局

为UIView自定义Xib

使用Xib添加自定义View

自定义 UIView 上的 Google 地图 GMSMapView