需要将使用 Interface Builder 创建的 UISlider 连接到非事件代码

Posted

技术标签:

【中文标题】需要将使用 Interface Builder 创建的 UISlider 连接到非事件代码【英文标题】:Need to connect a UISlider created with Interface Builder to non-event code 【发布时间】:2015-04-28 18:12:15 【问题描述】:

我有一个 ViewController 填充几个滑块:

// ViewController.h
@interface ViewController : UIViewController 

@property (weak, nonatomic) IBOutlet UISlider *aSlider;
@property (weak, nonatomic) IBOutlet UISlider *anotherSlider;

@end

// ViewController.m
@interface ViewController ()

@end

@implementation ViewController

-(void)resetSliders  

    NSLog(@"Resetting sliders sl1: %@ sl2: %@", self.aSlider, self.anotherSlider);
    [self.aSlider       setValue:0.5f animated:NO];
    [self.anotherSlider setValue:0.5f animated:NO];


- (IBAction)setOneSlider:(UISlider *)sender 
    NSLog(@"Setting aSlider to %f", sender.value);
    self.sl1Val = sender.value;
    [self doAThing];


- (IBAction)setTwoSlider:(UISlider *)sender 
    NSLog(@"Setting anotherSlider to %f", sender.value);
    self.sl2Val = sender.value;
    [self doBThing];

@end

setOneSlidersetTwoSlider 的调用被连接到两个滑块的值更改事件。这工作得很好。不幸的是,我没有将滑块连接到它们的编程句柄,因为对 resetSliders 的调用不会在 UI 中产生任何变化,即使在两个滑块元素上添加了对 setNeedsDisplay 的调用。

resetSliders被调用时,日志显示:

2015-04-28 12:22:19.608 myApp[4489:681127] Resetting sliders sl1: (null) sl2: (null)

谁能告诉我如何使用正确的对象句柄设置self.aSliderself.anotherSlider

添加一些颜色:我已经将滑块的 UI 表示拖到了它们各自的 @property 声明中,我可以看到它们在边缘填充了灰色圆圈,表明它们已经被连线了。 Connections Inspector 显示“Value Changed”事件触发器和将 myApp 连接到滑块的引用 Outlet。

我对 ios 编程非常陌生,并且正在达到从失败中学习的极限。

【问题讨论】:

我已经完成了下面@jszumski 和@picciano 列出的分类/调试(尽管他们似乎采取了相反的策略),但我的最终结果是一样的。当我期望滑块对象或至少是滑块对象的地址时,调用我的重置方法会为两个滑块打印 (null)。我什至不在乎哪个,只是生活的证明。此外,调用 setValue 方法时重置功能失败,因为没有引用滑块。 你能在问题中发布更新的代码吗? 更新了当前损坏的代码。删除了@synthesize(s) 和 ivars,并将所有对滑块的引用更改为“self”。我还重新连接了 Interface Builder 中的 UI 元素,以确保我有正确的连接。 您需要两个@ends:一个用于结束第一个@interface 块,一个用于结束@implementation 块。 抱歉,这些都存在,只是不在我的代码 sn-p 中。我在一个相当大且相当专有的应用程序中,所以我正在手动编写一些我实际大部分工作代码的混淆表示。 【参考方案1】:

属性应在@interface 块内定义。你的目前在外面。此外,它们可能应该是 weak 而不是 retain,并且不需要 @synthesize 语句或 ivars。

最后,当您在代码中引用它们时,您应该使用self.aSlider,而不仅仅是aSlider

【讨论】:

所以我已经完全删除了滑块的所有实例表示。事件驱动的功能仍然可以正常工作,但我无法以编程方式设置滑块的值来执行重置。想法? 此时,您的代码看起来是正确的。我建议删除 @property 行并通过将 UISlider 从 InterfaceBuilder 拖到您的代码中重新添加它们......再次。 咕。您知道我可以添加任何工具来尝试正确分配滑块对象吗?我在 setSlider 代码中尝试了类似if (aSlider == nil) aSlider = sender; 的东西,但这以某种方式触发了对该函数的无限循环调用。我想我没有清除表明事件已经结束或类似情况的秘密标志。【参考方案2】:

听起来您仍然需要在 Interface Builder 中连接这些插座:

@property (retain, nonatomic) IBOutlet UISlider *aSlider;
@property (retain, nonatomic) IBOutlet UISlider *anotherSlider;

此外,您不需要为相同的滑块声明属性和 ivars。只需声明并使用您已有的属性。

@interface ViewController : UIViewController

-(void)resetSliders  

    // note the addition of 'self.' below
    NSLog(@"Resetting sliders sl1: %@ sl2: %@", self.aSlider, self.anotherSlider);
    [self.aSlider       setTo:0.5f animated:NO];
    [self.anotherSlider setTo:0.5f animated:NO];

【讨论】:

你能准确地向我描述一下这个过程吗?我已经将滑块的 UI 表示拖到了它们各自的 @property 声明中,我可以看到它们在边缘填充了灰色圆圈,表明它们已被连接。我对 IOS 编程非常陌生,并且正在达到通过失败学习的极限。 听起来他们是有联系的。我认为您的问题已在我的回答的后半部分得到解决……您使用的是阴影 ivars(未初始化)而不是连接的属性。 我删除了看似掩盖了滑块句柄的 ivars,但现在直接在 resetSliders 中使用它们时,我看到了构建错误:No visible @interface for 'UISlider' declares the selector 'setTo:animated:' 改用setValue:animated:

以上是关于需要将使用 Interface Builder 创建的 UISlider 连接到非事件代码的主要内容,如果未能解决你的问题,请参考以下文章

Xcode 6 Interface Builder 视图大小错误

使用 Interface Builder 进行切换

使用 Interface Builder 将 UITableView 放在导航栏下方

Interface Builder 将控制出口设置为零——为啥?

不使用 Interface Builder 将 NIB 转换为 XIB

如何使用 Interface Builder 设置 UIScreenEdgePanGestureRecognizer?