4

我正在尝试子类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在外观和正常外观之间切换。但这是一个完全不同的问题。谢谢大家。UIBarButtonItemself.customView = nil

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

4

3 回答 3

4

使用一个简单的实现这个功能可能更好UIView,您可以以任何给定的方式简单地修改它。

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

- (id)initWithCustomView:(UIView *)customView

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

于 2012-12-30T12:42:58.683 回答
2

压倒performSelector:一切绝对不是正确的方法。该类可以performSelector:用来做各种事情,而不仅仅是 Target-Action 部分。

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

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

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

于 2012-12-30T12:37:21.650 回答
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];
    }
    
于 2012-12-30T22:34:30.063 回答