0

アプリ内通知を表示するために作成したカスタムのサブクラス化されたuiviewがあります。ビューは問題なく呼び出すことができますが、uibutton(カスタムビューに埋め込まれている)を使用してビューを閉じるのに問題があります

ボタンを押すと、アプリがクラッシュし、次のエラーが発生します。

更新-上記の問題を修正しましたが、実際のビューではなく、ボタンのみが閉じられるようになりました。以下の更新されたコードを参照してください。

-(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;
                     }
     ];
}

別のViewControllerからのView呼び出し:

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

2 に答える 2

1

[noticeDropDown closeNoticeDropDown:...]ビューインスタンス(のようなもの)でメソッドを呼び出そうとしますcloseNoticeDropDown:が、これはクラスメソッドであり、次のように呼び出す必要があります。

[NoticeDropDown closeNoticeDropDown: noticeDropDown];

アニメーションコードには、見た目が間違っているものもいくつかあります。

  • [UIView commitAnimations];[UIView beginAnimations:... context:...]メソッドと組み合わせて使用​​されるため、呼び出しは削除する必要があります。ブロックベースのアニメーションでは必要ありません。

  • [sender removeFromSuperview];呼び出しはアニメーションの完了ブロックに入る必要があります。そうしないと、アニメーションが開始される前に呼び出され、目的の効果が得られません。

于 2012-09-11T17:00:20.270 に答える
1

メソッドをクラスメソッドとして宣言しましたが、メッセージをインスタンスに送信しています。それでもクラスメソッドにしたい場合は、ターゲットパラメータとして[NoticeDropDown class]を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。メソッドは常に存在します。

于 2012-09-11T17:01:41.643 に答える