UIView可用但ViewController报错:参数标签frame:应为coder:如何解决?
init(frame:)报错的问题 这问题我之前踩过坑!核心原因是UIViewController和UIView的初始化规则完全不一样:
你写的init(frame:)是UIView的指定初始化器,但UIViewController根本没有这个初始化方法——它的指定初始化器是init(nibName:bundle:)(代码创建场景用)和init?(coder:)(从Storyboard/XIB加载场景用)。所以你调用super.init(frame: frame)时,父类UIViewController找不到对应方法,就会报"Incorrect argument label in call (have 'frame:', expected 'coder:')"的错误。
具体解决方案
1. 替换为ViewController的代码初始化方法
把你的自定义初始化器改成调用父类的init(nibName:bundle:),如果不需要加载XIB文件,直接传nil即可:
init() { super.init(nibName: nil, bundle: nil) self.view.backgroundColor = UIColor.clear currentMonthIndex = Calendar.current.component(.month, from: Date()) - 1 currentYear = Calendar.current.component(.year, from: Date()) setupViews() btnLeft.isEnabled = true }
如果需要传递额外业务参数,也可以在自定义初始化器里先处理参数,再调用父类的init(nibName:bundle:)。
2. 必须实现required init?(coder:)
因为UIViewController遵循NSCoding协议,不管你是否用Storyboard/XIB加载,都必须实现这个初始化器。如果只做纯代码创建,可以直接抛出错误:
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
如果需要支持从Storyboard加载,就在这个方法里补充对应的初始化逻辑即可。
额外提醒
ViewController的位置和尺寸是由它的容器(比如UINavigationController、UIWindow)管理的,不需要像UIView那样在初始化时传入frame。如果要设置ViewController的view尺寸,可以在viewDidLoad或者viewWillAppear里修改self.view.frame。
内容的提问来源于stack exchange,提问作者Appu Y

