【问题标题】:Dynamically set UIViewController pointer inline - Objective C动态设置 UIViewController 指针内联 - Objective C
【发布时间】:2018-12-04 12:29:07
【问题描述】:

我有一个带有 for 循环的 iOS 应用程序,它可以创建、设置和添加自定义视图控制器到我的视图中。问题是我需要根据当前的循环编号将UIViewController 对象动态设置为正确的类。这是我的代码:

// Loop through the data and setup the switches.
    
for (NSUInteger loop = 0; loop < [switchLabels count]; loop++) {
        
    // Create the view controller object.
    UIViewController *screen;
        
    // Create the custom switch view.
        
    if (loop < 3) {
        screen = [[CustomSwitchView alloc] initWithNibName:@"CustomSwitchView" bundle:nil];
    } else {
        screen = [[CustomTripleSwitchView alloc] initWithNibName:@"CustomTripleSwitchView" bundle:nil];
    }
        
    // Create the custom switch view.
    [screen setPassedInType:switchTypes[loop]];
    [screen setDelegate:self];
    [self addChildViewController:screen];
    [screen.view setFrame:CGRectMake((self.view.frame.size.width - 150), ((UILabel *)switchLabels[loop]).frame.origin.y, 144, 72)];
    [scrollTopView addSubview:screen.view];
    [screen didMoveToParentViewController:self];
    [screen setTitles:switchTitles[loop] state:[switchSettings[loop] boolValue]];
}

问题是上面的一些方法调用会报错:

“UIViewController”没有可见的@interface 声明选择器....

为了解决这个问题,我需要输入对象screen。但是我需要根据 for 循环号动态类型转换它:

如果循环小于3,我需要将对象类型转换为CustomSwitchView,否则我需要将它类型转换为CustomTripleSwitchView。我怎样才能做到这一点?例如我尝试了下面的代码,但它没有工作:

(loop < 3 ? (CustomSwitchView *) : (CustomTripleSwitchView *))

【问题讨论】:

  • 如果它们共享一些您正在使用的通用方法,那么您应该声明一个它们都符合的协议,该协议需要这些方法。然后你可以将你的局部变量声明为UIViewController&lt;Protocol&gt; *
  • 为什么不在调用实际方法之前尝试使用 respondsToSelector?

标签: ios objective-c cocoa-touch uiviewcontroller casting


【解决方案1】:

有几种方法可以处理这个问题。对现有代码影响最小的是将方法区分为一般适用于 UIViewController 的方法和特定于子类的方法。在声明为特定子类的堆栈变量上调用子类方法...

for (NSUInteger loop = 0; loop < [switchLabels count]; loop++) {

    // Create the view controller object.
    UIViewController *vc;

    // Create the custom switch view.

    if (loop < 3) {
        CustomSwitchView *screen = [[CustomSwitchView alloc] initWithNibName:@"CustomSwitchView" bundle:nil];
        [screen setPassedInType:switchTypes[loop]];
        [screen setDelegate:self];
        [screen setTitles:switchTitles[loop] state:[switchSettings[loop] boolValue]];
        vc = screen;
    } else {
        CustomTripleSwitchView *screen = [[CustomTripleSwitchView alloc] initWithNibName:@"CustomTripleSwitchView" bundle:nil];
        [screen setPassedInType:switchTypes[loop]];
        [screen setDelegate:self];
        [screen setTitles:switchTitles[loop] state:[switchSettings[loop] boolValue]];
        vc = screen;
    }

    // Create the custom switch view.
    [self addChildViewController:vc];
    [vc.view setFrame:CGRectMake((self.view.frame.size.width - 150), ((UILabel *)switchLabels[loop]).frame.origin.y, 144, 72)];
    [scrollTopView addSubview:vc.view];
    [vc didMoveToParentViewController:self];
}

如果我们在项目中遇到此问题,这是一个不错的解决方案。当你看到这种事情激增时,是时候开始思考了:(a)我应该在每个类上定义一个协议(正如评论者恰当地建议的那样),还是(b)这些子类真的是相互关联的,比如@987654322 @真的是CustomSwitchView的子类吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-26
    • 1970-01-01
    • 2015-05-19
    • 2018-01-05
    • 1970-01-01
    • 2021-02-28
    相关资源
    最近更新 更多