iOS - 从视图的uibutton关闭Subclassed UIView

时间:2012-09-11 16:51:09

标签: ios uiview uibutton subclass

我创建了一个自定义子类uiview来显示应用内通知。 我可以调用视图就好了,但是在使用uibutton(嵌入在自定义视图中)解决它时遇到了问题

按下按钮时,应用程序崩溃,我收到此错误:

  

UPDATE - 修正了上述问题,但现在只有按钮解散,而不是实际视图。请参阅下面的更新代码。

-(id)initWithMessage:(NSString *)message{
    self = [super initWithFrame:CGRectMake(0, -70, 320, 60)];
    if (self) {        
        //Add Image
        UIImage *image = [UIImage imageNamed:@"notice-drop-down"];
        UIImageView *background = [[UIImageView alloc] initWithImage:image];
        [self addSubview:background];

        //Add Label
        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, self.frame.size.height/2-25, 300, 50)];
        [label setBackgroundColor:[UIColor clearColor]];
        [label setTextColor:[UIColor blackColor]];
        [label setText:message];
        label.numberOfLines = 0;
        [label setFont:[UIFont fontWithName:@"Hand of Sean" size:16]];
        //NSLog(@"FONT FAMILIES\n%@",[UIFont familyNames]);


        [self addSubview:label];

        //Add Close Button
        UIButton *closeButton = [[UIButton alloc] initWithFrame:CGRectMake(280, self.frame.size.height/2-15, 30, 30)];
        UIImage *closeImage = [UIImage imageNamed:@"notice-close"];
        [closeButton setImage:closeImage forState:UIControlStateNormal];
        [closeButton addTarget:self action:@selector(closeNoticeDropDown:) forControlEvents:UIControlEventTouchUpInside];
        [self addSubview:closeButton];

        //Animate In
        [UIView animateWithDuration:1
                              delay:0
                            options: UIViewAnimationCurveEaseIn
                         animations:^{
                             self.frame = CGRectMake(0,70,320,60);
                         }
                         completion:nil
         ];
    }
    return self;
}

-(void)closeNoticeDropDown:(id)self{
    NoticeDropDown *notice = (NoticeDropDown *)self;
    NSLog(@"Frame: %f",notice.frame.size.width);
    //Animate In
    [UIView animateWithDuration:1
                          delay:0
                        options: UIViewAnimationCurveEaseOut
                     animations:^{
                         notice.frame = CGRectMake(0,-70,320,60);
                     }
                     completion:^(BOOL finished){
                         [notice removeFromSuperview];
                         //notice = nil;
                     }
     ];
}

查看来自其他视图控制器的调用:

noticeDropDown = [[NoticeDropDown alloc] initWithMessage:message];
[self.view insertSubview:noticeDropDown belowSubview:hudContainerTop];

2 个答案:

答案 0 :(得分:1)

您可能尝试在视图实例上调用您的方法(类似[noticeDropDown closeNoticeDropDown:...]),但closeNoticeDropDown:是一种类方法,您应该这样调用它:

[NoticeDropDown closeNoticeDropDown: noticeDropDown];

动画代码中也有一些看起来不对的东西:

  • [UIView commitAnimations];调用应该被删除,因为它们与[UIView beginAnimations:... context:...]方法配对使用,基于块的动画不需要它们

  • [sender removeFromSuperview];调用应该进入动画的完成块,否则会在你的动画开始之前调用它,你将无法获得理想的效果

答案 1 :(得分:1)

您已将方法声明为类方法,但正在将消息发送到实例。如果您希望它仍然是一个类方法,请将[NoticeDropDown类]作为目标参数传递给addTarget:action:forControlEvemts:方法。否则在方法声明中用“ - ”替换“+”。

此外 - 当UIControl操作具有发件人参数时,它会将控件作为发件人发送 - 因此您将获得UIButton而不是您的视图。

我的建议是将您的操作更改为实例方法,并将“sender”替换为“self”。

我为从手机上发布的格式道歉。我会在回到电脑前尝试修复。

编辑:

更改您的更新方法,如下所示:

-(void)closeNoticeDropDown:(id)sender{
    NSLog(@"Frame: %f",notice.frame.size.width);
    //Animate In
    [UIView animateWithDuration:1
                          delay:0
                        options: UIViewAnimationCurveEaseOut
                     animations:^{
                         self.frame = CGRectMake(0,-70,320,60);
                     }
                     completion:^(BOOL finished){
                         [self removeFromSuperview];
                     }
     ];
}

您无需将self传递给方法,它始终存在。