覆盖-performSelector:在UIBarButtonItem子类中

时间:2012-12-30 12:33:24

标签: objective-c ios cocoa subclass uibarbuttonitem

我正在尝试将UIBarButtonItem子类化以添加一些特殊功能。我需要barButtonItem在触摸时切换其外观,因此我试图覆盖performSelector:

当我使用下面的代码时,我得到EXC_BAD_ACCESS (code=2 ...)

-(id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2
{
    // Do something

    return [super performSelector:aSelector withObject:object1 withObject:object2];
}

我的猜测是,我错误地试图覆盖performSelector:(还有其他方式吗?)或错误地调用super上的方法。

在寻找3小时以上的解决方案后,我什么都没发现。非常感谢任何帮助。

更新 以下作品:

@implementation CustomBarButtonItem

- (void)setTarget:(id)target
{
    _realTarget = target;
    super.target = self;
}

- (void)setAction:(SEL)action
{
    _realAction = action;
    super.action = @selector(pressed);
}

- (void)pressed
{
    [self doCustom]; // implement this somewhere
    [_realTarget performSelector:_realAction withObject:nil afterDelay:0];
}

不幸的是,我希望通过设置customView来实现UIBarButtonItem和普通self.customView = nil外观之间切换,这只会有效。但这是一个完整的问题。谢谢大家。

我会再等一会儿,选择最佳答案,看看是否有更好的解决方案。

3 个答案:

答案 0 :(得分:4)

使用一个简单的UIView来实现此功能可能更好,你只需要以任何给定的方式进行修改。

UIBarButtonItem确实提供了一种基于自定义UIView进行初始化的方法:

- (id)initWithCustomView:(UIView *)customView

然后,您可以告诉UIView根据UIBarButtonItem触发的触摸事件更改其外观。

答案 1 :(得分:2)

覆盖performSelector:绝对不是正确的方法。 该类可以使用performSelector:来执行各种操作,而不仅仅是目标操作部分。

不幸的是,在执行目标操作的performSelector之前,没有正在执行的公共方法。

但是,您可以在视图控制器中使用Target-Action实现操作,或者您可以覆盖私有方法。

此外,了解“特殊功能”的含义会很有帮助。

答案 2 :(得分:1)

我会做以下事情:

  1. 添加/减少处理程序

    CAGradientLayer *gradient = [CAGradientLayer layer];
    loginButton.clipsToBounds = YES;
    UIColor *topColor = [UIColor colorWithRed:255/255 green:255/255 blue:255/255 alpha:0.9];
    UIColor *middleColor = [UIColor colorWithRed:61.0/255 green:130.0/255 blue:244.0/255 alpha:1.0];
    UIColor *bottomColor = [UIColor colorWithRed:24.0/255 green:77.0/255 blue:214.0/255 alpha:1.0];
    gradient.colors = [NSArray arrayWithObjects:(id)topColor.CGColor,
                       (id)middleColor.CGColor, (id)bottomColor.CGColor, nil];
    gradient.locations = [NSArray arrayWithObjects:
                          [NSNumber numberWithFloat:0.0f],
                          [NSNumber numberWithFloat:0.05f],
                          [NSNumber numberWithFloat:0.7],
                          nil];
    gradient.frame = [[loginButton layer] bounds];
    gradient.cornerRadius = 4.0;
    gradient.borderWidth = 0.5;
    [loginButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    [loginButton.layer insertSublayer:gradient atIndex:0]; 
    [loginButton addTarget:self action:@selector(loginTouchDown:)
                    forControlEvents:UIControlEventTouchDown];
    [loginButton addTarget:self action:@selector(loginTouchUp:)
                  forControlEvents:UIControlEventTouchUpOutside];
    
  2. 在处理程序中,我会使用渐变图层或简单图层(之前准备好的)来做你需要的外观。

    - (IBAction)loginTouchDown:(id)sender
    {
            CAGradientLayer *gradient = [loginButton.layer.sublayers objectAtIndex:0];
            UIColor *topColor = [UIColor colorWithRed:24.0/255 green:77.0/255 blue:214.0/255 alpha:1.0];
            UIColor *middleColor = [UIColor colorWithRed:24.0/255 green:77.0/255 blue:214.0/255 alpha:1.0];
            UIColor *bottomColor = [UIColor colorWithRed:24.0/255 green:77.0/255 blue:214.0/255 alpha:1.0];
            gradient.colors = [NSArray arrayWithObjects:(id)topColor.CGColor, (id)middleColor.CGColor,
                               (id)bottomColor.CGColor, nil];
    }
    
    - (IBAction)loginTouchUp:(id)sender
    {
            CAGradientLayer *gradient = [loginButton.layer.sublayers objectAtIndex:0];
            UIColor *topColor = [UIColor colorWithRed:255/255 green:255/255 blue:255/255 alpha:0.9];
            UIColor *middleColor = [UIColor colorWithRed:61.0/255 green:130.0/255 blue:244.0/255 alpha:1.0];
            UIColor *bottomColor = [UIColor colorWithRed:24.0/255 green:77.0/255 blue:214.0/255 alpha:1.0];
            gradient.colors = [NSArray arrayWithObjects:(id)topColor.CGColor,
                               (id)middleColor.CGColor, (id)bottomColor.CGColor, nil];
    }