自定义类中的UIButton目标操作

时间:2014-08-23 19:07:14

标签: ios objective-c iphone uiview uibutton

我一直在努力解决一个错误,我找到了解决办法,但我想了解究竟发生了什么。它与UIButton目标操作有关,这取决于子类内部的不同子视图层次结构。

简要总结:我有一个NSObject的子类,它有一个UIView属性对象,一个UIButton附加到它上面,一个目标被添加到调用子类内部函数的按钮中。在主ViewController中,我初始化子类并将其视图添加到视图堆栈,单击按钮,它将我抛给main.mm并显示错误 - EXC_BAD_ACCESS,给我一些反馈。层次结构如下所示:

-CustomClass
--UIView           <-this is added as a subview to the View Controller
---UIButton (onRelease calling a function)

所以我通过将自定义类更改为UIView的子类而不是NSObject来修复它,然后将其@property UIView添加为自定义类的子视图(并且按钮仍然附加到子视图),然后在主View Controller中,我将自定义类本身添加为子视图,而不是类的子视图属性对象。然后按钮成功调用该函数。所以新的安排看起来像这样:

-CustomClass (now UIView)     <-this is added as a subview to the View Controller
--UIView                      <-this is added as a subview to CustomClass
---UIButton (onRelease calling a function)

然后,我意识到我可以将CustomClass保留为两个实例的UIView的子类,如果其他所有内容都没有改变,问题仍然存在于原始设置中。

好的,更详细,这里的代码:

CustomClass: .H

@interface Temp : UIView
@property UIView *subview;
@property UIButton *but;
@end

的.m

-(id) init{
    self = [super initWithFrame:[[UIScreen mainScreen] bounds]];
    if(self){
        _subview = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        //[self addSubview:_subview];  // FOR THE FIX
        _but = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        [_but setTitle:@"OKAY" forState:UIControlStateNormal];
        [_but setBackgroundColor:[UIColor blackColor]];
        [_but setFrame:CGRectMake(50, 50, 200, 200)];
        [_subview addSubview:_but];
        [_but addTarget:self action:@selector(pageTurn) forControlEvents:UIControlEventTouchUpInside];
    }
    return self;
}

-(void) pageTurn{
    NSLog(@"WORKS");
}

内部视图控制器:

Temp *temp = [[Temp alloc] init];
[self.view addSubview:temp.subview];
//[self.view addSubview:temp];  // FOR THE FIX, instead of above line

2 个答案:

答案 0 :(得分:0)

您正在弄乱您不需要的各种视图层次结构,这可能是导致问题的原因。我创建了一个 Test UIView子类,它有一个UIButton实例变量,我在Test对象中添加了一个子视图,不需要添加另一个视图作为子视图,然后添加按钮到子视图,然后在视图控制器中将按钮的子视图添加到视图中 - 它的方式比它需要的更复杂。

简而言之 - 创建Temp UIView,将按钮添加为子视图,然后在视图控制器类中添加Temp UIView作为子视图。很简单,这是代码:

- (id)init {
    self = [super initWithFrame:[[UIScreen mainScreen] bounds]];
    if(self){
        _but = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        [_but setTitle:@"OKAY" forState:UIControlStateNormal];
        [_but setBackgroundColor:[UIColor blackColor]];
        [_but setFrame:CGRectMake(100, 100, 200, 200)];
        [_but addTarget:self action:@selector(pageTurn) forControlEvents:UIControlEventTouchUpInside];
        [self addSubview:_but];
    }
    return self;
}

- (void)pageTurn {
    NSLog(@"WORKS");
}

然后向我的视图控制器添加了一个实例:

Test *temp = [[Test alloc] init];
temp.backgroundColor = [UIColor redColor];
[self.view addSubview:temp];

这是结果:

enter image description here

答案 1 :(得分:0)

谁持有temp

如果任何人都没有引用temp,那么它就会被释放。那时目标是僵尸,当然你会崩溃。 temp.subview正在追踪self.view

在第二个设置中,添加temp作为self.view的子视图会保留对它的引用。


您可以通过在视图控制器中添加Temp *属性来解决此问题。

self.temp = [[Temp alloc] init];
[self.view addSubview:self.temp.subview];