繁体   English   中英

自定义类中的UIButton目标操作

[英]UIButton target action inside custom class

我一直在努力解决一个错误,并且找到了一种解决方法,但是我想了解到底发生了什么。 它与子类内部的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中,我将自定义类本身添加为子视图,而不是该类的subview属性对象。 然后该按钮成功调用该函数。 因此新的安排如下所示:

-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

您将不必要的各种视图层次结构东西弄乱了,这很可能是问题的原因。 我创建了一个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];

结果是:

在此处输入图片说明

谁在坚持temp

如果没有任何人引用temp ,那么它将被释放。 那时目标是僵尸,您当然会崩溃。 temp.subview正在举行self.view

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


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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM