Objective-C中如何根据调用的ViewController为同一类传入不同数据
如何让自定义GaugeView支持多模块不同数据源?
首先得解决你遇到的两个核心问题:重复符号编译错误和GaugeView的数据源复用性,咱们一步步来:
1. 先解决重复符号的问题
你复制GaugeView类导致的duplicate symbols错误,本质是同一个类被多次编译进不同模块了。正确的做法是把GaugeView做成公共可复用组件:
- 把GaugeView的.h和.m文件移到项目里所有模块都能访问的位置,比如创建一个
Shared文件夹(在Xcode里用Group管理),或者打包成一个静态/动态Framework,让需要的模块直接引用这个公共文件,而不是复制粘贴。这样就不会出现重复定义的问题了。
2. 重构GaugeView,让它脱离固定数据源依赖
你原来的思路是在GaugeView里判断当前是哪个ViewController,这种方式会让GaugeView和ViewController强耦合,以后新增页面还要修改GaugeView的代码,非常不灵活。更好的做法是让GaugeView接收外部传入的数据,而不是自己去UserDefaults里取固定值。
具体实现步骤:
第一步:给GaugeView添加可配置的属性
在GaugeView.h里声明两个属性,用来接收外部传入的当前分数和最高分数:
@interface GaugeView : UIView // 新增两个属性,让外部传入数据 @property (nonatomic, assign) double currentPoints; @property (nonatomic, assign) double maxPoints; @end
第二步:修改drawRect方法,使用属性计算比例
把原来从UserDefaults取数的逻辑删掉,直接用实例属性计算,还要加个除以0的兜底(避免maxPoints为0时崩溃):
- (void) drawRect:(CGRect)rect { CGContextRef ctx = UIGraphicsGetCurrentContext(); if(ctx == nil) return; // 用外部传入的属性计算,不再依赖固定的UserDefaults键 if (self.maxPoints <= 0) { orangeSegmentValue = 0; // 兜底处理,防止除以0 } else { orangeSegmentValue = (self.currentPoints/self.maxPoints)*270.00; } [self drawBackground:rect context:ctx]; }
第三步:添加属性监听,自动重绘仪表盘(优化项)
如果希望修改分数时仪表盘自动更新,可以给属性添加setter方法,触发重绘:
@implementation GaugeView - (void)setCurrentPoints:(double)currentPoints { _currentPoints = currentPoints; [self setNeedsDisplay]; // 修改后自动重绘 } - (void)setMaxPoints:(double)maxPoints { _maxPoints = maxPoints; [self setNeedsDisplay]; // 修改后自动重绘 } // 原来的drawRect和其他方法... @end
3. 在各个ViewController里使用GaugeView
现在你可以在任何模块的ViewController里,根据自己的数据源给GaugeView赋值:
比如在ViewController A里(用自己的数据源):
// 初始化GaugeView GaugeView *gaugeView = [[GaugeView alloc] initWithFrame:CGRectMake(50, 50, 200, 200)]; // 传入当前页面的自定义数据 gaugeView.currentPoints = 85; gaugeView.maxPoints = 150; [self.view addSubview:gaugeView];
在原来的ViewController里(继续用UserDefaults的数据):
GaugeView *gaugeView = [[GaugeView alloc] initWithFrame:CGRectMake(50, 50, 200, 200)]; // 从UserDefaults取原来的数值,赋值给GaugeView double maxPoints = [[NSUserDefaults standardUserDefaults] integerForKey:MAX_POINTS]; double currentPoints = [[NSUserDefaults standardUserDefaults] integerForKey:CURRENT_POINTS]; gaugeView.currentPoints = currentPoints; gaugeView.maxPoints = maxPoints; [self.view addSubview:gaugeView];
这样改造后,GaugeView就变成了一个通用的组件,不管哪个模块、哪个ViewController用它,都可以传入对应的数据源,完全解耦了原来的固定依赖,也解决了重复符号的问题。
内容的提问来源于stack exchange,提问作者Fabrizio L.
相关产品推荐
相关产品推荐

