awakeFromNib小总结

本文探讨了awakeFromNib方法在Objective-C中的应用,包括其触发时机、与init方法的区别,以及如何在TestView类中实现自定义功能。通过实例展示了在使用IB时,当.nib文件被加载时,此方法会被调用,允许开发者在此方法内定义对象的特定行为。

awakeFromNib

在使用IB的时候才会涉及到此方法的使用,当.nib文件被加载的时候,会发送一个awakeFromNib的消息到.nib文件中的每个对象,每个对象都可以定义自己的awakeFromNib函数来响应这个消息,执行一些必要的操作。

看例子:

创建一个viewController with XIB

定义一个UIView的子类



打开xib,并把View的类型指定为上一步骤定义的子类



然后在TestView.m中加入 awakeFromNib方法,运行程序发现此方法被调用了!!!可以在其中加代码来定义TestView的一些其他特性。

结果如图:



第一句:通过Xcode实例化controller,但controller的类在IB中创建时调用此方法

{我看有这么说的

awakeFromNib是一个只有在GUI对象被成功加载才调用的方法,而init方法是在GUI被创建前就已经调用了。

当程序对Nib文件进行反序列化然后初始化时,会调用一次awakeFromNib。
但是如果你使用initWithNibName调入Nib时,awakeFromNib是不会被调用的。

这个好像不准确!!!

第二句:initWithcoder是系统自动调用的,以后说!!!

第三句和第四句:这两局setNeedsDisplay会异步的调用drawRect来更新view的内容,这个我可以理解,但为什么是两句有点不理解,请高手指教

第四句:这句就是awakeFromNib被调用的地方了。

第五句:上述都结束后,view处理好了后就调用viewDidLoad了,所以无论从代码还是从IB加载view都要调用viewDidLoad的。

以上为个人观点,如有错误还请高手指教批评,不胜感激。

 

http://hi.baidu.com/zfpp25/blog/item/8e66e7eae22922352df534ec.html

我设置了颜色,为什么左侧列表还是白色,难道是tableview?我还没有添加数据:// // TPGuardEventView.swift // OmadaSurveillance // // Created by 代小青 on 2025/9/19. // class TPGuardEventView: NSView { // 左右split private let eventPageSplitView: EventPageSpliteView = EventPageSpliteView() // 左侧事件列表 let eventListView = NSTableView() let eventListScrollView = NSScrollView() // 右侧上下 split let rightPageSplitView : EventPageSpliteView = EventPageSpliteView() let playerView = NSView() let detailsTableView = NSTableView() override init(frame frameRect: NSRect) { super.init(frame: frameRect) setupSubviews() } required init?(coder: NSCoder) { fatalError() } private func setupSubviews() { // 主左右 split eventPageSplitView.isVertical = true eventPageSplitView.delegate = self addSubview(eventPageSplitView) eventPageSplitView.snp.makeConstraints { make in make.edges.equalToSuperview() } // 左侧列表 eventPageSplitView.addArrangedSubview(eventListScrollView) eventListScrollView.documentView = eventListView eventListScrollView.hasVerticalScroller = true eventListScrollView.layer?.backgroundColor = NSColor.tpBackground.cgColor // 右侧上下 split eventPageSplitView.addArrangedSubview(rightPageSplitView) rightPageSplitView.isVertical = false rightPageSplitView.dividerStyle = .thin rightPageSplitView.delegate = self rightPageSplitView.addArrangedSubview(playerView) rightPageSplitView.addArrangedSubview(detailsTableView) // 初始位置 eventPageSplitView.setPosition(200, ofDividerAt: 0) // 左侧宽度 200 rightPageSplitView.setPosition(350, ofDividerAt: 0) // 上方高度 350 } // 模拟数据 func setupMockData() { // 填充 tableView / detailsTableView } } class EventPageSpliteView: NSSplitView { override var dividerColor: NSColor { // return NSColor.tpSeparator return NSColor.red } override var dividerThickness: CGFloat { return 2 } } extension TPGuardEventView: NSSplitViewDelegate { func splitView(_ splitView: NSSplitView, constrainMinCoordinate proposedMinimumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat { if splitView == eventPageSplitView { // 左侧列表最小宽度 return 150 } else if splitView == rightPageSplitView { // 上部 player 最小高度 return 200 } return proposedMinimumPosition } func splitView(_ splitView: NSSplitView, constrainMaxCoordinate proposedMaximumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat { if splitView == eventPageSplitView { // 左侧列表最大宽度 return 400 } else if splitView == rightPageSplitView { // 上部 player 最大高度 return 600 } return proposedMaximumPosition } }
09-30
你问的问题是: > **“我设置了颜色,为什么左侧列表还是白色,难道是 tableView?”** 我们来一步步分析你的代码和现象。 --- ## ✅ 问题定位:**背景色显示为白色的原因** 虽然你在 `eventListScrollView` 上设置了: ```swift eventListScrollView.layer?.backgroundColor = NSColor.tpBackground.cgColor ``` 但仍然看到白色背景,**主要原因如下:** ### 🔴 根本原因:`NSTableView` 自身的背景覆盖了 ScrollView 的背景 - `NSScrollView.documentView = eventListView` —— 你把 `NSTableView` 当作文档视图放入了 `NSScrollView` - `NSTableView` 默认有自己的背景色(通常是白色或系统背景色) - 这个 `eventListView` 的背景会**遮住** `eventListScrollView` 的背景 - 所以即使你设置了 `eventListScrollView` 的背景色,你也看不到! --- ## ✅ 解决方案:同时设置 `NSTableView` 的背景色 和 清除其绘制干扰 你需要做两件事: ### ✅ 1. 设置 `eventListView`(即 `NSTableView`)的背景为透明或目标颜色 ```swift // 在 setupSubviews() 中添加: eventListView.backgroundColor = NSColor.tpBackground // 或你喜欢的颜色 eventListView.enclosingScrollView?.drawsBackground = false // 可选:让 scrollView 不画背景 ``` 或者更彻底地控制: ```swift eventListView.backgroundColors = [NSColor.tpBackground] // 支持多行背景 ``` > ⚠️ 注意:`NSTableView` 的 `backgroundColor` 是一个可读写属性(macOS 10.15+),如果你用的是旧版本,可能需要通过 `enclosingScrollView` 或自定义 cell 来实现。 --- ### ✅ 2. 确保 `NSScrollView` 不再额外绘制背景(避免冲突) ```swift eventListScrollView.drawsBackground = false ``` 这样就不会和 `tableView` 的背景打架。 --- ### ✅ 完整修复后的代码片段: ```swift // 左侧列表 eventPageSplitView.addArrangedSubview(eventListScrollView) eventListScrollView.documentView = eventListView eventListScrollView.hasVerticalScroller = true // 👇 关键修复:设置 tableView 背景 + 关闭 scrollview 背景绘制 eventListView.backgroundColor = NSColor.tpBackground eventListView.backgroundColors = [NSColor.tpBackground] eventListScrollView.drawsBackground = false ``` > 💡 提示:如果 `tpBackground` 是深色(比如暗黑模式下),你现在就能看到它生效了;否则默认 `NSTableView` 白底会完全盖住。 --- ## 🎨 额外建议:验证颜色是否真的生效 你可以**临时测试一下**: ```swift eventListView.backgroundColor = NSColor.red // 测试用红色 ``` 运行程序看左边是不是变红。如果是,说明之前的 `tpBackground` 可能其实是白色/浅灰色,而不是你期望的颜色。 --- ## ❓关于 `EventPageSpliteView.dividerColor` 没生效? 你说你改成了红色: ```swift override var dividerColor: NSColor { return NSColor.red } ``` 但在某些情况下,这个 getter **可能不会被调用**,因为: > ⚠️ `NSSplitView` 的分隔线绘制行为在较新 macOS 版本中受到 `isSpringLoaded`、`dividerStyle`、甚至 App 外观(light/dark)影响。 ### ✅ 确保生效的方法: ```swift class EventPageSpliteView: NSSplitView { override func drawDivider(in rect: NSRect) { let color = NSColor.red color.set() let path = NSBezierPath(rect: rect) path.fill() } // 可选:关闭动画风格以确保自定义绘制起效 override func awakeFromNib() { super.awakeFromNib() self.isSpringLoaded = false } } ``` > 📌 推荐使用 `drawDivider(in:)` 替代 `dividerColor`,这是最可靠的方式来自定义分隔线颜色。 --- ## ✅ 总结:你现在应该做什么? | 问题 | 原因 | 解决方法 | |------|------|---------| | 左侧面板看起来是白色 | `NSTableView` 背景覆盖了 `NSScrollView` 背景 | 设置 `tableView.backgroundColor` | | 设置 `scrollView.backgroundColor` 无效 | 被子视图遮挡 | 设置 `drawsBackground = false` | | 分隔线不是红色 | `dividerColor` 不一定被调用 | 使用 `drawDivider(in:)` 自定义绘制 | --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值