我有一个 UISlider 的子类连接到故事板以获取值更改:
- (IBAction)valueChanged:(RSSlider*)slider {
// do some super cool stuff with my new value
}
在我的子类视图中DidLoad,我得到了:
UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(sliderTapped:)];
[self addGestureRecognizer:gestureRecognizer];
然后在同一个子类中,一个很好的点击处理程序,可以移动滑块并更新当前值:
- (void)sliderTapped:(UIGestureRecognizer *)tap
{
if (self.highlighted)
return;
CGPoint locationInView = [tap locationInView: self];
CGFloat percentage = locationInView.x / self.bounds.size.width;
CGFloat delta = percentage * (self.maximumValue - self.minimumValue);
CGFloat value = self.minimumValue + delta;
[self setValue:value];
}
没关系,价值定下来了,生活还在继续。唯一的问题是,我在视图控制器中的情节提要处理程序(我们称之为委托,尽管显然它不是真的)永远不会被调用。
通过 tap 更改值后,如何触发对处理程序方法的更新?
正如你提到的,处理这个问题的一种方法是通过委托。
由于 UISlider 没有用于更改值的预定义委托方法,因此您可以在子类中创建自己的协议。让视图控制器符合该协议,并通过委托属性调用其方法。
下面是一个示例协议和委托创建:
@protocol RSSliderDelegate
- (void)changeValue:(RSSlider*)slider;
@end
@interface RSSlider: UISlider
@property (nonatomic, assign) id<RSSliderDelegate> delegate;
然后将 VC 设置为符合协议:
@interface ViewController : UIViewController <RSSliderDelegate>
然后只需在创建滑块时设置它:
RSSlider* rs = [[RSSlider alloc] init];
[rs setDelegate: self];
实现方法:
- (void)changeValue:(RSSlider*)slider
{
//Do some cool stuff
}
最后,从子类本身调用该方法:
[self.delegate changeValue:self];