You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UIKit中父视图无法显示子视图内容问题排查

问题:添加子控制器后界面黑屏,无法显示8X8棋盘

我尝试在主控制器MainView中以代码方式添加子控制器BoardViewController,期望展示8X8棋盘,但界面仅显示黑屏,Xcode无报错提示。以下是相关代码:

子控制器BoardViewController代码

import UIKit

class BoardViewController: UIViewController {

    private let boardGame: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        let board = UICollectionView(frame: .zero, collectionViewLayout: layout)
        board.allowsSelection =  true
        board.translatesAutoresizingMaskIntoConstraints = false
        return board
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(boardGame)
        
        boardGame.frame = view.bounds
        
        NSLayoutConstraint.activate([
                
                boardGame.centerXAnchor.constraint(equalTo: view.centerXAnchor),
                boardGame.centerYAnchor.constraint(equalTo: view.centerYAnchor),
                
               
                boardGame.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
                boardGame.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16),
                boardGame.topAnchor.constraint(equalTo: view.topAnchor, constant: 16),
                boardGame.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -16)
            ])
        
        boardGame.delegate = self
        boardGame.dataSource = self
        
    }
    
    init() {
           super.init(nibName: nil, bundle: nil)
       }
       required init?(coder: NSCoder) {
           fatalError("init(coder:) has not been implemented")
       }
}

extension BoardViewController: UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
    
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 64
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "unique", for: indexPath)
              
              let chessRow = indexPath.row / 8
              if chessRow % 2 == 0 {
                  if indexPath.row % 2 == 0 {
                       cell.backgroundColor = UIColor.white
                  }else{
                      cell.backgroundColor = UIColor.black
                  }
              } else{
                  if indexPath.row % 2 == 0 {
                      cell.backgroundColor = UIColor.black
                  }else{
                      cell.backgroundColor = UIColor.white
                  }
              }
          
              return cell
          }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
           
           let width = collectionView.frame.size.width / 8.0
           let height = width
           return CGSize(width: width, height: height)
       }

}

父控制器MainView代码

import UIKit

class MainView: UIViewController {

    let BoardView = BoardViewController()
    override func viewDidLoad() {
        super.viewDidLoad()
        addBoardView()
    }
    
    func addBoardView(){
        addChild(BoardView)
        view.addSubview(BoardView.view)
        BoardView.didMove(toParent: self)
    }
}

SceneDelegate代码

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

        guard let scene = (scene as? UIWindowScene) else { return }
        let window = UIWindow(frame: scene.coordinateSpace.bounds)
        let navVC = UINavigationController(rootViewController: MainView())
        window.rootViewController = navVC
        self.window = window
    } 

遗漏的关键点及修复方案

1. 未注册UICollectionViewCell

使用dequeueReusableCell之前必须先注册cell类型,否则无法创建cell,导致CollectionView无内容显示。在BoardViewController的viewDidLoad中添加注册代码:

override func viewDidLoad() {
    super.viewDidLoad()
    view.addSubview(boardGame)
    
    // 添加cell注册代码
    boardGame.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "unique")
    
    // ... 其余代码不变
}

2. 子控制器View未设置约束

在MainView的addBoardView方法中,添加子控制器View后未设置约束,导致子控制器View无法正确铺满父View。修改代码如下:

func addBoardView(){
    addChild(BoardView)
    view.addSubview(BoardView.view)
    // 关闭自动布局转义并添加约束
    BoardView.view.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint.activate([
        BoardView.view.topAnchor.constraint(equalTo: view.topAnchor),
        BoardView.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
        BoardView.view.trailingAnchor.constraint(equalTo: view.trailingAnchor),
        BoardView.view.bottomAnchor.constraint(equalTo: view.bottomAnchor)
    ])
    BoardView.didMove(toParent: self)
}

3. SceneDelegate未激活Window

创建Window后没有调用makeKeyAndVisible(),导致Window无法显示。在SceneDelegate方法末尾添加激活代码:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    guard let scene = (scene as? UIWindowScene) else { return }
    let window = UIWindow(frame: scene.coordinateSpace.bounds)
    let navVC = UINavigationController(rootViewController: MainView())
    window.rootViewController = navVC
    self.window = window
    // 激活Window
    window.makeKeyAndVisible()
} 

4. 约束冲突优化(可选)

BoardViewController中同时设置了centerX/Y和四边约束,会导致约束冲突。建议保留四边约束即可,删除centerX/Y的约束:

NSLayoutConstraint.activate([
    // 移除这两行冲突约束
    // boardGame.centerXAnchor.constraint(equalTo: view.centerXAnchor),
    // boardGame.centerYAnchor.constraint(equalTo: view.centerYAnchor),
    
    boardGame.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
    boardGame.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16),
    boardGame.topAnchor.constraint(equalTo: view.topAnchor, constant: 16),
    boardGame.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -16)
])

内容的提问来源于stack exchange,提问作者willd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 03:50:40