
こんにちは、あまのじゃくHikaruappです。
ボタンを非表示するとき UIButton.hidden = YES; でパッと非表示するのではなく、スーと消えながらStoryBoardのAutoLayout機能を利用して他のアイテムが追従して、かっこよく表示・非表示にする方法を紹介します。

StoryBoardに部品を配置する
表示・非表示させるボタンと非表示されるボタン。その下にラベルを一つおきます。

button Open/Closeを押すことによってButton1が表示・非表示となりButton1の状態によってラベルの位置が上下します。ラベルが上下するのはAutoLayoutの機能を使用しますので位置の設定は不要になります。
button open/close Actionの設定

button1 高さ関係のプロパティーの設定
ここが今までと違います。

“button Open/Close”と”button1″のスペースのプロパティーと”button1″高さのプロパティを作ります。
1.”button Open/Close”と”button1″のスペースのプロパティの設定

button1.top上でマウス右でドラッグして@interface ViewController ()へドロップ

NameにbuttonTopSpaceと入力してConnectをクリック
2.”button1″高さのプロパティの設定

“height = 30″上でマウス右でドラッグして@interface ViewController ()へドロップ

Nameにbutton1Heightと入力してConnectをクリック
3.button1のプロパティを設定
Storyboard上にあるbuttonを右ドラックして@interface ViewController ()へドロップ
Nameにbutton1と入力してConnectをクリック
@interface ViewController ()のコード
@interface ViewController () - (IBAction)buttonOpenClose:(id)sender; @property (weak, nonatomic) IBOutlet NSLayoutConstraint *buttonTopSpace; @property (weak, nonatomic) IBOutlet NSLayoutConstraint *button1Height; @property (weak, nonatomic) IBOutlet UIButton *button1; @end
これで設定が完了です。
アニメーション無しで表示・非表示
まずは、簡単にアニメーションなしにパッと表示・非表示させます。
- (IBAction)buttonOpenClose:(id)sender {
[self btnOpenCloseNonAnimation];
}
- (void)btnOpenCloseNonAnimation {
// アニメーション無し
if (self.button1.hidden) {
// Open
self.button1Height.constant = 30;
self.buttonTopSpace.constant = 8;
self.button1.hidden = !self.button1.hidden;
} else {
// Close
self.button1Height.constant = 0;
self.buttonTopSpace.constant = 0;
self.button1.hidden = !self.button1.hidden;
}
}
わかる人にはそうですよねという感じですね。それでは次はアニメーション付きです。
アニメーションありで表示・非表示
アニメーションには UIViewのanimateWithDurationを使用します。ここで気をつけないといけないところがあります。setNeedsUpdateConstraintsとlayoutIfNeeded使用しないとアニメーションしないところです。
では、コードです。
- (IBAction)buttonOpenClose:(id)sender {
[self btnOpenCloseAnimation];
}
- (void)btnOpenCloseAnimation {
// ボタン連打対策
if (self.isAnimationOpenClose) {
return;
}
self.isAnimationOpenClose = YES;
// アニメーション
[self.view setNeedsUpdateConstraints];
if (self.button1.hidden) {
// Open
self.button1Height.constant = 30;
self.buttonTopSpace.constant = 8;
self.button1.hidden = !self.button1.hidden;
[UIView animateWithDuration:0.3f
animations:^{
[self.view layoutIfNeeded];
self.button1.alpha = 1.0;
} completion:^(BOOL finished) {
self.isAnimationOpenClose = NO;
}];
} else {
// Close
self.button1Height.constant = 0;
self.buttonTopSpace.constant = 0;
[UIView animateWithDuration:0.3f
animations:^{
[self.view layoutIfNeeded];
self.button1.alpha = 0.0;
} completion:^(BOOL finished) {
self.button1.hidden = !self.button1.hidden;
self.isAnimationOpenClose = NO;
}];
}
}
ボタン連打対策
表示・非表示のアニメーション中にボタンを連打されると動作がおかしくなってしまいます。
その対策としてアニメーション中はボタン操作を無効にするようにアニメーション動作中をisAnimationOpenCloseで管理します。
まとめ|iPhoneらしくおしゃれな動作となりましたね
こういう機能はAPIで用意して欲しいところです。
Button意外にもUIViewも同じ方法で表示・非表示ができます。
この方法を利用して是非かっこいいUIのアプリを作ってみてください。
ソースコード
//
// ViewController.m
// buttonOpenClose
//
// Created by Yanase Yuji on 2016/08/09.
// Copyright © 2016年 hikaruApp. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
- (IBAction)buttonOpenClose:(id)sender;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *buttonTopSpace;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *button1Height;
@property (weak, nonatomic) IBOutlet UIButton *button1;
@property (nonatomic) BOOL isAnimationOpenClose;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)buttonOpenClose:(id)sender {
[self btnOpenCloseAnimation];
}
- (void)btnOpenCloseNonAnimation {
// アニメーション無し
if (self.button1.hidden) {
// Open
self.button1Height.constant = 30;
self.buttonTopSpace.constant = 8;
self.button1.hidden = !self.button1.hidden;
} else {
// Close
self.button1Height.constant = 0;
self.buttonTopSpace.constant = 0;
self.button1.hidden = !self.button1.hidden;
}
}
- (void)btnOpenCloseAnimation {
// ボタン連打対策
if (self.isAnimationOpenClose) {
return;
}
self.isAnimationOpenClose = YES;
// アニメーション
[self.view setNeedsUpdateConstraints];
if (self.button1.hidden) {
// Open
self.button1Height.constant = 30;
self.buttonTopSpace.constant = 8;
self.button1.hidden = !self.button1.hidden;
[UIView animateWithDuration:0.3f
animations:^{
[self.view layoutIfNeeded];
self.button1.alpha = 1.0;
} completion:^(BOOL finished) {
self.isAnimationOpenClose = NO;
}];
} else {
// Close
self.button1Height.constant = 0;
self.buttonTopSpace.constant = 0;
[UIView animateWithDuration:0.3f
animations:^{
[self.view layoutIfNeeded];
self.button1.alpha = 0.0;
} completion:^(BOOL finished) {
self.button1.hidden = !self.button1.hidden;
self.isAnimationOpenClose = NO;
}];
}
}
@end
プロジェクトファイル — github


コメント